import from HEAD:
authorfcusack <fcusack>
Thu, 24 May 2007 23:44:28 +0000 (23:44 +0000)
committerfcusack <fcusack>
Thu, 24 May 2007 23:44:28 +0000 (23:44 +0000)
handle OTP_RC_NEXTPASSCODE error from otpd-2.2.1+

693 files changed:
INSTALL
Make.inc.in
Makefile
README
acconfig.h [new file with mode: 0644]
acinclude.m4 [deleted file]
aclocal.m4
autogen.sh [deleted file]
config.guess
config.h.in [new file with mode: 0644]
config.sub
configure
configure.in
debian/changelog
debian/copyright
debian/freeradius-dialupadmin.dirs [deleted file]
debian/freeradius-dialupadmin.docs [deleted file]
debian/freeradius-dialupadmin.examples [deleted file]
debian/freeradius-dialupadmin.links [deleted file]
debian/freeradius.examples
debian/freeradius.init
dialup_admin/Changelog
dialup_admin/README
dialup_admin/bin/backup_radacct [deleted file]
dialup_admin/bin/clean_radacct
dialup_admin/bin/clearsession [deleted file]
dialup_admin/bin/log_badlogins
dialup_admin/bin/monthly_tot_stats
dialup_admin/bin/showmodem
dialup_admin/bin/snmpfinger
dialup_admin/bin/sqlrelay_query [deleted file]
dialup_admin/bin/tot_stats
dialup_admin/bin/truncate_radacct
dialup_admin/conf/admin.conf
dialup_admin/conf/config.php3
dialup_admin/conf/extra.ldap-attrmap
dialup_admin/conf/naslist.conf
dialup_admin/conf/sql.attrmap
dialup_admin/conf/user_edit.attrs
dialup_admin/conf/username.mappings
dialup_admin/doc/AUTHORS
dialup_admin/doc/FAQ
dialup_admin/doc/TODO
dialup_admin/htdocs/about.html
dialup_admin/htdocs/accounting.php3
dialup_admin/htdocs/badusers.php3
dialup_admin/htdocs/buttons.php3
dialup_admin/htdocs/clear_opensessions.php3
dialup_admin/htdocs/content.html
dialup_admin/htdocs/failed_logins.php3
dialup_admin/htdocs/find.php3
dialup_admin/htdocs/group_admin.php3
dialup_admin/htdocs/group_new.php3
dialup_admin/htdocs/help/help.php3
dialup_admin/htdocs/index.html
dialup_admin/htdocs/login_time_create.php3
dialup_admin/htdocs/nas_admin.php3
dialup_admin/htdocs/password.php3
dialup_admin/htdocs/session_destroy.php3
dialup_admin/htdocs/show_groups.php3
dialup_admin/htdocs/stats.php3
dialup_admin/htdocs/style.css
dialup_admin/htdocs/user_accounting.php3
dialup_admin/htdocs/user_admin.php3
dialup_admin/htdocs/user_delete.php3
dialup_admin/htdocs/user_edit.php3
dialup_admin/htdocs/user_finger.php3
dialup_admin/htdocs/user_info.php3
dialup_admin/htdocs/user_new.php3
dialup_admin/htdocs/user_state.php3
dialup_admin/htdocs/user_stats.php3
dialup_admin/htdocs/user_test.php3
dialup_admin/html/buttons/default/buttons.html.php3
dialup_admin/html/group_toolbar.html.php3
dialup_admin/html/stats.html.php3
dialup_admin/html/user_admin.html.php3
dialup_admin/html/user_admin_userinfo.html.php3
dialup_admin/html/user_toolbar.html.php3
dialup_admin/lib/acctshow.php3
dialup_admin/lib/add_badusers.php3
dialup_admin/lib/attrshow.php3
dialup_admin/lib/defaults.php3
dialup_admin/lib/functions.php3
dialup_admin/lib/ldap/attrmap.php3
dialup_admin/lib/ldap/change_attrs.php3
dialup_admin/lib/ldap/change_info.php3
dialup_admin/lib/ldap/defaults.php3
dialup_admin/lib/ldap/find.php3
dialup_admin/lib/ldap/functions.php3
dialup_admin/lib/ldap/user_info.php3
dialup_admin/lib/missing.php3 [deleted file]
dialup_admin/lib/operators.php3
dialup_admin/lib/sql/attrmap.php3
dialup_admin/lib/sql/change_attrs.php3
dialup_admin/lib/sql/change_info.php3
dialup_admin/lib/sql/change_passwd.php3
dialup_admin/lib/sql/create_group.php3
dialup_admin/lib/sql/create_user.php3
dialup_admin/lib/sql/defaults.php3
dialup_admin/lib/sql/drivers/dbx/functions.php3 [deleted file]
dialup_admin/lib/sql/drivers/mysql/functions.php3
dialup_admin/lib/sql/drivers/oracle/functions.php3 [deleted file]
dialup_admin/lib/sql/drivers/pg/functions.php3
dialup_admin/lib/sql/drivers/sqlrelay/functions.php3 [deleted file]
dialup_admin/lib/sql/find.php3
dialup_admin/lib/sql/functions.php3
dialup_admin/lib/sql/group_admin.php3
dialup_admin/lib/sql/group_change.php3 [deleted file]
dialup_admin/lib/sql/group_info.php3
dialup_admin/lib/sql/nas_list.php3 [deleted file]
dialup_admin/lib/sql/password_check.php3
dialup_admin/lib/sql/user_info.php3
dialup_admin/lib/xlat.php3 [deleted file]
dialup_admin/sql/badusers.sql [moved from dialup_admin/sql/mysql/badusers.sql with 80% similarity]
dialup_admin/sql/mtotacct.sql [moved from dialup_admin/sql/mysql/mtotacct.sql with 100% similarity]
dialup_admin/sql/oracle/badusers.sql [deleted file]
dialup_admin/sql/oracle/mtotacct.sql [deleted file]
dialup_admin/sql/oracle/totacct.sql [deleted file]
dialup_admin/sql/oracle/userinfo.sql [deleted file]
dialup_admin/sql/postgresql/badusers.sql [deleted file]
dialup_admin/sql/postgresql/mtotacct.sql [deleted file]
dialup_admin/sql/postgresql/totacct.sql [deleted file]
dialup_admin/sql/postgresql/userinfo.sql [deleted file]
dialup_admin/sql/totacct.sql [moved from dialup_admin/sql/mysql/totacct.sql with 100% similarity]
dialup_admin/sql/userinfo.sql [moved from dialup_admin/sql/mysql/userinfo.sql with 91% similarity]
doc/ChangeLog
doc/DIFFS
doc/Post-Auth-Type
doc/RADIUS-SQL.schema
doc/README
doc/ascend
doc/configurable_failover
doc/duplicate-users [new file with mode: 0644]
doc/examples/iplanet.ldif [deleted file]
doc/examples/iplanet.schema [deleted file]
doc/examples/mssql.sql
doc/examples/mysql.sql
doc/examples/openldap.schema [deleted file]
doc/examples/oracle.sql
doc/examples/postgresql.sql
doc/examples/postgresql_update_radacct_group_trigger.sql [deleted file]
doc/ldap_howto.txt
doc/load-balance.txt
doc/radrelay [new file with mode: 0644]
doc/rfc/Makefile
doc/rfc/attributes.html
doc/rfc/genref.pl
doc/rfc/per-rfc.pl [deleted file]
doc/rfc/rewrite.pl
doc/rfc/rfc2607.txt [deleted file]
doc/rfc/rfc3748.txt [deleted file]
doc/rfc/rfc4372.txt [deleted file]
doc/rfc/rfc4590.txt [deleted file]
doc/rfc/rfc4675.txt [deleted file]
doc/rfc/rfc4679.txt [deleted file]
doc/rfc/rfc4818.txt [deleted file]
doc/rfc/update.sh [deleted file]
doc/rlm_attr_filter [new file with mode: 0644]
doc/rlm_digest [new file with mode: 0644]
doc/rlm_eap
doc/rlm_expiration [deleted file]
doc/rlm_ldap
doc/rlm_sql
doc/rlm_sqlcounter
doc/rlm_sqlippool
doc/snmp [deleted file]
doc/variables.txt
libltdl/ltdl.c
ltconfig [new file with mode: 0755]
man/man1/radclient.1
man/man1/radwho.1
man/man1/radzap.1
man/man5/clients.5
man/man5/clients.conf.5 [deleted file]
man/man5/naslist.5
man/man5/radrelay.conf.5 [deleted file]
man/man5/rlm_attr_filter.5
man/man5/rlm_counter.5
man/man5/rlm_digest.5 [deleted file]
man/man5/rlm_files.5
man/man5/rlm_mschap.5
man/man5/rlm_pap.5
man/man5/rlm_passwd.5
man/man5/rlm_policy.5 [deleted file]
man/man5/rlm_realm.5
man/man5/rlm_sql_log.5
man/man5/rlm_unix.5
man/man8/radiusd.8
man/man8/radrelay.8
man/man8/radwatch.8
mibs/FREERADIUS-SMI.txt [deleted file]
mibs/GNOME-PRODUCT-RADIUSD-MIB [moved from mibs/FREERADIUS-PRODUCT-RADIUSD-MIB.txt with 55% similarity]
raddb/Makefile
raddb/acct_users
raddb/attrs
raddb/attrs.access_reject [deleted file]
raddb/attrs.accounting_response [deleted file]
raddb/attrs.pre-proxy [deleted file]
raddb/certs/Makefile [deleted file]
raddb/certs/README
raddb/certs/bootstrap [deleted file]
raddb/certs/ca.cnf [deleted file]
raddb/certs/cert-clt.der [new file with mode: 0644]
raddb/certs/cert-clt.p12 [new file with mode: 0644]
raddb/certs/cert-clt.pem [new file with mode: 0644]
raddb/certs/cert-srv.der [new file with mode: 0644]
raddb/certs/cert-srv.p12 [new file with mode: 0644]
raddb/certs/cert-srv.pem [new file with mode: 0644]
raddb/certs/client.cnf [deleted file]
raddb/certs/demoCA/index.txt [new file with mode: 0644]
raddb/certs/demoCA/index.txt.old [new file with mode: 0644]
raddb/certs/demoCA/serial [new file with mode: 0644]
raddb/certs/demoCA/serial.old [new file with mode: 0644]
raddb/certs/dh [new file with mode: 0644]
raddb/certs/newcert.pem [new file with mode: 0644]
raddb/certs/newreq.pem [new file with mode: 0644]
raddb/certs/random [new file with mode: 0644]
raddb/certs/root.der [new file with mode: 0644]
raddb/certs/root.p12 [new file with mode: 0644]
raddb/certs/root.pem [new file with mode: 0644]
raddb/certs/server.cnf [deleted file]
raddb/certs/xpextensions [deleted file]
raddb/clients [new file with mode: 0644]
raddb/clients.conf
raddb/eap.conf
raddb/experimental.conf
raddb/ldap.attrmap
raddb/mssql.conf [moved from raddb/sql/mssql-dialup.conf with 80% similarity]
raddb/naslist [new file with mode: 0644]
raddb/oraclesql.conf [moved from raddb/sql/oracle-dialup.conf with 84% similarity]
raddb/otp.conf
raddb/pgsql-voip.conf [moved from raddb/sql/postgresql-voip-postpaid.conf with 94% similarity]
raddb/policy.txt [deleted file]
raddb/postgresql.conf [new file with mode: 0644]
raddb/preproxy_users
raddb/protocol_filter.conf [deleted file]
raddb/proxy.conf
raddb/radiusd.conf.in
raddb/radrelay.conf.in [deleted file]
raddb/snmp.conf
raddb/sql.conf
raddb/sql/mysql-dialup.conf [deleted file]
raddb/sql/mysql-ippool-dialup.conf [deleted file]
raddb/sql/postgresql-dialup.conf [deleted file]
raddb/sql/postgresql-ippool-dialup.conf [deleted file]
raddb/sqlippool.conf
raddb/templates.conf [deleted file]
raddb/users
redhat/freeradius.spec
redhat/rc.radiusd-redhat
scripts/CA.all [new file with mode: 0755]
scripts/CA.certs [new file with mode: 0755]
scripts/Makefile
scripts/certs.sh [new file with mode: 0755]
scripts/check-radiusd-config.in
scripts/clients.pl [deleted file]
scripts/create-users.pl
scripts/cryptpasswd.in
scripts/exec-program-wait
scripts/min-includes.pl [deleted file]
scripts/radiusd2ldif.pl
scripts/rc.radiusd.in
scripts/users2mysql.pl
scripts/xpextensions [new file with mode: 0644]
share/Makefile [deleted file]
share/dictionary
share/dictionary.ascend
share/dictionary.asn
share/dictionary.azaire [deleted file]
share/dictionary.chillispot [deleted file]
share/dictionary.cisco
share/dictionary.freeradius.internal
share/dictionary.hp
share/dictionary.lucent
share/dictionary.nortel [deleted file]
share/dictionary.patton
share/dictionary.rfc4590 [new file with mode: 0644]
share/dictionary.rfc4818 [deleted file]
share/dictionary.roaringpenguin
share/dictionary.schulzrinne-sipping [new file with mode: 0644]
share/format.pl
src/Makefile
src/billing/README
src/billing/cisco_h323_db_sample_functions-postgres.sql
src/billing/cisco_h323_db_schema-postgres.sql
src/billing/clarent2db.pl
src/billing/h323detail2db.pl
src/include/Makefile
src/include/autoconf.h.in
src/include/conffile.h
src/include/event.h [deleted file]
src/include/hash.h [deleted file]
src/include/libradius.h
src/include/md4.h
src/include/md5.h
src/include/missing.h
src/include/modcall.h
src/include/modpriv.h
src/include/modules.h
src/include/packet.h [deleted file]
src/include/rad_assert.h
src/include/radius.h
src/include/radius_snmp.h
src/include/radiusd.h
src/include/radsniff.h [deleted file]
src/include/radutmp.h
src/include/realms.h [deleted file]
src/include/request_list.h [new file with mode: 0644]
src/include/smux.h
src/include/sysutmp.h
src/include/token.h
src/include/udpfromto.h
src/lib/LICENSE [deleted file]
src/lib/Makefile
src/lib/README [deleted file]
src/lib/crypt.c [moved from src/main/crypt.c with 65% similarity]
src/lib/dict.c
src/lib/event.c [deleted file]
src/lib/fifo.c [deleted file]
src/lib/filters.c
src/lib/getaddrinfo.c [deleted file]
src/lib/hash.c
src/lib/hmac.c
src/lib/hmacsha1.c
src/lib/isaac.c
src/lib/log.c
src/lib/md4.c
src/lib/md5.c
src/lib/misc.c
src/lib/missing.c
src/lib/packet.c [deleted file]
src/lib/print.c
src/lib/radius.c
src/lib/rbtree.c
src/lib/sha1.c
src/lib/snprintf.c
src/lib/snprintf.h
src/lib/strlcat.c [deleted file]
src/lib/strlcpy.c [deleted file]
src/lib/token.c
src/lib/udpfromto.c
src/lib/valuepair.c
src/main/00-OLD/Make.inc [new file with mode: 0644]
src/main/00-OLD/Makefile [new file with mode: 0644]
src/main/00-OLD/Makefile.BSD [new file with mode: 0644]
src/main/00-OLD/Makefile.lnx [new file with mode: 0644]
src/main/00-OLD/Makefile.osf [new file with mode: 0644]
src/main/00-OLD/Makefile.sunos5 [new file with mode: 0644]
src/main/Makefile.in
src/main/acct.c
src/main/auth.c
src/main/checkrad.pl.in
src/main/client.c
src/main/conffile.c
src/main/event.c [deleted file]
src/main/exec.c
src/main/files.c
src/main/listen.c [deleted file]
src/main/log.c
src/main/mainconfig.c
src/main/modcall.c
src/main/modules.c
src/main/nas.c [new file with mode: 0644]
src/main/proxy.c [new file with mode: 0644]
src/main/radclient.c
src/main/radius_snmp.c
src/main/radiusd.c
src/main/radrelay.c [new file with mode: 0644]
src/main/radsniff.c [deleted file]
src/main/radwho.c
src/main/radzap [deleted file]
src/main/radzap.c [new file with mode: 0644]
src/main/realms.c [deleted file]
src/main/request_list.c [new file with mode: 0644]
src/main/session.c
src/main/smux.c
src/main/threads.c
src/main/timestr.c [moved from src/modules/rlm_logintime/timestr.c with 94% similarity]
src/main/util.c
src/main/valuepair.c
src/main/version.c
src/main/xlat.c
src/modules/Makefile
src/modules/rlm_acct_unique/rlm_acct_unique.c
src/modules/rlm_acctlog/Makefile.in [deleted file]
src/modules/rlm_acctlog/configure.in [deleted file]
src/modules/rlm_acctlog/rlm_acctlog.c [deleted file]
src/modules/rlm_always/rlm_always.c
src/modules/rlm_attr_filter/rlm_attr_filter.c
src/modules/rlm_attr_rewrite/Makefile.in
src/modules/rlm_attr_rewrite/configure
src/modules/rlm_attr_rewrite/configure.in
src/modules/rlm_attr_rewrite/rlm_attr_rewrite.c
src/modules/rlm_caching/Makefile.in [deleted file]
src/modules/rlm_caching/rlm_caching.c [deleted file]
src/modules/rlm_chap/rlm_chap.c
src/modules/rlm_checkval/Makefile.in
src/modules/rlm_checkval/configure
src/modules/rlm_checkval/configure.in
src/modules/rlm_checkval/rlm_checkval.c
src/modules/rlm_copy_packet/Makefile [deleted file]
src/modules/rlm_copy_packet/README [deleted file]
src/modules/rlm_copy_packet/rlm_copy_packet.c [deleted file]
src/modules/rlm_counter/acconfig.h [new file with mode: 0644]
src/modules/rlm_counter/config.h.in
src/modules/rlm_counter/configure
src/modules/rlm_counter/configure.in
src/modules/rlm_counter/rad_counter.pl
src/modules/rlm_counter/rlm_counter.c
src/modules/rlm_cram/rlm_cram.c
src/modules/rlm_dbm/configure
src/modules/rlm_dbm/configure.in
src/modules/rlm_dbm/rlm_dbm.c
src/modules/rlm_dbm/rlm_dbm_cat.c
src/modules/rlm_dbm/rlm_dbm_parser.c
src/modules/rlm_detail/rlm_detail.c
src/modules/rlm_digest/rlm_digest.c
src/modules/rlm_eap/configure
src/modules/rlm_eap/configure.in
src/modules/rlm_eap/eap.c
src/modules/rlm_eap/eap.h
src/modules/rlm_eap/libeap/Makefile
src/modules/rlm_eap/libeap/cb.c
src/modules/rlm_eap/libeap/eap_sim.h
src/modules/rlm_eap/libeap/eap_tls.c
src/modules/rlm_eap/libeap/eap_tls.h
src/modules/rlm_eap/libeap/eap_types.h
src/modules/rlm_eap/libeap/eapcommon.c
src/modules/rlm_eap/libeap/eapcrypto.c
src/modules/rlm_eap/libeap/eapsimlib.c
src/modules/rlm_eap/libeap/fips186prf.c
src/modules/rlm_eap/libeap/mppe_keys.c
src/modules/rlm_eap/libeap/tls.c
src/modules/rlm_eap/mem.c
src/modules/rlm_eap/radeapclient.c
src/modules/rlm_eap/rlm_eap.c
src/modules/rlm_eap/rlm_eap.h
src/modules/rlm_eap/state.c
src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c
src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.c
src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.h
src/modules/rlm_eap/types/rlm_eap_leap/rlm_eap_leap.c
src/modules/rlm_eap/types/rlm_eap_leap/smbdes.c
src/modules/rlm_eap/types/rlm_eap_md5/Makefile.in [moved from src/modules/rlm_eap/types/rlm_eap_md5/Makefile with 59% similarity]
src/modules/rlm_eap/types/rlm_eap_md5/configure [moved from src/modules/rlm_acctlog/configure with 53% similarity]
src/modules/rlm_eap/types/rlm_eap_md5/configure.in [new file with mode: 0644]
src/modules/rlm_eap/types/rlm_eap_md5/eap_md5.c
src/modules/rlm_eap/types/rlm_eap_md5/eap_md5.h
src/modules/rlm_eap/types/rlm_eap_md5/rlm_eap_md5.c
src/modules/rlm_eap/types/rlm_eap_mschapv2/Makefile.in [moved from src/modules/rlm_eap/types/rlm_eap_mschapv2/Makefile with 58% similarity]
src/modules/rlm_eap/types/rlm_eap_mschapv2/configure [new file with mode: 0755]
src/modules/rlm_eap/types/rlm_eap_mschapv2/configure.in [new file with mode: 0644]
src/modules/rlm_eap/types/rlm_eap_mschapv2/eap_mschapv2.h
src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c
src/modules/rlm_eap/types/rlm_eap_peap/config.h.in
src/modules/rlm_eap/types/rlm_eap_peap/configure
src/modules/rlm_eap/types/rlm_eap_peap/configure.in
src/modules/rlm_eap/types/rlm_eap_peap/eap_peap.h
src/modules/rlm_eap/types/rlm_eap_peap/peap.c
src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c
src/modules/rlm_eap/types/rlm_eap_psk/AES.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/AES.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/BlockCipher.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/CTR.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/CTR.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/EAX.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/EAX.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/Makefile.in [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/OMAC.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/OMAC.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/SOBMMO.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/SOBMMO.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/eap_psk.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/eap_psk.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/eap_psk_ssm.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/eap_psk_ssm.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/rlm_eap_psk.cpp [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/userinfo.c [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/userinfo.h [deleted file]
src/modules/rlm_eap/types/rlm_eap_psk/users.psk [deleted file]
src/modules/rlm_eap/types/rlm_eap_sim/Makefile [deleted file]
src/modules/rlm_eap/types/rlm_eap_sim/Makefile.in [new file with mode: 0644]
src/modules/rlm_eap/types/rlm_eap_sim/configure [new file with mode: 0644]
src/modules/rlm_eap/types/rlm_eap_sim/configure.in [new file with mode: 0644]
src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c
src/modules/rlm_eap/types/rlm_eap_tls/config.h.in
src/modules/rlm_eap/types/rlm_eap_tls/configure
src/modules/rlm_eap/types/rlm_eap_tls/configure.in
src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c
src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h
src/modules/rlm_eap/types/rlm_eap_ttls/config.h.in
src/modules/rlm_eap/types/rlm_eap_ttls/configure
src/modules/rlm_eap/types/rlm_eap_ttls/configure.in
src/modules/rlm_eap/types/rlm_eap_ttls/eap_ttls.h
src/modules/rlm_eap/types/rlm_eap_ttls/rlm_eap_ttls.c
src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c
src/modules/rlm_example/config.h.in
src/modules/rlm_example/configure
src/modules/rlm_example/configure.in
src/modules/rlm_example/other.c
src/modules/rlm_example/other.h
src/modules/rlm_example/rlm_example.c
src/modules/rlm_exec/rlm_exec.c
src/modules/rlm_expiration/Makefile [deleted file]
src/modules/rlm_expiration/rlm_expiration.c [deleted file]
src/modules/rlm_expr/Makefile
src/modules/rlm_expr/paircmp.c [deleted file]
src/modules/rlm_expr/rlm_expr.c
src/modules/rlm_fastusers/rlm_fastusers.c
src/modules/rlm_files/rlm_files.c
src/modules/rlm_ippool/acconfig.h [new file with mode: 0644]
src/modules/rlm_ippool/config.h.in
src/modules/rlm_ippool/configure
src/modules/rlm_ippool/configure.in
src/modules/rlm_ippool/rlm_ippool.c
src/modules/rlm_ippool/rlm_ippool_tool.c
src/modules/rlm_krb5/configure
src/modules/rlm_krb5/configure.in
src/modules/rlm_krb5/rlm_krb5.c
src/modules/rlm_ldap/configure
src/modules/rlm_ldap/configure.in
src/modules/rlm_ldap/edir_ldapext.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_linelog/Makefile [deleted file]
src/modules/rlm_linelog/rlm_linelog.c [deleted file]
src/modules/rlm_logintime/Makefile [deleted file]
src/modules/rlm_logintime/rlm_logintime.c [deleted file]
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_mschap/smbdes.c
src/modules/rlm_mschap/smbdes.h
src/modules/rlm_mschap/smbencrypt.c
src/modules/rlm_ns_mta_md5/Makefile [new file with mode: 0644]
src/modules/rlm_ns_mta_md5/rlm_ns_mta_md5.c [new file with mode: 0644]
src/modules/rlm_otp/Makefile.in
src/modules/rlm_otp/configure
src/modules/rlm_otp/extern.h
src/modules/rlm_otp/ident.h [moved from src/include/ident.h with 100% similarity]
src/modules/rlm_otp/otp.h
src/modules/rlm_otp/otp_mppe.c
src/modules/rlm_otp/otp_mppe.h
src/modules/rlm_otp/otp_pw_valid.c
src/modules/rlm_otp/otp_pw_valid.h
src/modules/rlm_otp/otp_pwe.c
src/modules/rlm_otp/otp_radstate.c
src/modules/rlm_otp/otp_rlm.c
src/modules/rlm_otp/otp_util.c
src/modules/rlm_pam/config.h.in
src/modules/rlm_pam/configure
src/modules/rlm_pam/configure.in
src/modules/rlm_pam/rlm_pam.c
src/modules/rlm_pap/rlm_pap.c
src/modules/rlm_passwd/rlm_passwd.c
src/modules/rlm_perl/config.h.in
src/modules/rlm_perl/configure
src/modules/rlm_perl/configure.in
src/modules/rlm_perl/example.pl
src/modules/rlm_perl/rlm_perl.c
src/modules/rlm_policy/Makefile [deleted file]
src/modules/rlm_policy/evaluate.c [deleted file]
src/modules/rlm_policy/parse.c [deleted file]
src/modules/rlm_policy/rlm_policy.c [deleted file]
src/modules/rlm_policy/rlm_policy.h [deleted file]
src/modules/rlm_preprocess/rlm_preprocess.c
src/modules/rlm_protocol_filter/Makefile [deleted file]
src/modules/rlm_protocol_filter/rlm_protocol_filter.c [deleted file]
src/modules/rlm_python/configure
src/modules/rlm_python/configure.in
src/modules/rlm_python/prepaid.py
src/modules/rlm_python/radiusd.py
src/modules/rlm_python/radiusd_test.py
src/modules/rlm_python/rlm_python.c
src/modules/rlm_radutmp/config.h.in
src/modules/rlm_radutmp/configure
src/modules/rlm_radutmp/configure.in
src/modules/rlm_radutmp/rlm_radutmp.c
src/modules/rlm_radutmp/rlm_radutmp2.c [deleted file]
src/modules/rlm_realm/rlm_realm.c
src/modules/rlm_sim_files/rlm_sim_files.c
src/modules/rlm_smb/byteorder.h
src/modules/rlm_smb/config.h.in
src/modules/rlm_smb/configure
src/modules/rlm_smb/configure.in
src/modules/rlm_smb/rfcnb-common.h
src/modules/rlm_smb/rfcnb-error.h
src/modules/rlm_smb/rfcnb-io.c
src/modules/rlm_smb/rfcnb-io.h
src/modules/rlm_smb/rfcnb-priv.h
src/modules/rlm_smb/rfcnb-util.c
src/modules/rlm_smb/rfcnb-util.h
src/modules/rlm_smb/rfcnb.h
src/modules/rlm_smb/rlm_smb.c
src/modules/rlm_smb/session.c
src/modules/rlm_smb/smbdes.c
src/modules/rlm_smb/smbencrypt.c
src/modules/rlm_smb/smblib-common.h
src/modules/rlm_smb/smblib-priv.h
src/modules/rlm_smb/smblib-util.c
src/modules/rlm_smb/smblib.c
src/modules/rlm_smb/smblib.h
src/modules/rlm_smb/std-includes.h
src/modules/rlm_smb/valid.c
src/modules/rlm_smb/valid.h
src/modules/rlm_sql/conf.h
src/modules/rlm_sql/configure
src/modules/rlm_sql/configure.in
src/modules/rlm_sql/drivers/rlm_sql_db2/configure
src/modules/rlm_sql/drivers/rlm_sql_db2/configure.in
src/modules/rlm_sql/drivers/rlm_sql_db2/sql_db2.c
src/modules/rlm_sql/drivers/rlm_sql_firebird/Makefile.in
src/modules/rlm_sql/drivers/rlm_sql_firebird/configure
src/modules/rlm_sql/drivers/rlm_sql_firebird/configure.in
src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.c
src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_fbapi.h
src/modules/rlm_sql/drivers/rlm_sql_firebird/sql_firebird.c
src/modules/rlm_sql/drivers/rlm_sql_freetds/Makefile [new file with mode: 0644]
src/modules/rlm_sql/drivers/rlm_sql_iodbc/configure
src/modules/rlm_sql/drivers/rlm_sql_iodbc/configure.in
src/modules/rlm_sql/drivers/rlm_sql_iodbc/sql_iodbc.c
src/modules/rlm_sql/drivers/rlm_sql_mysql/config.h.in
src/modules/rlm_sql/drivers/rlm_sql_mysql/configure
src/modules/rlm_sql/drivers/rlm_sql_mysql/configure.in
src/modules/rlm_sql/drivers/rlm_sql_mysql/sql_mysql.c
src/modules/rlm_sql/drivers/rlm_sql_oracle/configure
src/modules/rlm_sql/drivers/rlm_sql_oracle/configure.in
src/modules/rlm_sql/drivers/rlm_sql_oracle/sql_oracle.c
src/modules/rlm_sql/drivers/rlm_sql_postgresql/configure
src/modules/rlm_sql/drivers/rlm_sql_postgresql/configure.in
src/modules/rlm_sql/drivers/rlm_sql_postgresql/sql_postgresql.c
src/modules/rlm_sql/drivers/rlm_sql_postgresql/sql_postgresql.h [deleted file]
src/modules/rlm_sql/drivers/rlm_sql_sybase/sql_sybase.c
src/modules/rlm_sql/drivers/rlm_sql_unixodbc/configure
src/modules/rlm_sql/drivers/rlm_sql_unixodbc/configure.in
src/modules/rlm_sql/drivers/rlm_sql_unixodbc/sql_unixodbc.c
src/modules/rlm_sql/drivers/rules.mak
src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_sql/rlm_sql.h
src/modules/rlm_sql/sql.c
src/modules/rlm_sql_log/rlm_sql_log.c
src/modules/rlm_sqlcounter/Makefile.in
src/modules/rlm_sqlcounter/acconfig.h [new file with mode: 0644]
src/modules/rlm_sqlcounter/configure
src/modules/rlm_sqlcounter/configure.in
src/modules/rlm_sqlcounter/rlm_sqlcounter.c
src/modules/rlm_sqlhpwippool/configure.in
src/modules/rlm_sqlhpwippool/rlm_sqlhpwippool.c
src/modules/rlm_sqlhpwippool/sqlhpwippool.sql
src/modules/rlm_sqlippool/Makefile.in
src/modules/rlm_sqlippool/configure
src/modules/rlm_sqlippool/configure.in
src/modules/rlm_sqlippool/rlm_sqlippool.c
src/modules/rlm_unix/Makefile.in
src/modules/rlm_unix/cache.c [new file with mode: 0644]
src/modules/rlm_unix/cache.h [new file with mode: 0644]
src/modules/rlm_unix/compat.c [new file with mode: 0644]
src/modules/rlm_unix/compat.h [new file with mode: 0644]
src/modules/rlm_unix/config.h.in
src/modules/rlm_unix/configure
src/modules/rlm_unix/configure.in
src/modules/rlm_unix/rlm_unix.c
src/modules/rules.mak
src/modules/stable
src/tests/Makefile [deleted file]
src/tests/README
src/tests/chap [deleted file]
src/tests/dictionary.test [deleted file]
src/tests/digest-auth-MD5
src/tests/digest-auth-MD5_Sess
src/tests/digest-auth-int
src/tests/digest-auth-noalgo
src/tests/digest-auth_int-MD5
src/tests/digest-auth_int-MD5_Sess
src/tests/digest-auth_int-noalgo
src/tests/digest-md5-sess
src/tests/eapmd5-01/client.sh
src/tests/eapmd5-01/req.txt
src/tests/eapsim-02/client.sh
src/tests/eapsim-02/req.txt
src/tests/eapsim-03/radiusd-example.txt
src/tests/example.com [deleted file]
src/tests/mschapv1
src/tests/proxy.conf [deleted file]
src/tests/runtests.sh [deleted file]
src/tests/stripped.example.com [deleted file]
src/tests/user_password
src/tests/users [deleted file]
suse/dialup_admin.patch [new file with mode: 0644]
suse/edir.patch [new file with mode: 0644]
suse/freeradius.spec
suse/lib64.patch [new file with mode: 0644]
suse/radiusd-pam-old [deleted file]
suse/rcradius-relayd [deleted file]
suse/rcradiusd
todo/TODO

diff --git a/INSTALL b/INSTALL
index 8c59af0..3f3797d 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -13,7 +13,7 @@ the following steps to build and install the server:
        $ make
        $ make install
 
-  Note that in this release, the location of the dictionary files has
+  Note that as of 1.0.0, the location of the dictionary files has
 changed, to /usr/local/share/freeradius/dictionary.  Please ensure
 that /etc/raddb/dictionary is THE SAME as ./raddb/dictionary.  If not,
 you will have to copy it over by hand;
@@ -50,14 +50,6 @@ following list is a selection from the available flags:
   --with-edir             Compile with support for Novell eDirectory
                               integration.
 
-  To get the defaults that Cistron Radius used up to 1.5.4.3-beta18, use:
-
-       ./configure --localstatedir=/var --sysconfdir=/etc
-
-  That means binaries will get installed in /usr/local/{bin,sbin},
-manpages in /usr/local/man, configuration files in /etc/raddb, and
-logfiles in /var/log and /var/log/radacct.
-
   Now type "make". The binaries will be compiled.
 
   Then do "make install". That will install the binaries, the 'man'
index e3cd090..1df1643 100644 (file)
@@ -17,7 +17,6 @@ mandir                = @mandir@
 datadir                = @datadir@
 dictdir                = $(datadir)/freeradius
 logdir         = @logdir@
-includedir     = @includedir@
 raddbdir       = @raddbdir@
 radacctdir     = @radacctdir@
 top_builddir   = @abs_top_builddir@
@@ -26,11 +25,11 @@ top_srcdir  = @abs_top_srcdir@
 MAKE           = @MAKE@
 CC             = @CC@
 RANLIB         = @RANLIB@
-INCLUDE                =
-CFLAGS         = $(INCLUDE) @CFLAGS@
+INCLUDE                = 
+CFLAGS         = $(INCLUDE) @CFLAGS@ @LFS_CFLAGS@
 CPPFLAGS       = @CPPFLAGS@
 LIBPREFIX      = @LIBPREFIX@
-EXEEXT         = @EXEEXT@
+EXEEXT         = @EXEEXT@ 
 
 LIBTOOL                = @LIBTOOL@
 ACLOCAL                = @ACLOCAL@
@@ -43,8 +42,8 @@ INSTALL_SCRIPT        = ${INSTALL_PROGRAM}
 INSTALLSTRIP   = @INSTALLSTRIP@
 
 LCRYPT         = @CRYPTLIB@
-LIBS           = @LIBS@
-LDFLAGS                = @LDFLAGS@
+LIBS           = @LIBS@ @LFS_LIBS@
+LDFLAGS                = @LDFLAGS@ @LFS_LDFLAGS@
 
 LOGDIR         = ${logdir}
 RADDBDIR       = ${raddbdir}
index 21709e8..c9436db 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -107,9 +107,5 @@ config.status: configure
 
 configure.in:
 
-.PHONY: check-includes
-check-includes:
-       scripts/min-includes.pl `find . -name "*.c" -print`
-
 TAGS:
        etags `find src -type f -name '*.[ch]' -print`
diff --git a/README b/README
index 7ade473..65ff0dc 100644 (file)
--- a/README
+++ b/README
@@ -1,20 +1,8 @@
 1. INTRODUCTION
 
   The FreeRADIUS Server Project is a high performance and highly
-configurable GPL'd free RADIUS server. The server is similar in some
-respects to Livingston's 2.0 server.  While FreeRADIUS started as a
-variant of the Cistron RADIUS server, they don't share a lot in common
-any more.  It now has many more features than Cistron or Livingston,
-and is much more configurable.
-
-  FreeRADIUS is an Internet authentication daemon, which implements
-the RADIUS protocol, as defined in RFC 2865 (and others).  It allows
-Network Access Servers (NAS boxes) to perform authentication for
-dial-up users.  There are also RADIUS clients available for Web
-servers, firewalls, Unix logins, and more.  Using RADIUS allows
-authentication and authorization for a network to be centralized, and
-minimizes the amount of re-configuration which has to be done when
-adding or deleting new users.
+configurable GPL'd free RADIUS server. It is stable, and is currently
+being used in many deployments with millions of users.
 
   Please see the main web page (http://www.freeradius.org) for more
 information.
@@ -24,6 +12,45 @@ information.
   To install the server, please see the INSTALL file in this
 directory.
 
+  Version 1.1.4 contains a few key improvements over previous
+versions.  The most important is the addition of the
+Cleartext-Password attribute.  Using this attribute can make your
+configuration MUCH simpler, and MUCH easier to understand.  Please
+read "man rlm_pap" for more details.
+
+  New users of FreeRADIUS should prefer using Cleartext-Password over
+User-Password.  That is, if the documentation or a web page says to
+configure User-Password in a database or server configuration file,
+the documentation is likely out of date, and you should use
+User-Password instead.
+
+  The main differences between 1.1.3 and 1.1.4 are significantly
+improved functionality in rlm_pap.  The module is MUCH smarter, which
+means that many previous complicated configurations are now almost
+trivial to do.  Please read "man rlm_pap" for details.
+
+  Existing deployments of FreeRADIUS will NOT be affected by this
+change to rlm_pap.  Existing configurations will work as before.
+However, we do recommend reading the rlm_pap "man" page, to see how
+your configuration may be made simpler by using the new functionality.
+
+  The differences between 1.0.x and 1.1.0 are documented in the file
+doc/ChangeLog.  What these differences mean for an administrator
+upgrading from 1.0.x are as follows:
+
+  * You MUST use the new dictionaries.  This is NOT done by default,
+    because you may have edited the installed version of /etc/raddb/dictionary.
+    If you have not edited /etc/raddb/dictionary, then you can make
+    the server use the new dictionaries by copying the
+    raddb/dictionary file from this directory to /etc/raddb.  Without
+    this change, the server WILL NOT WORK PROPERLY.
+
+  * Sites using SQL for logging should look into using the new
+    rlm_sql_log module.  See it's "man" page for details.
+
+  * Sites using rlm_x99_token will have to update their configuration
+    to use rlm_otp.
+
 3. DEBUGGING THE SERVER
 
   Run the server in debugging mode, (radiusd -X) and READ the output.
@@ -43,11 +70,17 @@ documentation, other than comments in the configuration file.
 discussions about common problems and solution.
 
 
+  See the Wiki
+
+       http://wiki.freeradius.org
+
 4. ADDITIONAL INFORMATION
 
   See 'doc/README' for more information about FreeRADIUS.
 
-  There is now an O'Reilly book available, which we recommend highly:
+  There is now an O'Reilly book available, which we recommend for
+people new to RADIUS.  It covers an earlier version of the server, but
+much of the information is applicable to this version also.
 
 http://www.amazon.com/exec/obidos/ASIN/0596003226/freeradiusorg-20/
 
diff --git a/acconfig.h b/acconfig.h
new file mode 100644 (file)
index 0000000..c04a5dd
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
+
+*/
+
+@TOP@
+
+/* style of gethost*_r functions */
+#define GNUSTYLE 1
+#define SYSVSTYLE 2
+#define BSDSTYLE 3
+#undef GETHOSTBYADDRRSTYLE
+#undef GETHOSTBYNAMERSTYLE
+
+/* style of ctime_r function */
+#define POSIXSTYLE 1
+#define SOLARISSTYLE 2
+#undef CTIMERSTYLE
+
+/* Do we have the crypt function ? */
+#undef HAVE_CRYPT
+
+/* Do we have shadow support? */
+#undef HAVE_GETSPNAM
+
+/* Use USR-style vendor specific attributes */
+#undef ATTRIB_NMC
+
+/* Include support for Ascend binary filter attributes */
+#undef ASCEND_BINARY
+
+/* socklen_t is generally 'int' on systems which don't use it */
+#undef socklen_t
+
+/* uint8_t should be the canonical 'octet' for network traffic */
+#undef uint8_t
+
+/* uint16_t should be the canonical '2 octets' for network traffic */
+#undef uint16_t
+
+/* uint32_t should be the canonical 'network integer' */
+#undef uint32_t
+
+/* Define if prototype for strncasecmp needed */
+#undef NEED_DECLARATION_STRNCASECMP
+
+/* Define if prototype for strcasecmp needed */
+#undef NEED_DECLARATION_STRCASECMP
+
+/* Define if prototype for inet_aton needed */
+#undef NEED_DECLARATION_INET_ATON
+
+/* Define if prototype for gethostname needed */
+#undef NEED_DECLARATION_GETHOSTNAME
+
+/* Define if prototype for setlinebuf needed */
+#undef NEED_DECLARATION_SETLINEBUF
+
+/* Define if prototype for getusershell needed */
+#undef NEED_DECLARATION_GETUSERSHELL
+
+/* Define if prototype for endusershell needed */
+#undef NEED_DECLARATION_ENDUSERSHELL
+
+/* use a pool of threads to handle requests, instead of spawning threads? */
+#undef WITH_THREAD_POOL
+
+/* Include SNMP subagent */
+#undef WITH_SNMP
+
+/* Include user collision code*/
+#undef WITH_USERCOLLIDE
+
+/* Define if you have the <ucd-snmp/asn1.h>, <ucd-snmp/snmp_impl.h> and <ucd-snmp/snmp.h> header file.  */
+#undef HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H
+
+/* Define if you have the <asn1.h>, <snmp_impl.h> and <snmp.h> header file.  */
+#undef HAVE_ASN1_SNMP_SNMPIMPL_H
+
+/* Define if you have the snmp library (-lsnmp).  */
+#undef HAVE_LIBSNMP
+
+/* define if you have the <libpq_fe.h> header file.  */
+#undef HAVE_LIBPQ_FE_H
+
+/* define if you have the <postgres.h> header file.  */
+#undef HAVE_POSTGRES_H
+
+/* define this if we have the <regex.h> header file */
+#undef HAVE_REGEX_H
+
+/* define this if we have REG_EXTENDED (from <regex.h>) */
+#undef HAVE_REG_EXTENDED
+
+/* define this if you have the <mysql.h> header file */
+#undef HAVE_MYSQL_H
+
+/* define this if you have the <isql.h> header file */
+#undef HAVE_ISQL_H
+
+/* define this if you have the <oci.h> header file */
+#undef HAVE_OCI_H
+
+/* define to something if you don't have ut_xtime in struct utmpx */
+#undef ut_xtime
+
+/* define if you have OSFC2 authentication */
+#undef OSFC2
+
+/* define if you have OSFSIA authentication */
+#undef OSFSIA
+
+/* define if you have IP_PKTINFO (Linux) */
+#undef HAVE_IP_PKTINFO
+
+/* define if you want udpfromto */
+#undef WITH_UDPFROMTO
+
+/* define if you have openssl/ssl.h */
+#undef HAVE_OPENSSL_SSL_H
+
+/* define if you have initgroups() */
+#undef HAVE_INITGROUPS
+
+@BOTTOM@
+
+#ifndef HAVE_SNPRINTF
+#define HAVE_LOCAL_SNPRINTF
+#define snprintf lrad_snprintf
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#define HAVE_LOCAL_SNPRINTF
+#define vsnprintf lrad_vsnprintf
+#endif
diff --git a/acinclude.m4 b/acinclude.m4
deleted file mode 100644 (file)
index 8253976..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-dnl See whether we need a declaration for a function.
-dnl RADIUSD_NEED_DECLARATION(FUNCTION [, EXTRA-HEADER-FILES])
-AC_DEFUN([RADIUSD_NEED_DECLARATION],
-[AC_MSG_CHECKING([whether $1 must be declared])
-AC_CACHE_VAL(radius_cv_decl_needed_$1,
-[AC_TRY_COMPILE([
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_RESOURCE_H
-#include <resource.h>
-#endif
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-#ifdef HAVE_REGEX_H
-#include <regex.h>
-#endif
-#ifdef HAVE_SYSLOG_H
-#include <syslog.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-$2],
-[char *(*pfn) = (char *(*)) $1],
-eval "radius_cv_decl_needed_$1=no", eval "radius_cv_decl_needed_$1=yes")])
-if eval "test \"`echo '$radius_cv_decl_needed_'$1`\" = yes"; then
-  AC_MSG_RESULT(yes)
-  radius_tr_decl=NEED_DECLARATION_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  AC_DEFINE_UNQUOTED($radius_tr_decl)
-else
-  AC_MSG_RESULT(no)
-fi
-])dnl
-
-dnl Check multiple functions to see whether each needs a declaration.
-dnl RADIUSD_NEED_DECLARATIONS(FUNCTION... [, EXTRA-HEADER-FILES])
-AC_DEFUN([RADIUSD_NEED_DECLARATIONS],
-[for ac_func in $1
-do
-RADIUSD_NEED_DECLARATION($ac_func, $2)
-done
-])
-
-dnl Checks to see if this is SUNPro we're building with
-dnl Usage:
-dnl AC_PROG_CC_SUNPRO
-AC_DEFUN([AC_PROG_CC_SUNPRO],
-[AC_CACHE_CHECK(whether we are using SUNPro C, ac_cv_prog_suncc,
-[dnl The semicolon is to pacify NeXT's syntax-checking cpp.
-cat > conftest.c <<EOF
-#ifdef __SUNPRO_C
-  yes;
-#endif
-EOF
-if AC_TRY_COMMAND(${CC-cc} -E conftest.c) | egrep yes >/dev/null 2>&1; then
-  ac_cv_prog_suncc=yes
-else
-  ac_cv_prog_suncc=no
-fi])])
-
-dnl #
-dnl # FR_CHECK_TYPE_INCLUDE([#includes ...], type, default-C-types)
-dnl #
-dnl # This function is like AC_CHECK_TYPE, but you can give this one
-dnl # a list of include files to check.
-dnl #
-AC_DEFUN([FR_CHECK_TYPE_INCLUDE],
-[
-  AC_CACHE_CHECK(for $2, ac_cv_type_$2,
-    [ ac_cv_type_$2=no
-      AC_TRY_COMPILE($1,
-        [$2 foo],
-        ac_cv_type_$2=yes,
-      )
-    ]
-  )
-
-  if test "$ac_cv_type_$2" != "yes"; then
-         AC_DEFINE($2, $3, $4)
-  fi
-])
-
-dnl #######################################################################
-dnl #
-dnl #  Look for SNMP in a variety of places.
-dnl #
-AC_DEFUN([SNMP_CHECKS], [
-       AC_SUBST(SNMP_LIBS)
-       AC_SUBST(SNMP_INCLUDE)
-
-AC_MSG_CHECKING([for asn1.h,snmp.h,snmp_impl.h])
-
-dnl #
-dnl #  First, see if we can build it WITHOUT using any special includes and in ucd-snmp
-dnl #
-AC_TRY_COMPILE([
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <ucd-snmp/ucd-snmp-config.h>
-#include <ucd-snmp/asn1.h>
-#include <ucd-snmp/snmp.h>
-#include <ucd-snmp/snmp_impl.h>],
-               [ int a = 1;],
-               SNMP_INCLUDE="";ucdsnmp=yes,
-               ucdsnmp=)
-
-dnl #
-dnl #  If not, look for it in a number of directories and in ucd-snmp.
-dnl #
-if test "x$ucdsnmp" = "x"; then
-  old_CFLAGS="$CFLAGS"
-  for try in /usr/include /usr/local/include $snmp_include_dir; do
-    CFLAGS="$old_CFLAGS -I$try"
-    AC_TRY_COMPILE([
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <ucd-snmp/ucd-snmp-config.h>
-#include <ucd-snmp/asn1.h>
-#include <ucd-snmp/snmp.h>
-#include <ucd-snmp/snmp_impl.h>],
-                   [ int a = 1;],
-                   SNMP_INCLUDE="-I$try";ucdsnmp=yes,
-                   ucdsnmp=)
-    if test "x$ucdsnmp" != "x"; then
-      break;
-    fi
-  done
-  CFLAGS="$old_CFLAGS"
-fi
-
-if test "x$ucdsnmp" = "x"; then
-  old_CFLAGS="$CFLAGS"
-  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $snmp_include_dir; do
-    CFLAGS="$old_CFLAGS -I$try"
-dnl #
-dnl #  First, see if we can build it WITHOUT using any special includes and without ucd-snmp
-dnl #
-AC_TRY_COMPILE([
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <asn1.h>
-#include <snmp.h>
-#include <snmp_impl.h>],
-               [ int a = 1;],
-               SNMP_INCLUDE="";ucdsnmp=no,
-               ucdsnmp=)
-    if test "x$ucdsnmp" != "x"; then
-      break;
-    fi
-  done
-  CFLAGS="$old_CFLAGS"
-fi
-
-dnl #
-dnl #  If not, look for it in a number of directories and without ucd-snmp
-dnl #
-if test "x$ucdsnmp" = "x"; then
-  old_CFLAGS="$CFLAGS"
-  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $snmp_include_dir; do
-    CFLAGS="$old_CFLAGS -I$try"
-    AC_TRY_COMPILE([
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <asn1.h>
-#include <snmp.h>
-#include <snmp_impl.h>],
-                   [ int a = 1;],
-                   SNMP_INCLUDE="-I$try";ucdsnmp=no,
-                   ucdsnmp=)
-    if test "x$ucdsnmp" != "x"; then
-      break;
-    fi
-  done
-  CFLAGS="$old_CFLAGS"
-fi
-
-if test "x$ucdsnmp" = "x"; then
-  AC_MSG_RESULT(no)
-else
-  if test "x$ucdsnmp" = "xyes"; then
-    AC_MSG_RESULT((ucd-snmp)yes)
-    AC_DEFINE(HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H, [], [Define if you have the <ucd-snmp/asn1.h>, <ucd-snmp/snmp_impl.h> and <ucd-snmp/snmp.h> header file.])
-  else
-    AC_MSG_RESULT(yes)
-    AC_DEFINE(HAVE_ASN1_SNMP_SNMPIMPL_H, [], [Define if you have the <asn1.h>, <snmp_impl.h> and <snmp.h> header file.])
-  fi
-dnl #
-dnl #  Now do the same thing, looking for the SNMP library directory
-dnl #
-  AC_MSG_CHECKING([for snmp_build_var_op in -lsnmp])
-
-dnl #
-dnl #  First, see if we can build it WITHOUT using any special includes
-dnl #
-  old_LIBS="$LIBS"
-  LIBS="$old_LIBS -lsnmp"
-  AC_TRY_LINK([extern char snmp_build_var_op();],
-              [ snmp_build_var_op()],
-              SNMP_LIBS="-lsnmp",
-              SNMP_LIBS=)
-
-  if test "x$SNMP_LIBS" = "x"; then
-    for try in /usr/lib /usr/local/lib /usr/local/snmp/lib $with_snmp_lib_dir; do
-      LIBS="$old_LIBS -L$try -lsnmp"
-      AC_TRY_LINK([extern char snmp_build_var_op();],
-                  [ snmp_build_var_op()],
-                  SNMP_LIBS="-L$try -lsnmp",
-                  SNMP_LIBS=)
-      if test "x$SNMP_LIBS" != "x"; then
-        break;
-      fi
-dnl   #
-dnl   #  That didn't work.  Try adding the '-lcrypto' line.
-dnl   #  Some SNMP libraries are linked against SSL...
-dnl   #
-      LIBS="$old_LIBS -L$try -lsnmp -lcrypto"
-      AC_TRY_LINK([extern char snmp_build_var_op();],
-                  [ snmp_build_var_op()],
-                  SNMP_LIBS="-L$try -lsnmp -lcrypto",
-                  SNMP_LIBS=)
-      if test "x$SNMP_LIBS" != "x"; then
-        break;
-      fi
-dnl   #
-dnl   #  That didn't work.  Try adding the '-lkstat' line.
-dnl   #  Some SNMP libraries are linked against Kernel Statistics,
-dnl   #  in particular, Solaris 9...
-dnl   #
-      LIBS="$old_LIBS -L$try -lsnmp -lcrypto -lkstat"
-      AC_TRY_LINK([extern char snmp_build_var_op();],
-                  [ snmp_build_var_op()],
-                  SNMP_LIBS="-L$try -lsnmp -lcrypto -lkstat",
-                  SNMP_LIBS=)
-      if test "x$SNMP_LIBS" != "x"; then
-        break;
-      fi
-    done
-  fi
-  LIBS="$old_LIBS"
-
-  dnl #
-  dnl #  If one or the other isn't found, disable them both..
-  dnl #  If both are found, enable them both.
-  dnl #
-  CFLAGS="$old_CFLAGS"
-  if test "x$SNMP_LIBS" = "x"; then
-    AC_MSG_RESULT(no)
-    SNMP_INCLUDE=
-  else
-    AC_MSG_RESULT(yes)
-    AC_DEFINE(WITH_SNMP, [], [Include SNMP subagent])
-    AC_DEFINE(HAVE_LIBSNMP, [], [Define if you have the snmp library (-lsnmp).])
-  fi
-fi
-])
-
-
-dnl #
-dnl #  Locate the directory in which a particular file is found.
-dnl #
-dnl #  Usage: FR_LOCATE_DIR(MYSQLLIB_DIR, libmysqlclient.a)
-dnl #
-dnl #    Defines the variable MYSQLLIB_DIR to be the directory(s) in
-dnl #    which the file libmysqlclient.a is to be found.
-dnl #
-dnl #
-AC_DEFUN([FR_LOCATE_DIR],
-[
-dnl # If we have the program 'locate', then the problem of finding a
-dnl # particular file becomes MUCH easier.
-dnl #
-
-dnl #
-dnl #  No 'locate' defined, do NOT do anything.
-dnl #
-if test "x$LOCATE" != "x"; then
-  dnl #
-  dnl #  Root through a series of directories, looking for the given file.
-  dnl #
-  DIRS=
-  file=$2
-
-  for x in `${LOCATE} $file 2>/dev/null`; do
-    dnl #
-    dnl #  When asked for 'foo', locate will also find 'foo_bar', which we
-    dnl #  don't want.  We want that EXACT filename.
-    dnl #
-    dnl #  We ALSO want to be able to look for files like 'mysql/mysql.h',
-    dnl #  and properly match them, too.  So we try to strip off the last
-    dnl #  part of the filename, using the name of the file we're looking
-    dnl #  for.  If we CANNOT strip it off, then the name will be unchanged.
-    dnl #
-    base=`echo $x | sed "s%/${file}%%"`
-    if test "x$x" = "x$base"; then
-      continue;
-    fi
-
-    dir=`${DIRNAME} $x 2>/dev/null`
-    dnl #
-    dnl #  Exclude a number of directories.
-    dnl #
-    exclude=`echo ${dir} | ${GREP} /home`
-    if test "x$exclude" != "x"; then
-      continue
-    fi
-
-    dnl #
-    dnl #  OK, we have an exact match.  Let's be sure that we only find ONE
-    dnl #  matching directory.
-    dnl #
-    already=`echo \$$1 ${DIRS} | ${GREP} ${dir}`
-    if test "x$already" = "x"; then
-      DIRS="$DIRS $dir"
-    fi
-  done
-fi
-
-dnl #
-dnl #  And remember the directory in which we found the file.
-dnl #
-eval "$1=\"\$$1 $DIRS\""
-])
-
-
-dnl #######################################################################
-dnl #
-dnl #  Look for a library in a number of places.
-dnl #
-dnl #  FR_SMART_CHECK_LIB(library, function)
-dnl #
-AC_DEFUN([FR_SMART_CHECK_LIB], [
-
-sm_lib_safe=`echo "$1" | sed 'y%./+-%__p_%'`
-sm_func_safe=`echo "$2" | sed 'y%./+-%__p_%'`
-AC_MSG_CHECKING([for $2 in -l$1])
-
-old_LIBS="$LIBS"
-smart_lib=
-smart_lib_dir=
-
-dnl #
-dnl #  Try first any user-specified directory, otherwise we may pick up
-dnl #  the wrong version.
-dnl #
-if test "x$smart_try_dir" != "x"; then
-  for try in $smart_try_dir; do
-    LIBS="-L$try -l$1 $old_LIBS"
-    AC_TRY_LINK([extern char $2();],
-               [ $2()],
-               smart_lib="-L$try -l$1")
-    if test "x$smart_lib" != "x"; then
-      break;
-    fi
-  done
-  LIBS="$old_LIBS"
-fi
-
-dnl #
-dnl #  Try using the default library path
-dnl #
-if test "x$smart_lib" = "x"; then
-  LIBS="-l$1 $old_LIBS"
-  AC_TRY_LINK([extern char $2();],
-             [ $2()],
-             smart_lib="-l$1")
-  LIBS="$old_LIBS"
-fi
-
-dnl #
-dnl #  Try to guess possible locations.
-dnl #
-if test "x$smart_lib" = "x"; then
-  FR_LOCATE_DIR(smart_lib_dir,[lib$1${libltdl_cv_shlibext}])
-  FR_LOCATE_DIR(smart_lib_dir,[lib$1.a])
-
-  for try in $smart_lib_dir /usr/local/lib /opt/lib; do
-    LIBS="-L$try -l$1 $old_LIBS"
-    AC_TRY_LINK([extern char $2();],
-               [ $2()],
-               smart_lib="-L$try -l$1")
-    if test "x$smart_lib" != "x"; then
-      break;
-    fi
-  done
-  LIBS="$old_LIBS"
-fi
-
-dnl #
-dnl #  Found it, set the appropriate variable.
-dnl #
-if test "x$smart_lib" != "x"; then
-  AC_MSG_RESULT(yes)
-  eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
-  LIBS="$smart_lib $old_LIBS"
-  SMART_LIBS="$smart_lib $SMART_LIBS"
-else
-  AC_MSG_RESULT(no)
-fi
-])
-
-dnl #######################################################################
-dnl #
-dnl #  Look for a header file in a number of places.
-dnl #
-dnl #  FR_SMART_CHECK_INCLUDE(foo.h, [ #include <other.h> ])
-dnl #
-AC_DEFUN([FR_SMART_CHECK_INCLUDE], [
-
-ac_safe=`echo "$1" | sed 'y%./+-%__pm%'`
-AC_MSG_CHECKING([for $1])
-
-old_CFLAGS="$CFLAGS"
-smart_include=
-smart_include_dir=
-
-dnl #
-dnl #  Try first any user-specified directory, otherwise we may pick up
-dnl #  the wrong version.
-dnl #
-if test "x$smart_try_dir" != "x"; then
-  for try in $smart_try_dir; do
-    CFLAGS="$old_CFLAGS -I$try"
-    AC_TRY_COMPILE([$2
-                   #include <$1>],
-                  [ int a = 1;],
-                  smart_include="-I$try",
-                  smart_include=)
-    if test "x$smart_include" != "x"; then
-      break;
-    fi
-  done
-  CFLAGS="$old_CFLAGS"
-fi
-
-dnl #
-dnl #  Try using the default includes.
-dnl #
-if test "x$smart_include" = "x"; then
-  AC_TRY_COMPILE([$2
-                 #include <$1>],
-                [ int a = 1;],
-                smart_include=" ",
-                smart_include=)
-fi
-
-dnl #
-dnl #  Try to guess possible locations.
-dnl #
-if test "x$smart_include" = "x"; then
-  FR_LOCATE_DIR(smart_include_dir,$1)
-
-  for try in $smart_include_dir /usr/local/include /opt/include; do
-    CFLAGS="$old_CFLAGS -I$try"
-    AC_TRY_COMPILE([$2
-                   #include <$1>],
-                  [ int a = 1;],
-                  smart_include="-I$try",
-                  smart_include=)
-    if test "x$smart_include" != "x"; then
-      break;
-    fi
-  done
-  CFLAGS="$old_CFLAGS"
-fi
-
-dnl #
-dnl #  Found it, set the appropriate variable.
-dnl #
-if test "x$smart_include" != "x"; then
-  AC_MSG_RESULT(yes)
-  eval "ac_cv_header_$ac_safe=yes"
-  CFLAGS="$old_CFLAGS $smart_include"
-  SMART_CFLAGS="$SMART_CFLAGS $smart_include"
-else
-  AC_MSG_RESULT(no)
-fi
-])
-
-dnl #######################################################################
-dnl #
-dnl #  Look for a header file in a number of places.
-dnl #
-dnl #  Usage:  FR_CHECK_STRUCT_HAS_MEMBER([#include <foo.h>], [struct foo], member)
-dnl #  If the member is defined, then the variable
-dnl #     ac_cv_type_struct_foo_has_member is set to 'yes'
-dnl #
-AC_DEFUN([FR_CHECK_STRUCT_HAS_MEMBER], [
-  AC_MSG_CHECKING([for $3 in $2])
-
-dnl BASED on 'offsetof':
-dnl #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-dnl
-
-  AC_TRY_COMPILE([
-$1
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
-#endif
-],
-                 [ int foo = offsetof($2, $3) ],
-                 has_element=" ",
-                 has_element=)
-
-  ac_safe_type=`echo "$2" | sed 'y% %_%'`
-  if test "x$has_element" != "x"; then
-    AC_MSG_RESULT(yes)
-    eval "ac_cv_type_${ac_safe_type}_has_$3=yes"
-  else
-    AC_MSG_RESULT(no) 
-    eval "ac_cv_type_${ac_safe_type}_has_$3="
- fi
-])
-
-AC_INCLUDE(aclocal.m4)
index 5336a19..ff7ba14 100644 (file)
 # This line will prevent autoreconf from running aclocal again.
 # generated automatically by aclocal 1.9.5 -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005  Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+m4_include([libtool.m4])
 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
+dnl See whether we need a declaration for a function.
+dnl RADIUSD_NEED_DECLARATION(FUNCTION [, EXTRA-HEADER-FILES])
+AC_DEFUN(RADIUSD_NEED_DECLARATION,
+[AC_MSG_CHECKING([whether $1 must be declared])
+AC_CACHE_VAL(radius_cv_decl_needed_$1,
+[AC_TRY_COMPILE([
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_RESOURCE_H
+#include <resource.h>
+#endif
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+$2],
+[char *(*pfn) = (char *(*)) $1],
+eval "radius_cv_decl_needed_$1=no", eval "radius_cv_decl_needed_$1=yes")])
+if eval "test \"`echo '$radius_cv_decl_needed_'$1`\" = yes"; then
+  AC_MSG_RESULT(yes)
+  radius_tr_decl=NEED_DECLARATION_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  AC_DEFINE_UNQUOTED($radius_tr_decl)
+else
+  AC_MSG_RESULT(no)
+fi
+])dnl
 
-m4_include([libtool.m4])
+dnl Check multiple functions to see whether each needs a declaration.
+dnl RADIUSD_NEED_DECLARATIONS(FUNCTION... [, EXTRA-HEADER-FILES])
+AC_DEFUN(RADIUSD_NEED_DECLARATIONS,
+[for ac_func in $1
+do
+RADIUSD_NEED_DECLARATION($ac_func, $2)
+done
+])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+dnl Checks to see if this is SUNPro we're building with
+dnl Usage:
+dnl AC_PROG_CC_SUNPRO
+AC_DEFUN(AC_PROG_CC_SUNPRO,
+[AC_CACHE_CHECK(whether we are using SUNPro C, ac_cv_prog_suncc,
+[dnl The semicolon is to pacify NeXT's syntax-checking cpp.
+cat > conftest.c <<EOF
+#ifdef __SUNPRO_C
+  yes;
+#endif
+EOF
+if AC_TRY_COMMAND(${CC-cc} -E conftest.c) | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_suncc=yes
+else
+  ac_cv_prog_suncc=no
+fi])])
 
-# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory.  The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run.  This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-#    fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-#    fails if $ac_aux_dir is absolute,
-#    fails when called from a subdirectory in a VPATH build with
-#          a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir.  In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
-#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-#   MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH.  The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+dnl #
+dnl # AC_CHECK_TYPE_INCLUDE([#includes ...], type, default-C-types)
+dnl #
+dnl # This function is like AC_CHECK_TYPE, but you can give this one
+dnl # a list of include files to check.
+dnl #
+AC_DEFUN(AC_CHECK_TYPE_INCLUDE,
+[
+  AC_CACHE_CHECK(for $2, ac_cv_type_$2,
+    [ ac_cv_type_$2=no
+      AC_TRY_COMPILE($1,
+        [$2 foo],
+        ac_cv_type_$2=yes,
+      )
+    ]
+  )
+
+  if test "$ac_cv_type_$2" != "yes"; then
+         AC_DEFINE($2, $3)
+  fi
 ])
 
-# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+dnl #######################################################################
+dnl #
+dnl #  Look for SNMP in a variety of places.
+dnl #
+AC_DEFUN(SNMP_CHECKS, [
+       AC_SUBST(SNMP_LIBS)
+       AC_SUBST(SNMP_INCLUDE)
 
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+AC_MSG_CHECKING([for asn1.h,snmp.h,snmp_impl.h])
 
-# serial 4
+dnl #
+dnl #  First, see if we can build it WITHOUT using any special includes and in ucd-snmp
+dnl #
+AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <ucd-snmp/ucd-snmp-config.h>
+#include <ucd-snmp/asn1.h>
+#include <ucd-snmp/snmp.h>
+#include <ucd-snmp/snmp_impl.h>],
+               [ int a = 1;],
+               SNMP_INCLUDE="";ucdsnmp=yes,
+               ucdsnmp=)
 
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
+dnl #
+dnl #  If not, look for it in a number of directories and in ucd-snmp.
+dnl #
+if test "x$ucdsnmp" = "x"; then
+  old_CFLAGS="$CFLAGS"
+  for try in /usr/include /usr/local/include $with_snmp_include_dir; do
+    CFLAGS="$old_CFLAGS -I$try"
+    AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <ucd-snmp/ucd-snmp-config.h>
+#include <ucd-snmp/asn1.h>
+#include <ucd-snmp/snmp.h>
+#include <ucd-snmp/snmp_impl.h>],
+                   [ int a = 1;],
+                   SNMP_INCLUDE="-I$try";ucdsnmp=yes,
+                   ucdsnmp=)
+    if test "x$ucdsnmp" != "x"; then
+      break;
+    fi
+  done
+  CFLAGS="$old_CFLAGS"
+fi
+
+if test "x$ucdsnmp" = "x"; then
+  old_CFLAGS="$CFLAGS"
+  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $with_snmp_include_dir; do
+    CFLAGS="$old_CFLAGS -I$try"
+dnl #
+dnl #  First, see if we can build it WITHOUT using any special includes and without ucd-snmp
+dnl #
+AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <asn1.h>
+#include <snmp.h>
+#include <snmp_impl.h>],
+               [ int a = 1;],
+               SNMP_INCLUDE="";ucdsnmp=no,
+               ucdsnmp=)
+    if test "x$ucdsnmp" != "x"; then
+      break;
+    fi
+  done
+  CFLAGS="$old_CFLAGS"
+fi
 
+dnl #
+dnl #  If not, look for it in a number of directories and without ucd-snmp
+dnl #
+if test "x$ucdsnmp" = "x"; then
+  old_CFLAGS="$CFLAGS"
+  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $with_snmp_include_dir; do
+    CFLAGS="$old_CFLAGS -I$try"
+    AC_TRY_COMPILE([
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <asn1.h>
+#include <snmp.h>
+#include <snmp_impl.h>],
+                   [ int a = 1;],
+                   SNMP_INCLUDE="-I$try";ucdsnmp=no,
+                   ucdsnmp=)
+    if test "x$ucdsnmp" != "x"; then
+      break;
+    fi
+  done
+  CFLAGS="$old_CFLAGS"
+fi
 
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
-  am_missing_run="$MISSING --run "
+if test "x$ucdsnmp" = "x"; then
+  AC_MSG_RESULT(no)
 else
-  am_missing_run=
-  AC_MSG_WARN([`missing' script is too old or missing])
+  if test "x$ucdsnmp" = "xyes"; then
+    AC_MSG_RESULT((ucd-snmp)yes)
+    AC_DEFINE(HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H)
+  else
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_ASN1_SNMP_SNMPIMPL_H)
+  fi
+dnl #
+dnl #  Now do the same thing, looking for the SNMP library directory
+dnl #
+  AC_MSG_CHECKING([for snmp_build_var_op in -lsnmp])
+
+dnl #
+dnl #  First, see if we can build it WITHOUT using any special includes
+dnl #
+  old_LIBS="$LIBS"
+  LIBS="$old_LIBS -lsnmp"
+  AC_TRY_LINK([extern char snmp_build_var_op();],
+              [ snmp_build_var_op()],
+              SNMP_LIBS="-lsnmp",
+              SNMP_LIBS=)
+
+  if test "x$SNMP_LIBS" = "x"; then
+    for try in /usr/lib /usr/local/lib /usr/local/snmp/lib $with_snmp_lib_dir; do
+      LIBS="$old_LIBS -L$try -lsnmp"
+      AC_TRY_LINK([extern char snmp_build_var_op();],
+                  [ snmp_build_var_op()],
+                  SNMP_LIBS="-L$try -lsnmp",
+                  SNMP_LIBS=)
+      if test "x$SNMP_LIBS" != "x"; then
+        break;
+      fi
+dnl   #
+dnl   #  That didn't work.  Try adding the '-lcrypto' line.
+dnl   #  Some SNMP libraries are linked against SSL...
+dnl   #
+      LIBS="$old_LIBS -L$try -lsnmp -lcrypto"
+      AC_TRY_LINK([extern char snmp_build_var_op();],
+                  [ snmp_build_var_op()],
+                  SNMP_LIBS="-L$try -lsnmp -lcrypto",
+                  SNMP_LIBS=)
+      if test "x$SNMP_LIBS" != "x"; then
+        break;
+      fi
+dnl   #
+dnl   #  That didn't work.  Try adding the '-lkstat' line.
+dnl   #  Some SNMP libraries are linked against Kernel Statistics,
+dnl   #  in particular, Solaris 9...
+dnl   #
+      LIBS="$old_LIBS -L$try -lsnmp -lcrypto -lkstat"
+      AC_TRY_LINK([extern char snmp_build_var_op();],
+                  [ snmp_build_var_op()],
+                  SNMP_LIBS="-L$try -lsnmp -lcrypto -lkstat",
+                  SNMP_LIBS=)
+      if test "x$SNMP_LIBS" != "x"; then
+        break;
+      fi
+    done
+  fi
+  LIBS="$old_LIBS"
+
+  dnl #
+  dnl #  If one or the other isn't found, disable them both..
+  dnl #  If both are found, enable them both.
+  dnl #
+  CFLAGS="$old_CFLAGS"
+  if test "x$SNMP_LIBS" = "x"; then
+    AC_MSG_RESULT(no)
+    SNMP_INCLUDE=
+  else
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(WITH_SNMP)
+    AC_DEFINE(HAVE_LIBSNMP)
+  fi
+fi
+])
+
+
+dnl #
+dnl #  Locate the directory in which a particular file is found.
+dnl #
+dnl #  Usage: AC_LOCATE_DIR(MYSQLLIB_DIR, libmysqlclient.a)
+dnl #
+dnl #    Defines the variable MYSQLLIB_DIR to be the directory(s) in
+dnl #    which the file libmysqlclient.a is to be found.
+dnl #
+dnl #
+AC_DEFUN(AC_LOCATE_DIR,
+[
+dnl # If we have the program 'locate', then the problem of finding a
+dnl # particular file becomes MUCH easier.
+dnl #
+
+dnl #
+dnl #  No 'locate' defined, do NOT do anything.
+dnl #
+if test "x$LOCATE" != "x"; then
+  dnl #
+  dnl #  Root through a series of directories, looking for the given file.
+  dnl #
+  DIRS=
+  file=$2
+
+  for x in `${LOCATE} $file 2>/dev/null`; do
+    dnl #
+    dnl #  When asked for 'foo', locate will also find 'foo_bar', which we
+    dnl #  don't want.  We want that EXACT filename.
+    dnl #
+    dnl #  We ALSO want to be able to look for files like 'mysql/mysql.h',
+    dnl #  and properly match them, too.  So we try to strip off the last
+    dnl #  part of the filename, using the name of the file we're looking
+    dnl #  for.  If we CANNOT strip it off, then the name will be unchanged.
+    dnl #
+    base=`echo $x | sed "s%/${file}%%"`
+    if test "x$x" = "x$base"; then
+      continue;
+    fi
+
+    dir=`${DIRNAME} $x 2>/dev/null`
+    dnl #
+    dnl #  Exclude a number of directories.
+    dnl #
+    exclude=`echo ${dir} | ${GREP} /home`
+    if test "x$exclude" != "x"; then
+      continue
+    fi
+
+    dnl #
+    dnl #  OK, we have an exact match.  Let's be sure that we only find ONE
+    dnl #  matching directory.
+    dnl #
+    already=`echo \$$1 ${DIRS} | ${GREP} ${dir}`
+    if test "x$already" = "x"; then
+      DIRS="$DIRS $dir"
+    fi
+  done
 fi
+
+dnl #
+dnl #  And remember the directory in which we found the file.
+dnl #
+eval "$1=\"\$$1 $DIRS\""
 ])
 
-m4_include([acinclude.m4])
+
+dnl #######################################################################
+dnl #
+dnl #  Look for a library in a number of places.
+dnl #
+dnl #  AC_SMART_CHECK_LIB(library, function)
+dnl #
+AC_DEFUN(AC_SMART_CHECK_LIB, [
+
+sm_lib_safe=`echo "$1" | sed 'y%./+-%__p_%'`
+sm_func_safe=`echo "$2" | sed 'y%./+-%__p_%'`
+AC_MSG_CHECKING([for $2 in -l$1])
+
+old_LIBS="$LIBS"
+smart_lib=
+smart_lib_dir=
+
+dnl #
+dnl #  Try first any user-specified directory, otherwise we may pick up
+dnl #  the wrong version.
+dnl #
+if test "x$smart_try_dir" != "x"; then
+  for try in $smart_try_dir; do
+    LIBS="-L$try -l$1 $old_LIBS"
+    AC_TRY_LINK([extern char $2();],
+               [ $2()],
+               smart_lib="-L$try -l$1")
+    if test "x$smart_lib" != "x"; then
+      break;
+    fi
+  done
+  LIBS="$old_LIBS"
+fi
+
+dnl #
+dnl #  Try using the default library path.
+dnl #
+if test "x$smart_lib" = "x"; then
+  LIBS="-l$1 $old_LIBS"
+  AC_TRY_LINK([extern char $2();],
+             [ $2()],
+             smart_lib="-l$1")
+  LIBS="$old_LIBS"
+fi
+
+dnl #
+dnl #  Try to guess possible locations.
+dnl #
+if test "x$smart_lib" = "x"; then
+  AC_LOCATE_DIR(smart_lib_dir,[lib$1${libltdl_cv_shlibext}])
+  AC_LOCATE_DIR(smart_lib_dir,[lib$1.a])
+
+  for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+    LIBS="-L$try -l$1 $old_LIBS"
+    AC_TRY_LINK([extern char $2();],
+               [ $2()],
+               smart_lib="-L$try -l$1")
+    if test "x$smart_lib" != "x"; then
+      break;
+    fi
+  done
+  LIBS="$old_LIBS"
+fi
+
+dnl #
+dnl #  Found it, set the appropriate variable.
+dnl #
+if test "x$smart_lib" != "x"; then
+  AC_MSG_RESULT(yes)
+  eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+  LIBS="$smart_lib $old_LIBS"
+  SMART_LIBS="$smart_lib $SMART_LIBS"
+else
+  AC_MSG_RESULT(no)
+fi
+])
+
+dnl #######################################################################
+dnl #
+dnl #  Look for a header file in a number of places.
+dnl #
+dnl #  AC_SMART_CHECK_INCLUDE(foo.h, [ #include <other.h> ])
+dnl #
+AC_DEFUN(AC_SMART_CHECK_INCLUDE, [
+
+ac_safe=`echo "$1" | sed 'y%./+-%__pm%'`
+AC_MSG_CHECKING([for $1])
+
+old_CFLAGS="$CFLAGS"
+smart_include=
+smart_include_dir=
+
+dnl #
+dnl #  Try first any user-specified directory, otherwise we may pick up
+dnl #  the wrong version.
+dnl #
+if test "x$smart_try_dir" != "x"; then
+  for try in $smart_try_dir; do
+    CFLAGS="$old_CFLAGS -I$try"
+    AC_TRY_COMPILE([$2
+                   #include <$1>],
+                  [ int a = 1;],
+                  smart_include="-I$try",
+                  smart_include=)
+    if test "x$smart_include" != "x"; then
+      break;
+    fi
+  done
+  CFLAGS="$old_CFLAGS"
+fi
+
+dnl #
+dnl #  Try using the default includes
+dnl #
+if test "x$smart_include" = "x"; then
+  AC_TRY_COMPILE([$2
+                 #include <$1>],
+                [ int a = 1;],
+                smart_include=" ",
+                smart_include=)
+fi
+
+dnl #
+dnl #  Try to guess possible locations.
+dnl #
+if test "x$smart_include" = "x"; then
+  AC_LOCATE_DIR(smart_include_dir,$1)
+
+  for try in $smart_include_dir /usr/local/include /opt/include; do
+    CFLAGS="$old_CFLAGS -I$try"
+    AC_TRY_COMPILE([$2
+                   #include <$1>],
+                  [ int a = 1;],
+                  smart_include="-I$try",
+                  smart_include=)
+    if test "x$smart_include" != "x"; then
+      break;
+    fi
+  done
+  CFLAGS="$old_CFLAGS"
+fi
+
+dnl #
+dnl #  Found it, set the appropriate variable.
+dnl #
+if test "x$smart_include" != "x"; then
+  AC_MSG_RESULT(yes)
+  eval "ac_cv_header_$ac_safe=yes"
+  CFLAGS="$old_CFLAGS $smart_include"
+  SMART_CFLAGS="$SMART_CFLAGS $smart_include"
+else
+  AC_MSG_RESULT(no)
+fi
+])
+
+dnl #######################################################################
+dnl #
+dnl #  Look for a header file in a number of places.
+dnl #
+dnl #  Usage:  AC_CHECK_STRUCT_HAS_MEMBER([#include <foo.h>], [struct foo], member)
+dnl #  If the member is defined, then the variable
+dnl #     ac_cv_type_struct_foo_has_member is set to 'yes'
+dnl #
+AC_DEFUN(AC_CHECK_STRUCT_HAS_MEMBER, [
+  AC_MSG_CHECKING([for $3 in $2])
+
+dnl BASED on 'offsetof':
+dnl #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+dnl
+
+  AC_TRY_COMPILE([
+$1
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
+#endif
+],
+                 [ int foo = offsetof($2, $3) ],
+                 has_element=" ",
+                 has_element=)
+
+  ac_safe_type=`echo "$2" | sed 'y% %_%'`
+  if test "x$has_element" != "x"; then
+    AC_MSG_RESULT(yes)
+    eval "ac_cv_type_${ac_safe_type}_has_$3=yes"
+  else
+    AC_MSG_RESULT(no) 
+    eval "ac_cv_type_${ac_safe_type}_has_$3="
+ fi
+])
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755 (executable)
index 9cba642..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh -e
-
-parentdir=`dirname $0`
-
-cd $parentdir
-parentdir=`pwd`
-
-libtoolize -f -c
-#aclocal
-autoheader
-autoconf
-
-mysubdirs="$mysubdirs `find src/modules/ -name configure -print | sed 's%/configure%%'`"
-mysubdirs=`echo $mysubdirs`
-
-for F in $mysubdirs
-do
-       echo "Configuring in $F..."
-       (cd $F && grep "^AC_CONFIG_HEADER" configure.in > /dev/null && autoheader -I$parentdir)
-       (cd $F && autoconf -I$parentdir)
-done
index 8229471..51fab47 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2004-11-12'
+timestamp='2004-03-12'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
@@ -203,15 +203,15 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     amiga:OpenBSD:*:*)
        echo m68k-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
     cats:OpenBSD:*:*)
        echo arm-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
     hp300:OpenBSD:*:*)
        echo m68k-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
-    luna88k:OpenBSD:*:*)
-       echo m88k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
     mac68k:OpenBSD:*:*)
        echo m68k-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
@@ -227,12 +227,21 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     mvmeppc:OpenBSD:*:*)
        echo powerpc-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
+    pegasos:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
     sgi:OpenBSD:*:*)
-       echo mips64-unknown-openbsd${UNAME_RELEASE}
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
     sun3:OpenBSD:*:*)
        echo m68k-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
     *:OpenBSD:*:*)
        echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
        exit 0 ;;
@@ -298,6 +307,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # 1.2 uses "1.2" for uname -r.
        echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
        exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+       echo alpha-hp-vms
+       exit 0 ;;
     Alpha\ *:Windows_NT*:*)
        # How do we know it's Interix rather than the generic POSIX subsystem?
        # Should we change UNAME_MACHINE based on the output of uname instead
@@ -319,9 +331,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:OS/390:*:*)
        echo i370-ibm-openedition
        exit 0 ;;
-    *:z/VM:*:*)
-       echo s390-ibm-zvmoe
-       exit 0 ;;
     *:OS400:*:*)
         echo powerpc-ibm-os400
        exit 0 ;;
@@ -345,7 +354,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     DRS?6000:unix:4.0:6*)
        echo sparc-icl-nx6
        exit 0 ;;
-    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+    DRS?6000:UNIX_SV:4.2*:7*)
        case `/usr/bin/uname -p` in
            sparc) echo sparc-icl-nx7 && exit 0 ;;
        esac ;;
@@ -755,7 +764,7 @@ EOF
        echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
        exit 0 ;;
     *:UNICOS/mp:*:*)
-       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
        exit 0 ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
        FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
@@ -778,7 +787,21 @@ EOF
        echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
        exit 0 ;;
     *:FreeBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       # Determine whether the default compiler uses glibc.
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #if __GLIBC__ >= 2
+       LIBC=gnu
+       #else
+       LIBC=
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       # GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+       # FreeBSD's kernel, but not the complete OS.
+       case ${LIBC} in gnu) kernel_only='k' ;; esac
+       echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
        exit 0 ;;
     i*:CYGWIN*:*)
        echo ${UNAME_MACHINE}-pc-cygwin
@@ -827,12 +850,6 @@ EOF
     cris:Linux:*:*)
        echo cris-axis-linux-gnu
        exit 0 ;;
-    crisv32:Linux:*:*)
-       echo crisv32-axis-linux-gnu
-       exit 0 ;;
-    frv:Linux:*:*)
-       echo frv-unknown-linux-gnu
-       exit 0 ;;
     ia64:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit 0 ;;
@@ -1079,9 +1096,9 @@ EOF
     M680?0:D-NIX:5.3:*)
        echo m68k-diab-dnix
        exit 0 ;;
-    M68*:*:R3V[5678]*:*)
+    M68*:*:R3V[567]*:*)
        test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
-    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
        OS_REL=''
        test -r /etc/.relid \
        && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -1179,10 +1196,9 @@ EOF
        echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
        exit 0 ;;
     *:Darwin:*:*)
-       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       case $UNAME_PROCESSOR in
+       case `uname -p` in
            *86) UNAME_PROCESSOR=i686 ;;
-           unknown) UNAME_PROCESSOR=powerpc ;;
+           powerpc) UNAME_PROCESSOR=powerpc ;;
        esac
        echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
        exit 0 ;;
@@ -1244,16 +1260,6 @@ EOF
     *:DragonFly:*:*)
        echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
        exit 0 ;;
-    *:*VMS:*:*)
-       UNAME_MACHINE=`(uname -p) 2>/dev/null`
-       case "${UNAME_MACHINE}" in
-           A*) echo alpha-dec-vms && exit 0 ;;
-           I*) echo ia64-dec-vms && exit 0 ;;
-           V*) echo vax-dec-vms && exit 0 ;;
-       esac ;;
-    *:XENIX:*:SysV)
-       echo i386-pc-xenix
-       exit 0 ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..98ed4a3
--- /dev/null
@@ -0,0 +1,19 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
+
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
+
+*/
+
+
+#ifndef HAVE_SNPRINTF
+#define HAVE_LOCAL_SNPRINTF
+#define snprintf lrad_snprintf
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#define HAVE_LOCAL_SNPRINTF
+#define vsnprintf lrad_vsnprintf
+#endif
index 0f84ac2..ba33103 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2004-11-30'
+timestamp='2004-03-12'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -70,7 +70,7 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
@@ -145,7 +145,7 @@ case $os in
        -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
        -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
        -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray)
+       -apple | -axis)
                os=
                basic_machine=$1
                ;;
@@ -267,7 +267,7 @@ case $basic_machine in
        | tahoe | thumb | tic4x | tic80 | tron \
        | v850 | v850e \
        | we32k \
-       | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | x86 | xscale | xstormy16 | xtensa \
        | z8k)
                basic_machine=$basic_machine-unknown
                ;;
@@ -300,7 +300,7 @@ case $basic_machine in
        | avr-* \
        | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
-       | clipper-* | craynv-* | cydra-* \
+       | clipper-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
        | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
@@ -326,9 +326,8 @@ case $basic_machine in
        | mipsisa64sb1-* | mipsisa64sb1el-* \
        | mipsisa64sr71k-* | mipsisa64sr71kel-* \
        | mipstx39-* | mipstx39el-* \
-       | mmix-* \
        | msp430-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
+       | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
@@ -343,8 +342,8 @@ case $basic_machine in
        | tron-* \
        | v850-* | v850e-* | vax-* \
        | we32k-* \
-       | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
-       | xstormy16-* | xtensa-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+       | xtensa-* \
        | ymp-* \
        | z8k-*)
                ;;
@@ -446,10 +445,6 @@ case $basic_machine in
                basic_machine=j90-cray
                os=-unicos
                ;;
-       craynv)
-               basic_machine=craynv-cray
-               os=-unicosmp
-               ;;
        cr16c)
                basic_machine=cr16c-unknown
                os=-elf
@@ -457,9 +452,6 @@ case $basic_machine in
        crds | unos)
                basic_machine=m68k-crds
                ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
-               ;;
        cris | cris-* | etrax*)
                basic_machine=cris-axis
                ;;
@@ -489,10 +481,6 @@ case $basic_machine in
                basic_machine=m88k-motorola
                os=-sysv3
                ;;
-       djgpp)
-               basic_machine=i586-pc
-               os=-msdosdjgpp
-               ;;
        dpx20 | dpx20-*)
                basic_machine=rs6000-bull
                os=-bosx
@@ -671,6 +659,10 @@ case $basic_machine in
        mips3*)
                basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
                ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
        monitor)
                basic_machine=m68k-rom68k
                os=-coff
@@ -751,6 +743,10 @@ case $basic_machine in
        np1)
                basic_machine=np1-gould
                ;;
+       nv1)
+               basic_machine=nv1-cray
+               os=-unicosmp
+               ;;
        nsr-tandem)
                basic_machine=nsr-tandem
                ;;
@@ -1033,10 +1029,6 @@ case $basic_machine in
                basic_machine=hppa1.1-winbond
                os=-proelf
                ;;
-       xbox)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
        xps | xps100)
                basic_machine=xps100-honeywell
                ;;
@@ -1067,9 +1059,6 @@ case $basic_machine in
        romp)
                basic_machine=romp-ibm
                ;;
-       mmix)
-               basic_machine=mmix-knuth
-               ;;
        rs6000)
                basic_machine=rs6000-ibm
                ;;
@@ -1305,9 +1294,6 @@ case $os in
        -kaos*)
                os=-kaos
                ;;
-       -zvmoe)
-               os=-zvmoe
-               ;;
        -none)
                ;;
        *)
@@ -1388,9 +1374,6 @@ case $basic_machine in
        *-ibm)
                os=-aix
                ;;
-       *-knuth)
-               os=-mmixware
-               ;;
        *-wec)
                os=-proelf
                ;;
index 577b4d4..8f7ec66 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
-# From configure.in Revision: 1.236 .
+# From configure.in Revision: 1.198.2.15.2.14 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.60.
+# Generated by GNU Autoconf 2.60a.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -720,36 +720,36 @@ ac_unique_file="src/main/radiusd.c"
 # Factoring default headers for most tests.
 ac_includes_default="\
 #include <stdio.h>
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
 # include <sys/types.h>
 #endif
-#if HAVE_SYS_STAT_H
+#ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
-#if STDC_HEADERS
+#ifdef STDC_HEADERS
 # include <stdlib.h>
 # include <stddef.h>
 #else
-# if HAVE_STDLIB_H
+# ifdef HAVE_STDLIB_H
 #  include <stdlib.h>
 # endif
 #endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
 #  include <memory.h>
 # endif
 # include <string.h>
 #endif
-#if HAVE_STRINGS_H
+#ifdef HAVE_STRINGS_H
 # include <strings.h>
 #endif
-#if HAVE_INTTYPES_H
+#ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
 #endif
-#if HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
-#if HAVE_UNISTD_H
+#ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
@@ -797,13 +797,11 @@ CPPFLAGS
 ac_ct_CC
 EXEEXT
 OBJEXT
-CXX
-CXXFLAGS
-ac_ct_CXX
 CPP
 GREP
 EGREP
 RANLIB
+abs_top_builddir
 GMAKE
 MAKE
 LTDL_SUBDIRS
@@ -820,6 +818,9 @@ LN_S
 ECHO
 AR
 STRIP
+CXX
+CXXFLAGS
+ac_ct_CXX
 CXXCPP
 F77
 FFLAGS
@@ -840,11 +841,14 @@ REGEX
 REGEX_EXTENDED
 OPENSSL_INCLUDE
 OPENSSL_LIBS
-PCAP_LIBS
 LIBPREFIX
 CRYPTLIB
 SNMP_LIBS
 SNMP_INCLUDE
+GETCONF
+LFS_CFLAGS
+LFS_LDFLAGS
+LFS_LIBS
 HOSTINFO
 LIBLTDL
 INCLTDL
@@ -867,10 +871,10 @@ CC
 CFLAGS
 LDFLAGS
 CPPFLAGS
+CPP
 CXX
 CXXFLAGS
 CCC
-CPP
 CXXCPP
 F77
 FFLAGS'
@@ -1446,7 +1450,6 @@ if test -n "$ac_init_help"; then
 Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --disable-largefile     omit support for large files
   --enable-shared[=PKGS]  build shared libraries [default=yes]
   --enable-static[=PKGS]  build static libraries [default=yes]
   --enable-fast-install[=PKGS]
@@ -1470,6 +1473,7 @@ Optional Packages:
   --with-ascend-binary    Include support for Ascend binary filter attributes (default=yes)
   --with-threads          Use threads, if available.  (default=yes)
   --with-snmp             Compile in SNMP support. (default=yes)
+  --with-large-files      Compile in large (2G+) file support. (default=no)
   --with-static-modules=QUOTED-MODULE-LIST
  --with-modules=QUOTED-MODULE-LIST
   --with-experimental-modules      Use experimental and unstable modules. (default=no)
@@ -1477,7 +1481,8 @@ Optional Packages:
   --with-openssl-libraries=DIR     Directory to look for OpenSSL library files
   --with-rlm-FOO-lib-dir=DIR       Directory to look for library files used by module FOO
   --with-rlm-FOO-include-dir=DIR   Directory to look for include files used by module FOO
-  --with-udpfromto        Compile in UDPFROMTO support. (default=yes)
+  --with-udpfromto        Compile in UDPFROMTO support. (default=no)
+  --with-edir             Enable Novell eDirectory integration.  (default=no)
 
 Some influential environment variables:
   CC          C compiler command
@@ -1486,9 +1491,9 @@ Some influential environment variables:
               nonstandard directory <lib dir>
   CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
-  CPP         C preprocessor
   CXXCPP      C++ preprocessor
   F77         Fortran 77 compiler command
   FFLAGS      Fortran 77 compiler flags
@@ -1557,7 +1562,7 @@ test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 configure
-generated by GNU Autoconf 2.60
+generated by GNU Autoconf 2.60a
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -1571,7 +1576,7 @@ This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.60a.  Invocation command line was
 
   $ $0 $@
 
@@ -1918,10 +1923,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 ac_config_headers="$ac_config_headers src/include/autoconf.h"
 
 
-RADIUSD_MAJOR_VERSION=2
-RADIUSD_MINOR_VERSION=0.0-pre1
+
+RADIUSD_MAJOR_VERSION=1
+RADIUSD_MINOR_VERSION=1.6
 RADIUSD_VERSION="${RADIUSD_MAJOR_VERSION}.${RADIUSD_MINOR_VERSION}"
-PACKAGE=freeradius
 
 
 ac_ext=c
@@ -2327,7 +2332,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 # in a Makefile.  We should not override ac_cv_exeext if it was cached,
 # so that the user can short-circuit this test for compilers unknown to
 # Autoconf.
-for ac_file in $ac_files
+for ac_file in $ac_files ''
 do
   test -f "$ac_file" || continue
   case $ac_file in
@@ -2355,6 +2360,12 @@ done
 test "$ac_cv_exeext" = no && ac_cv_exeext=
 
 else
+  ac_file=''
+fi
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
@@ -2366,8 +2377,6 @@ See \`config.log' for more details." >&2;}
 fi
 
 ac_exeext=$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
 
 # Check that the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
@@ -2924,459 +2933,146 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
-  if test -n "$CCC"; then
-    CXX=$CCC
-  else
-    if test -n "$ac_tool_prefix"; then
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CXX"; then
-  ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
-  { echo "$as_me:$LINENO: result: $CXX" >&5
-echo "${ECHO_T}$CXX" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
 
-    test -n "$CXX" && break
-  done
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
 fi
-if test -z "$CXX"; then
-  ac_ct_CXX=$CXX
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test -n "$ac_ct_CXX"; then
-  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
 do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CXX="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
-echo "${ECHO_T}$ac_ct_CXX" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CXX" && break
-done
-
-  if test "x$ac_ct_CXX" = x; then
-    CXX="g++"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CXX=$ac_ct_CXX
-  fi
-fi
-
-  fi
-fi
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C++ compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
 #endif
-
-  ;
-  return 0;
-}
+                    Syntax error
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_compiler_gnu=yes
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_compiler_gnu=no
+  # Broken: fails on valid input.
+continue
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+rm -f conftest.err conftest.$ac_ext
 
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
-GXX=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
-echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cxx_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
-   ac_cxx_werror_flag=yes
-   ac_cv_prog_cxx_g=no
-   CXXFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cxx_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       CXXFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
+#include <ac_nonexistent.h>
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-        CXXFLAGS="-g"
-        cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cxx_g=yes
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  # Passes both tests.
+ac_preproc_ok=:
+break
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
+rm -f conftest.err conftest.$ac_ext
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
-  CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
-  if test "$GXX" = yes; then
-    CXXFLAGS="-g -O2"
-  else
-    CXXFLAGS="-g"
-  fi
-else
-  if test "$GXX" = yes; then
-    CXXFLAGS="-O2"
-  else
-    CXXFLAGS=
-  fi
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
 fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
 
+    done
+    ac_cv_prog_CPP=$CPP
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
 fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  CPP=$ac_cv_prog_CPP
 else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
+  ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
@@ -3482,139 +3178,20 @@ done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then
-  break
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
 fi
 
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
-else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
@@ -3979,39 +3556,28 @@ else
 fi
 
 
-# Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then
-  enableval=$enable_largefile;
-fi
+abs_top_builddir=`pwd`
 
-if test "$enable_largefile" != no; then
 
-  { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
-echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_largefile_CC+set}" = set; then
+
+PACKAGE=freeradius
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_sys_largefile_CC=no
-     if test "$GCC" != yes; then
-       ac_save_CC=$CC
-       while :; do
-        # IRIX 6.2 and later do not support large files by default,
-        # so use the C compiler's -n32 option if that helps.
-        cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
 int
 main ()
 {
@@ -4020,7 +3586,7 @@ main ()
   return 0;
 }
 _ACEOF
-        rm -f conftest.$ac_objext
+rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -4054,126 +3620,105 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  break
+  ac_cv_header_stdc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_header_stdc=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext
-        CC="$CC -n32"
-        rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_sys_largefile_CC=' -n32'; break
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
 
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
 
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
 fi
+rm -f conftest*
 
-rm -f core conftest.err conftest.$ac_objext
-        break
-       done
-       CC=$ac_save_CC
-       rm -f conftest.$ac_ext
-    fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
-  if test "$ac_cv_sys_largefile_CC" != no; then
-    CC=$CC$ac_cv_sys_largefile_CC
-  fi
 
-  { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
 else
-  while :; do
-  ac_cv_sys_file_offset_bits=no
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
 int
 main ()
 {
-
-  ;
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      return 2;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -4183,38 +3728,59 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  break
+  :
 else
-  echo "$as_me: failed program was:" >&5
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
 
 fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
+$ac_includes_default
 
-  ;
-  return 0;
-}
+#include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -4250,53 +3816,51 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sys_file_offset_bits=64; break
+  eval "$as_ac_Header=yes"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       eval "$as_ac_Header=no"
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  break
-done
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
-echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
-if test "$ac_cv_sys_file_offset_bits" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
 fi
-rm -f conftest*
-  { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
-echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
-if test "${ac_cv_sys_large_files+set}" = set; then
+
+done
+
+
+{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  while :; do
-  ac_cv_sys_large_files=no
-  cat >conftest.$ac_ext <<_ACEOF
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
+#include <sys/param.h>
+
 int
 main ()
 {
+#if  ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \
+       && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN)
+ bogus endian macros
+#endif
 
   ;
   return 0;
@@ -4336,34 +3900,22 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#define _LARGE_FILES 1
 #include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
+#include <sys/param.h>
+
 int
 main ()
 {
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
 
   ;
   return 0;
@@ -4403,51 +3955,39 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_sys_large_files=1; break
+  ac_cv_c_bigendian=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_c_bigendian=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  break
-done
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
-echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
-if test "$ac_cv_sys_large_files" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-
-fi
-rm -f conftest*
-fi
-
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       # It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
 int
 main ()
 {
-
+ _ascii (); _ebcdic ();
   ;
   return 0;
 }
@@ -4486,62 +4026,25 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_header_stdc=yes
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_header_stdc=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
 
 fi
 
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
-  :
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -4549,28 +4052,21 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+$ac_includes_default
 int
 main ()
 {
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
+
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long int l;
+    char c[sizeof (long int)];
+  } u;
+  u.l = 1;
+  return u.c[sizeof (long int) - 1] == 1;
+
+  ;
   return 0;
 }
 _ACEOF
@@ -4594,151 +4090,212 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  :
+  ac_cv_c_bigendian=no
 else
   echo "$as_me: program exited with status $ac_status" >&5
 echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 ( exit $ac_status )
-ac_cv_header_stdc=no
+ac_cv_c_bigendian=yes
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
 
 
 fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6; }
+case $ac_cv_c_bigendian in
+  yes)
 
 cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
+#define WORDS_BIGENDIAN 1
 _ACEOF
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
 
 
+# Extract the first word of "gmake", so it can be a program name with args.
+set dummy gmake; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_GMAKE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$GMAKE"; then
+  ac_cv_prog_GMAKE="$GMAKE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_GMAKE="yes"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
+  test -z "$ac_cv_prog_GMAKE" && ac_cv_prog_GMAKE="no"
+fi
+fi
+GMAKE=$ac_cv_prog_GMAKE
+if test -n "$GMAKE"; then
+  { echo "$as_me:$LINENO: result: $GMAKE" >&5
+echo "${ECHO_T}$GMAKE" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
 
 
+if test $GMAKE = no; then
+  # Extract the first word of "make", so it can be a program name with args.
+set dummy make; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_MAKE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAKE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
+  test -z "$ac_cv_path_MAKE" && ac_cv_path_MAKE="/usr/local/bin/make"
+  ;;
+esac
+fi
+MAKE=$ac_cv_path_MAKE
+if test -n "$MAKE"; then
+  { echo "$as_me:$LINENO: result: $MAKE" >&5
+echo "${ECHO_T}$MAKE" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
 
 
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-                 inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+else
+  # Extract the first word of "gmake", so it can be a program name with args.
+set dummy gmake; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_MAKE+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
+  case $MAKE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+  test -z "$ac_cv_path_MAKE" && ac_cv_path_MAKE="/usr/local/gnu/bin/make"
+  ;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  eval "$as_ac_Header=yes"
+fi
+MAKE=$ac_cv_path_MAKE
+if test -n "$MAKE"; then
+  { echo "$as_me:$LINENO: result: $MAKE" >&5
+echo "${ECHO_T}$MAKE" >&6; }
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       eval "$as_ac_Header=no"
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
 
 fi
+makever=`$ac_cv_path_MAKE --version 2>&1 | grep "GNU Make"`
+if test -z "$makever"; then
+  { { echo "$as_me:$LINENO: error: GNU Make is not installed.  Please download and install it
+               from ftp://prep.ai.mit.edu/pub/gnu/make/ before continuing." >&5
+echo "$as_me: error: GNU Make is not installed.  Please download and install it
+               from ftp://prep.ai.mit.edu/pub/gnu/make/ before continuing." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 
-done
-
-
-{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
-echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then
+  { echo "$as_me:$LINENO: checking for lt_dlinit in -lltdl" >&5
+echo $ECHO_N "checking for lt_dlinit in -lltdl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ltdl_lt_dlinit+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  # See if sys/param.h defines the BYTE_ORDER macro.
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lltdl  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/param.h>
 
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char lt_dlinit ();
 int
 main ()
 {
-#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
-#endif
-
+return lt_dlinit ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -4755,7 +4312,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -4765,1233 +4322,1228 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  # It does; now see whether it defined to BIG_ENDIAN or not.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/param.h>
+  ac_cv_lib_ltdl_lt_dlinit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif
+       ac_cv_lib_ltdl_lt_dlinit=no
+fi
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_c_bigendian=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cv_c_bigendian=no
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ltdl_lt_dlinit" >&5
+echo "${ECHO_T}$ac_cv_lib_ltdl_lt_dlinit" >&6; }
+if test $ac_cv_lib_ltdl_lt_dlinit = yes; then
+  test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  if test x"$enable_ltdl_install" = xno; then
+     { echo "$as_me:$LINENO: WARNING: libltdl not installed, but installation disabled" >&5
+echo "$as_me: WARNING: libltdl not installed, but installation disabled" >&2;}
+   else
+     enable_ltdl_install=yes
+   fi
 
-       # It does not; compile a test program.
-if test "$cross_compiling" = yes; then
-  # try to guess the endianness by grepping values into an object file
-  ac_cv_c_bigendian=unknown
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
-short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
-int
-main ()
-{
- _ascii (); _ebcdic ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
-  ac_cv_c_bigendian=yes
 fi
-if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
-  if test "$ac_cv_c_bigendian" = unknown; then
-    ac_cv_c_bigendian=no
+
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/''libltdl'/libltdl.la
+    LTDLINCL='-I${top_srcdir}/''libltdl'
   else
-    # finding both strings is unlikely to happen, but who knows?
-    ac_cv_c_bigendian=unknown
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    LTDLINCL=
   fi
-fi
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
 
 
+if test x"$enable_ltdl_install" = x"yes"; then
+  LTDL_SUBDIRS=libltdl
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
+  enable_shared=yes
+fi
 
-  /* Are we little or big endian?  From Harbison&Steele.  */
-  union
-  {
-    long int l;
-    char c[sizeof (long int)];
-  } u;
-  u.l = 1;
-  return u.c[sizeof (long int) - 1] == 1;
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_c_bigendian=no
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_bigendian=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+  enable_static=yes
 fi
 
 
+# Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
-echo "${ECHO_T}$ac_cv_c_bigendian" >&6; }
-case $ac_cv_c_bigendian in
-  yes)
 
-cat >>confdefs.h <<\_ACEOF
-#define WORDS_BIGENDIAN 1
-_ACEOF
- ;;
-  no)
-     ;;
-  *)
-    { { echo "$as_me:$LINENO: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&5
-echo "$as_me: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
-   { (exit 1); exit 1; }; } ;;
-esac
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
-# Extract the first word of "gmake", so it can be a program name with args.
-set dummy gmake; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_GMAKE+set}" = set; then
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+{ echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
+if test "${ac_cv_build+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test -n "$GMAKE"; then
-  ac_cv_prog_GMAKE="$GMAKE" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_GMAKE="yes"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
 
-  test -z "$ac_cv_prog_GMAKE" && ac_cv_prog_GMAKE="no"
-fi
-fi
-GMAKE=$ac_cv_prog_GMAKE
-if test -n "$GMAKE"; then
-  { echo "$as_me:$LINENO: result: $GMAKE" >&5
-echo "${ECHO_T}$GMAKE" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
 fi
+{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+echo "$as_me: error: invalid value of canonical build" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 
-if test $GMAKE = no; then
-  # Extract the first word of "make", so it can be a program name with args.
-set dummy make; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_MAKE+set}" = set; then
+{ echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
+if test "${ac_cv_host+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $MAKE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-  test -z "$ac_cv_path_MAKE" && ac_cv_path_MAKE="/usr/local/bin/make"
-  ;;
-esac
-fi
-MAKE=$ac_cv_path_MAKE
-if test -n "$MAKE"; then
-  { echo "$as_me:$LINENO: result: $MAKE" >&5
-echo "${ECHO_T}$MAKE" >&6; }
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
 fi
+{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+echo "$as_me: error: invalid value of canonical host" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
-else
-  # Extract the first word of "gmake", so it can be a program name with args.
-set dummy gmake; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_MAKE+set}" = set; then
+{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
+if test "${lt_cv_path_SED+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $MAKE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_MAKE="$MAKE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_MAKE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
 done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
 done
-IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_MAKE" && ac_cv_path_MAKE="/usr/local/gnu/bin/make"
-  ;;
-esac
-fi
-MAKE=$ac_cv_path_MAKE
-if test -n "$MAKE"; then
-  { echo "$as_me:$LINENO: result: $MAKE" >&5
-echo "${ECHO_T}$MAKE" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
 fi
 
+SED=$lt_cv_path_SED
+{ echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6; }
 
-fi
-makever=`$ac_cv_path_MAKE --version 2>&1 | grep "GNU Make"`
-if test -z "$makever"; then
-  { { echo "$as_me:$LINENO: error: GNU Make is not installed.  Please download and install it
-               from ftp://prep.ai.mit.edu/pub/gnu/make/ before continuing." >&5
-echo "$as_me: error: GNU Make is not installed.  Please download and install it
-               from ftp://prep.ai.mit.edu/pub/gnu/make/ before continuing." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-  { echo "$as_me:$LINENO: checking for lt_dlinit in -lltdl" >&5
-echo $ECHO_N "checking for lt_dlinit in -lltdl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ltdl_lt_dlinit+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lltdl  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char lt_dlinit ();
-int
-main ()
-{
-return lt_dlinit ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_ltdl_lt_dlinit=yes
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cv_lib_ltdl_lt_dlinit=no
+  with_gnu_ld=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
+else
+  { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ltdl_lt_dlinit" >&5
-echo "${ECHO_T}$ac_cv_lib_ltdl_lt_dlinit" >&6; }
-if test $ac_cv_lib_ltdl_lt_dlinit = yes; then
-  test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test x"$enable_ltdl_install" = xno; then
-     { echo "$as_me:$LINENO: WARNING: libltdl not installed, but installation disabled" >&5
-echo "$as_me: WARNING: libltdl not installed, but installation disabled" >&2;}
-   else
-     enable_ltdl_install=yes
-   fi
-
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
-
-  if test x"$enable_ltdl_install" = x"yes"; then
-    ac_configure_args="$ac_configure_args --enable-ltdl-install"
-    LIBLTDL='${top_builddir}/''libltdl'/libltdl.la
-    LTDLINCL='-I${top_srcdir}/''libltdl'
-  else
-    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
-    LIBLTDL="-lltdl"
-    LTDLINCL=
-  fi
-  # For backwards non-gettext consistent compatibility...
-  INCLTDL="$LTDLINCL"
-
-
-if test x"$enable_ltdl_install" = x"yes"; then
-  LTDL_SUBDIRS=libltdl
 fi
 
-
-# Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then
-  enableval=$enable_shared; p=${PACKAGE-default}
-    case $enableval in
-    yes) enable_shared=yes ;;
-    no) enable_shared=no ;;
-    *)
-      enable_shared=no
-      # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-      for pkg in $enableval; do
-       IFS="$lt_save_ifs"
-       if test "X$pkg" = "X$p"; then
-         enable_shared=yes
-       fi
-      done
-      IFS="$lt_save_ifs"
-      ;;
-    esac
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6; }
 else
-  enable_shared=yes
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
-
-
-# Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then
-  enableval=$enable_static; p=${PACKAGE-default}
-    case $enableval in
-    yes) enable_static=yes ;;
-    no) enable_static=no ;;
-    *)
-     enable_static=no
-      # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-      for pkg in $enableval; do
-       IFS="$lt_save_ifs"
-       if test "X$pkg" = "X$p"; then
-         enable_static=yes
-       fi
-      done
-      IFS="$lt_save_ifs"
-      ;;
-    esac
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  enable_static=yes
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
 fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
 
 
-# Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then
-  enableval=$enable_fast_install; p=${PACKAGE-default}
-    case $enableval in
-    yes) enable_fast_install=yes ;;
-    no) enable_fast_install=no ;;
-    *)
-      enable_fast_install=no
-      # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-      for pkg in $enableval; do
-       IFS="$lt_save_ifs"
-       if test "X$pkg" = "X$p"; then
-         enable_fast_install=yes
-       fi
-      done
-      IFS="$lt_save_ifs"
-      ;;
-    esac
-else
-  enable_fast_install=yes
-fi
-
-
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
-echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
-
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
-echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
-   { (exit 1); exit 1; }; }
-
-{ echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
-if test "${ac_cv_build+set}" = set; then
+{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
-  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
-   { (exit 1); exit 1; }; }
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-
+  lt_cv_ld_reload_flag='-r'
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
-echo "$as_me: error: invalid value of canonical build" >&2;}
-   { (exit 1); exit 1; }; };;
+{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
 esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
-if test "${ac_cv_host+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "x$host_alias" = x; then
-  ac_cv_host=$ac_cv_build
-else
-  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
-echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
-echo "$as_me: error: invalid value of canonical host" >&2;}
-   { (exit 1); exit 1; }; };;
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
 esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
-
-{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
-echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
-if test "${lt_cv_path_SED+set}" = set; then
+{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; }
+if test "${lt_cv_path_NM+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  # Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for lt_ac_prog in sed gsed; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
-        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       # Tru64's nm complains that /dev/null is an invalid object file
+       case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+       */dev/null* | *'Invalid file or object type'*)
+         lt_cv_path_NM="$tmp_nm -B"
+         break
+         ;;
+       *)
+         case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+         */dev/null*)
+           lt_cv_path_NM="$tmp_nm -p"
+           break
+           ;;
+         *)
+           lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+           continue # so that we can try to find one that supports BSD flags
+           ;;
+         esac
+         ;;
+       esac
       fi
     done
+    IFS="$lt_save_ifs"
   done
-done
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f $lt_ac_sed && continue
-  cat /dev/null > conftest.in
-  lt_ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
-  # Check for GNU sed and select it if it is found.
-  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
-    lt_cv_path_SED=$lt_ac_sed
-    break
-  fi
-  while true; do
-    cat conftest.in conftest.in >conftest.tmp
-    mv conftest.tmp conftest.in
-    cp conftest.in conftest.nl
-    echo >>conftest.nl
-    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
-    cmp -s conftest.out conftest.nl || break
-    # 10000 chars as input seems more than enough
-    test $lt_ac_count -gt 10 && break
-    lt_ac_count=`expr $lt_ac_count + 1`
-    if test $lt_ac_count -gt $lt_ac_max; then
-      lt_ac_max=$lt_ac_count
-      lt_cv_path_SED=$lt_ac_sed
-    fi
-  done
-done
-
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
 fi
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6; }
+NM="$lt_cv_path_NM"
 
-SED=$lt_cv_path_SED
-{ echo "$as_me:$LINENO: result: $SED" >&5
-echo "${ECHO_T}$SED" >&6; }
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then
-  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
 else
-  with_gnu_ld=no
+  { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6; }
 fi
 
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
-echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case $ac_prog in
-    # Accept absolute paths.
-    [\\/]* | ?:[\\/]*)
-      re_direlt='/[^/][^/]*/\.\./'
-      # Canonicalize the pathname of ld
-      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
+{ echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
+echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu | dragonfly*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
       ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
     ;;
   *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
     ;;
   esac
-elif test "$with_gnu_ld" = yes; then
-  { echo "$as_me:$LINENO: checking for GNU ld" >&5
-echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
-else
-  { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
-echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -z "$LD"; then
-  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-  for ac_dir in $PATH; do
-    IFS="$lt_save_ifs"
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some variants of GNU ld only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
-      *GNU* | *'with BFD'*)
-       test "$with_gnu_ld" != no && break
-       ;;
-      *)
-       test "$with_gnu_ld" != yes && break
-       ;;
-      esac
-    fi
-  done
-  IFS="$lt_save_ifs"
-else
-  lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
+  ;;
 
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
-  { echo "$as_me:$LINENO: result: $LD" >&5
-echo "${ECHO_T}$LD" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
-echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
-   { (exit 1); exit 1; }; }
-{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
-echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
-  lt_cv_prog_gnu_ld=yes
+interix3*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
   ;;
-*)
-  lt_cv_prog_gnu_ld=no
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
   ;;
-esac
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
-echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
 
+# This must be Linux ELF.
+linux*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
 
-{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
-echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  lt_cv_ld_reload_flag='-r'
-fi
-{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
-echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; }
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
-  darwin*)
-    if test "$GCC" = yes; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
-    else
-      reload_cmds='$LD$reload_flag -o $output$reload_objs'
-    fi
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
     ;;
+  esac
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
 esac
 
-{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
-echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; }
-if test "${lt_cv_path_NM+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$NM"; then
-  # Let the user override the test.
-  lt_cv_path_NM="$NM"
-else
-  lt_nm_to_check="${ac_tool_prefix}nm"
-  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
-    lt_nm_to_check="$lt_nm_to_check nm"
-  fi
-  for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS="$lt_save_ifs"
-      test -z "$ac_dir" && ac_dir=.
-      tmp_nm="$ac_dir/$lt_tmp_nm"
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
-       # Check to see if the nm accepts a BSD-compat flag.
-       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
-       #   nm: unknown option "B" ignored
-       # Tru64's nm complains that /dev/null is an invalid object file
-       case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
-       */dev/null* | *'Invalid file or object type'*)
-         lt_cv_path_NM="$tmp_nm -B"
-         break
-         ;;
-       *)
-         case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
-         */dev/null*)
-           lt_cv_path_NM="$tmp_nm -p"
-           break
-           ;;
-         *)
-           lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
-           continue # so that we can try to find one that supports BSD flags
-           ;;
-         esac
-         ;;
-       esac
-      fi
-    done
-    IFS="$lt_save_ifs"
-  done
-  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
-fi
 fi
-{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
-echo "${ECHO_T}$lt_cv_path_NM" >&6; }
-NM="$lt_cv_path_NM"
+{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
 
-{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
-echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
-  { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
-echo "${ECHO_T}no, using $LN_S" >&6; }
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval=$enable_libtool_lock;
 fi
 
-{ echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
-echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 5033 "configure"' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.o` in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-case $host_os in
-aix4* | aix5*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
+     cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
-beos*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
+int
+main ()
+{
 
-bsdi[45]*)
-  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
-  lt_cv_file_magic_cmd='/usr/bin/file -L'
-  lt_cv_file_magic_test_file=/shlib/libc.so
-  ;;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-cygwin*)
-  # func_win32_libid is a shell function defined in ltmain.sh
-  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
-  lt_cv_file_magic_cmd='func_win32_libid'
-  ;;
+       lt_cv_cc_needs_belf=no
+fi
 
-mingw* | pw32*)
-  # Base MSYS/MinGW do not provide the 'file' command needed by
-  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
-  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
-  lt_cv_file_magic_cmd='$OBJDUMP -f'
-  ;;
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-darwin* | rhapsody*)
-  lt_cv_deplibs_check_method=pass_all
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
   ;;
-
-freebsd* | kfreebsd*-gnu | dragonfly*)
-  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
-    case $host_cpu in
-    i*86 )
-      # Not sure whether the presence of OpenBSD here was a mistake.
-      # Let's accept both of them until this is cleared up.
-      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
-      lt_cv_file_magic_cmd=/usr/bin/file
-      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
       ;;
     esac
-  else
-    lt_cv_deplibs_check_method=pass_all
   fi
+  rm -rf conftest*
   ;;
 
-gnu*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 
-hpux10.20* | hpux11*)
-  lt_cv_file_magic_cmd=/usr/bin/file
-  case $host_cpu in
-  ia64*)
-    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
-    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
-    ;;
-  hppa*64*)
-    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
-    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
-    ;;
-  *)
-    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
-    lt_cv_file_magic_test_file=/usr/lib/libc.sl
-    ;;
-  esac
-  ;;
+esac
 
-interix3*)
-  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
-  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
-  ;;
+need_locks="$enable_libtool_lock"
 
-irix5* | irix6* | nonstopux*)
-  case $LD in
-  *-32|*"-32 ") libmagic=32-bit;;
-  *-n32|*"-n32 ") libmagic=N32;;
-  *-64|*"-64 ") libmagic=64-bit;;
-  *) libmagic=never-match;;
-  esac
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 
-# This must be Linux ELF.
-linux*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 
-netbsd*)
-  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
-    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
-  else
-    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
-  fi
-  ;;
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-newos6*)
-  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
-  lt_cv_file_magic_cmd=/usr/bin/file
-  lt_cv_file_magic_test_file=/usr/lib/libnls.so
-  ;;
+       ac_header_compiler=no
+fi
 
-nto-qnx*)
-  lt_cv_deplibs_check_method=unknown
-  ;;
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-openbsd*)
-  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
   else
-    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+    ac_cpp_err=
   fi
-  ;;
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-osf3* | osf4* | osf5*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
+  ac_header_preproc=no
+fi
 
-solaris*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
-sysv4 | sysv4.3*)
-  case $host_vendor in
-  motorola)
-    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
-    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
-    ;;
-  ncr)
-    lt_cv_deplibs_check_method=pass_all
-    ;;
-  sequent)
-    lt_cv_file_magic_cmd='/bin/file'
-    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
-    ;;
-  sni)
-    lt_cv_file_magic_cmd='/bin/file'
-    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
-    lt_cv_file_magic_test_file=/lib/libc.so
-    ;;
-  siemens)
-    lt_cv_deplibs_check_method=pass_all
-    ;;
-  pc)
-    lt_cv_deplibs_check_method=pass_all
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
     ;;
-  esac
-  ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
 
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
+    ;;
 esac
-
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
-echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; }
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
 
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
+fi
 
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+done
 
-# Allow CC to be a program name with arguments.
-compiler=$CC
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then
-  enableval=$enable_libtool_lock;
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
-  # Find out which ABI we are using.
-  echo 'int i;' > conftest.$ac_ext
-  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-    case `/usr/bin/file conftest.$ac_objext` in
-    *ELF-32*)
-      HPUX_IA64_MODE="32"
-      ;;
-    *ELF-64*)
-      HPUX_IA64_MODE="64"
-      ;;
-    esac
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
   fi
-  rm -rf conftest*
-  ;;
-*-*-irix6*)
-  # Find out which ABI we are using.
-  echo '#line 5898 "configure"' > conftest.$ac_ext
-  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-   if test "$lt_cv_prog_gnu_ld" = yes; then
-    case `/usr/bin/file conftest.$ac_objext` in
-    *32-bit*)
-      LD="${LD-ld} -melf32bsmip"
-      ;;
-    *N32*)
-      LD="${LD-ld} -melf32bmipn32"
-      ;;
-    *64-bit*)
-      LD="${LD-ld} -melf64bmip"
-      ;;
-    esac
-   else
-    case `/usr/bin/file conftest.$ac_objext` in
-    *32-bit*)
-      LD="${LD-ld} -32"
-      ;;
-    *N32*)
-      LD="${LD-ld} -n32"
-      ;;
-    *64-bit*)
-      LD="${LD-ld} -64"
-      ;;
-    esac
-   fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
   fi
-  rm -rf conftest*
-  ;;
+fi
 
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
-  # Find out which ABI we are using.
-  echo 'int i;' > conftest.$ac_ext
-  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+  fi
+fi
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-    case `/usr/bin/file conftest.o` in
-    *32-bit*)
-      case $host in
-        x86_64-*linux*)
-          LD="${LD-ld} -m elf_i386"
-          ;;
-        ppc64-*linux*|powerpc64-*linux*)
-          LD="${LD-ld} -m elf32ppclinux"
-          ;;
-        s390x-*linux*)
-          LD="${LD-ld} -m elf_s390"
-          ;;
-        sparc64-*linux*)
-          LD="${LD-ld} -m elf32_sparc"
-          ;;
-      esac
-      ;;
-    *64-bit*)
-      case $host in
-        x86_64-*linux*)
-          LD="${LD-ld} -m elf_x86_64"
-          ;;
-        ppc*-*linux*|powerpc*-*linux*)
-          LD="${LD-ld} -m elf64ppc"
-          ;;
-        s390*-*linux*)
-          LD="${LD-ld} -m elf64_s390"
-          ;;
-        sparc*-*linux*)
-          LD="${LD-ld} -m elf64_sparc"
-          ;;
-      esac
-      ;;
-    esac
-  fi
-  rm -rf conftest*
-  ;;
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
 
-*-*-sco3.2v5*)
-  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS="$CFLAGS"
-  CFLAGS="$CFLAGS -belf"
-  { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
-echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-     cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -6001,26 +5553,29 @@ cat >>conftest.$ac_ext <<_ACEOF
 int
 main ()
 {
+#ifndef __GNUC__
+       choke me
+#endif
 
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -6030,7 +5585,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
+        { ac_try='test -s conftest.$ac_objext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -6040,81 +5595,101 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  lt_cv_cc_needs_belf=yes
+  ac_compiler_gnu=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       lt_cv_cc_needs_belf=no
+       ac_compiler_gnu=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-     ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
-echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; }
-  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
-    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS="$SAVE_CFLAGS"
-  fi
-  ;;
-sparc*-*solaris*)
-  # Find out which ABI we are using.
-  echo 'int i;' > conftest.$ac_ext
-  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-    case `/usr/bin/file conftest.o` in
-    *64-bit*)
-      case $lt_cv_prog_gnu_ld in
-      yes*) LD="${LD-ld} -m elf64_sparc" ;;
-      *)    LD="${LD-ld} -64" ;;
-      esac
-      ;;
-    esac
-  fi
-  rm -rf conftest*
-  ;;
+{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
+int
+main ()
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
 esac
-
-need_locks="$enable_libtool_lock"
-
-
-
-for ac_header in dlfcn.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       CXXFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -6130,7 +5705,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -6150,109 +5725,101 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_header_compiler=yes
+  :
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+       ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+        CXXFLAGS="-g"
+        cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <$ac_header>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
 
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 
-done
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
 
@@ -7781,11 +7348,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7784: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7351: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7788: \$? = $ac_status" >&5
+   echo "$as_me:7355: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8049,11 +7616,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8052: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7619: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8056: \$? = $ac_status" >&5
+   echo "$as_me:7623: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8153,11 +7720,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8156: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7723: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8160: \$? = $ac_status" >&5
+   echo "$as_me:7727: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -8667,7 +8234,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -8742,7 +8309,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -10019,7 +9586,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_dl_dlopen=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -10130,7 +9697,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_func_shl_load=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
@@ -10209,7 +9776,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_dld_shl_load=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -10310,7 +9877,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_func_dlopen=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 { echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
@@ -10389,7 +9956,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_dl_dlopen=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -10469,7 +10036,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_svld_dlopen=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -10549,7 +10116,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_dld_dld_link=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -10605,7 +10172,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10608 "configure"
+#line 10175 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10705,7 +10272,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10708 "configure"
+#line 10275 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11826,7 +11393,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -11902,7 +11469,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -13077,11 +12644,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13080: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12647: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13084: \$? = $ac_status" >&5
+   echo "$as_me:12651: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -13181,11 +12748,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13184: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12751: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13188: \$? = $ac_status" >&5
+   echo "$as_me:12755: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14751,11 +14318,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14754: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14321: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14758: \$? = $ac_status" >&5
+   echo "$as_me:14325: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14855,11 +14422,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14858: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14425: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14862: \$? = $ac_status" >&5
+   echo "$as_me:14429: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15359,7 +14926,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -15424,7 +14991,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -17089,11 +16656,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17092: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16659: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17096: \$? = $ac_status" >&5
+   echo "$as_me:16663: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -17357,11 +16924,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17360: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16927: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17364: \$? = $ac_status" >&5
+   echo "$as_me:16931: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -17461,11 +17028,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17464: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17031: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:17468: \$? = $ac_status" >&5
+   echo "$as_me:17035: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17975,7 +17542,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -18050,7 +17617,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
@@ -20354,9 +19921,8 @@ if test "${with_ascend_binary+set}" = set; then
 fi
 
 if test "X$ASCEND_BINARY" = "Xyes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define ASCEND_BINARY
+  cat >>confdefs.h <<\_ACEOF
+#define ASCEND_BINARY 1
 _ACEOF
 
 fi
@@ -20383,431 +19949,172 @@ if test "${with_snmp+set}" = set; then
     yes)
         ;;
     *)
-       WITH_SNMP=no
-  esac
-
-fi
-
-
-STATIC_MODULES=
-
-# Check whether --with-static_modules was given.
-if test "${with_static_modules+set}" = set; then
-  withval=$with_static_modules;
-  for i in $withval; do
-    STATIC_MODULES="$STATIC_MODULES -dlpreopen ../modules/rlm_$i/rlm_$i.la"
-  done
-
-fi
-
-
-MODULES=
-
-# Check whether --with-modules was given.
-if test "${with_modules+set}" = set; then
-  withval=$with_modules;
- for i in $withval; do
-   MODULES="$MODULES $i"
- done
-
-fi
-
-
-# Check whether --enable-developer was given.
-if test "${enable_developer+set}" = set; then
-  enableval=$enable_developer;  case "$enableval" in
-    no)
-       developer=no
-       ;;
-    *)
-       developer=yes
-  esac
-
-fi
-
-
-if test "x$developer" != "xno" -a -d $srcdir/CVS; then
-    developer="yes"
-fi
-
-EXPERIMENTAL=
-
-# Check whether --with-experimental-modules was given.
-if test "${with_experimental_modules+set}" = set; then
-  withval=$with_experimental_modules;  case "$withval" in
-    yes)
-       EXPERIMENTAL=yes
-       ;;
-    *)
-  esac
-
-fi
-
-
-OPENSSL_INCLUDE_DIR=
-
-# Check whether --with-openssl-includes was given.
-if test "${with_openssl_includes+set}" = set; then
-  withval=$with_openssl_includes;  case "$withval" in
-    *) OPENSSL_INCLUDE_DIR="$withval"
-       ;;
-  esac
-
-fi
-
-
-OPENSSL_LIB_DIR=
-
-# Check whether --with-openssl-libraries was given.
-if test "${with_openssl_libraries+set}" = set; then
-  withval=$with_openssl_libraries;  case "$withval" in
-    *) OPENSSL_LIB_DIR="$withval"
-       ;;
-  esac
-
-fi
-
-
-
-
-# Check whether --with-rlm-FOO-lib-dir was given.
-if test "${with_rlm_FOO_lib_dir+set}" = set; then
-  withval=$with_rlm_FOO_lib_dir;  case "$withval" in
-    *)
-       ;;
-  esac
-
-fi
-
-
-
-# Check whether --with-rlm-FOO-include-dir was given.
-if test "${with_rlm_FOO_include_dir+set}" = set; then
-  withval=$with_rlm_FOO_include_dir;  case "$withval" in
-    *)
-       ;;
+       WITH_SNMP=no
   esac
 
 fi
 
 
+rad_enable_largefiles=no
 
-WITH_UDPFROMTO=yes
-
-# Check whether --with-udpfromto was given.
-if test "${with_udpfromto+set}" = set; then
-  withval=$with_udpfromto;  case "$withval" in
+# Check whether --with-large-files was given.
+if test "${with_large_files+set}" = set; then
+  withval=$with_large_files;  case "$withval" in
     yes)
-       WITH_UDPFROMTO=yes
-        ;;
+        rad_enable_largefiles=yes
+       ;;
     *)
-       WITH_UDPFROMTO=no
+       ;;
   esac
 
 fi
 
 
-if test "x$WITH_UDPFROMTO" = "xyes"; then
 
-cat >>confdefs.h <<\_ACEOF
-#define WITH_UDPFROMTO
-_ACEOF
+STATIC_MODULES=
 
-fi
+# Check whether --with-static_modules was given.
+if test "${with_static_modules+set}" = set; then
+  withval=$with_static_modules;
+  for i in $withval; do
+    STATIC_MODULES="$STATIC_MODULES -dlpreopen ../modules/rlm_$i/rlm_$i.la"
+  done
 
+fi
 
-CHECKRAD=checkrad.pl
-# Extract the first word of "perl", so it can be a program name with args.
-set dummy perl; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_PERL+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $PERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="/usr/local/bin/perl"
-  ;;
-esac
-fi
-PERL=$ac_cv_path_PERL
-if test -n "$PERL"; then
-  { echo "$as_me:$LINENO: result: $PERL" >&5
-echo "${ECHO_T}$PERL" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
+MODULES=
 
+# Check whether --with-modules was given.
+if test "${with_modules+set}" = set; then
+  withval=$with_modules;
+ for i in $withval; do
+   MODULES="$MODULES $i"
+ done
 
-if test "x$ac_cv_path_PERL" = "x"; then
-  { echo "$as_me:$LINENO: WARNING: perl not found - Simultaneous-Use and checkrad.pl may not work" >&5
-echo "$as_me: WARNING: perl not found - Simultaneous-Use and checkrad.pl may not work" >&2;}
 fi
-# Extract the first word of "snmpget", so it can be a program name with args.
-set dummy snmpget; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_SNMPGET+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $SNMPGET in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_SNMPGET="$SNMPGET" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_SNMPGET="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-  ;;
-esac
-fi
-SNMPGET=$ac_cv_path_SNMPGET
-if test -n "$SNMPGET"; then
-  { echo "$as_me:$LINENO: result: $SNMPGET" >&5
-echo "${ECHO_T}$SNMPGET" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
+# Check whether --enable-developer was given.
+if test "${enable_developer+set}" = set; then
+  enableval=$enable_developer;  case "$enableval" in
+    no)
+       developer=no
+       ;;
+    *)
+       developer=yes
+  esac
 
-if test "x$ac_cv_path_SNMPGET" = "x"; then
-  { echo "$as_me:$LINENO: WARNING: snmpget not found - Simultaneous-Use and checkrad.pl may not work" >&5
-echo "$as_me: WARNING: snmpget not found - Simultaneous-Use and checkrad.pl may not work" >&2;}
 fi
 
-# Extract the first word of "snmpwalk", so it can be a program name with args.
-set dummy snmpwalk; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_SNMPWALK+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $SNMPWALK in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_SNMPWALK="$SNMPWALK" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_SNMPWALK="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-  ;;
-esac
-fi
-SNMPWALK=$ac_cv_path_SNMPWALK
-if test -n "$SNMPWALK"; then
-  { echo "$as_me:$LINENO: result: $SNMPWALK" >&5
-echo "${ECHO_T}$SNMPWALK" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+if test "x$developer" != "xno" -a -d $srcdir/CVS; then
+    developer="yes"
 fi
 
+EXPERIMENTAL=
 
-if test "x$ac_cv_path_SNMPWALK" = "x"; then
-  { echo "$as_me:$LINENO: WARNING: snmpwalk not found - Simultaneous-Use and checkrad.pl may not work" >&5
-echo "$as_me: WARNING: snmpwalk not found - Simultaneous-Use and checkrad.pl may not work" >&2;}
-fi
-
-# Extract the first word of "rusers", so it can be a program name with args.
-set dummy rusers; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_RUSERS+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $RUSERS in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_RUSERS="$RUSERS" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_RUSERS="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
+# Check whether --with-experimental-modules was given.
+if test "${with_experimental_modules+set}" = set; then
+  withval=$with_experimental_modules;  case "$withval" in
+    yes)
+       EXPERIMENTAL=yes
+       ;;
+    *)
+  esac
 
-  test -z "$ac_cv_path_RUSERS" && ac_cv_path_RUSERS="/usr/bin/rusers"
-  ;;
-esac
-fi
-RUSERS=$ac_cv_path_RUSERS
-if test -n "$RUSERS"; then
-  { echo "$as_me:$LINENO: result: $RUSERS" >&5
-echo "${ECHO_T}$RUSERS" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
 fi
 
 
+OPENSSL_INCLUDE_DIR=
 
-missing_dir=`cd $ac_aux_dir && pwd`
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Check whether --with-openssl-includes was given.
+if test "${with_openssl_includes+set}" = set; then
+  withval=$with_openssl_includes;  case "$withval" in
+    *) OPENSSL_INCLUDE_DIR="$withval"
+       ;;
+  esac
 
-test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
-  am_missing_run="$MISSING --run "
-else
-  am_missing_run=
-  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
-echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
 fi
 
 
-ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal"}
+OPENSSL_LIB_DIR=
 
+# Check whether --with-openssl-libraries was given.
+if test "${with_openssl_libraries+set}" = set; then
+  withval=$with_openssl_libraries;  case "$withval" in
+    *) OPENSSL_LIB_DIR="$withval"
+       ;;
+  esac
 
-AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+fi
 
 
-AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
 
 
-# Extract the first word of "locate", so it can be a program name with args.
-set dummy locate; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_LOCATE+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $LOCATE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_LOCATE="$LOCATE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_LOCATE="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
+# Check whether --with-rlm-FOO-lib-dir was given.
+if test "${with_rlm_FOO_lib_dir+set}" = set; then
+  withval=$with_rlm_FOO_lib_dir;  case "$withval" in
+    *)
+       ;;
+  esac
 
-  ;;
-esac
 fi
-LOCATE=$ac_cv_path_LOCATE
-if test -n "$LOCATE"; then
-  { echo "$as_me:$LINENO: result: $LOCATE" >&5
-echo "${ECHO_T}$LOCATE" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+
+
+
+# Check whether --with-rlm-FOO-include-dir was given.
+if test "${with_rlm_FOO_include_dir+set}" = set; then
+  withval=$with_rlm_FOO_include_dir;  case "$withval" in
+    *)
+       ;;
+  esac
+
 fi
 
 
-# Extract the first word of "dirname", so it can be a program name with args.
-set dummy dirname; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_DIRNAME+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  case $DIRNAME in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_DIRNAME="$DIRNAME" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_DIRNAME="$as_dir/$ac_word$ac_exec_ext"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-  ;;
-esac
+WITH_UDPFROMTO=no
+
+# Check whether --with-udpfromto was given.
+if test "${with_udpfromto+set}" = set; then
+  withval=$with_udpfromto;  case "$withval" in
+    yes)
+       WITH_UDPFROMTO=yes
+        ;;
+    *)
+       WITH_UDPFROMTO=no
+  esac
+
 fi
-DIRNAME=$ac_cv_path_DIRNAME
-if test -n "$DIRNAME"; then
-  { echo "$as_me:$LINENO: result: $DIRNAME" >&5
-echo "${ECHO_T}$DIRNAME" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+
+
+if test "x$WITH_UDPFROMTO" = "xyes"; then
+       cat >>confdefs.h <<\_ACEOF
+#define WITH_UDPFROMTO 1
+_ACEOF
+
 fi
 
 
-# Extract the first word of "grep", so it can be a program name with args.
-set dummy grep; ac_word=$2
+# Check whether --with-edir was given.
+if test "${with_edir+set}" = set; then
+  withval=$with_edir;
+fi
+
+
+
+CHECKRAD=checkrad.pl
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
 { echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
+if test "${ac_cv_path_PERL+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  case $GREP in
+  case $PERL in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GREP="$GREP" # Let the user override the test with a path.
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -20817,7 +20124,7 @@ do
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 IFS=$as_save_IFS
 
+  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="/usr/local/bin/perl"
   ;;
 esac
 fi
-GREP=$ac_cv_path_GREP
-if test -n "$GREP"; then
-  { echo "$as_me:$LINENO: result: $GREP" >&5
-echo "${ECHO_T}$GREP" >&6; }
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+  { echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6; }
 else
   { echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6; }
 fi
 
 
-
-
-old_CFLAGS=$CFLAGS
-if test "x$WITH_THREADS" = "xyes"; then
-  if test $ac_cv_prog_suncc = "yes"; then
-    CFLAGS="$CFLAGS -mt"
-  fi
-
-
-for ac_header in pthread.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
+if test "x$ac_cv_path_PERL" = "x"; then
+  { echo "$as_me:$LINENO: WARNING: perl not found - Simultaneous-Use and checkrad.pl may not work" >&5
+echo "$as_me: WARNING: perl not found - Simultaneous-Use and checkrad.pl may not work" >&2;}
 fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+# Extract the first word of "snmpget", so it can be a program name with args.
+set dummy snmpget; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_SNMPGET+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+  case $SNMPGET in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_SNMPGET="$SNMPGET" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_SNMPGET="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
+  ;;
+esac
 fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
+SNMPGET=$ac_cv_path_SNMPGET
+if test -n "$SNMPGET"; then
+  { echo "$as_me:$LINENO: result: $SNMPGET" >&5
+echo "${ECHO_T}$SNMPGET" >&6; }
 else
-   WITH_THREADS="no"
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-done
 
+if test "x$ac_cv_path_SNMPGET" = "x"; then
+  { echo "$as_me:$LINENO: WARNING: snmpget not found - Simultaneous-Use and checkrad.pl may not work" >&5
+echo "$as_me: WARNING: snmpget not found - Simultaneous-Use and checkrad.pl may not work" >&2;}
+fi
 
-  { echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
-echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6; }
-if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
+# Extract the first word of "snmpwalk", so it can be a program name with args.
+set dummy snmpwalk; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_SNMPWALK+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpthread  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+  case $SNMPWALK in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_SNMPWALK="$SNMPWALK" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_SNMPWALK="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_create ();
-int
-main ()
-{
-return pthread_create ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+  ;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_pthread_pthread_create=yes
+fi
+SNMPWALK=$ac_cv_path_SNMPWALK
+if test -n "$SNMPWALK"; then
+  { echo "$as_me:$LINENO: result: $SNMPWALK" >&5
+echo "${ECHO_T}$SNMPWALK" >&6; }
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cv_lib_pthread_pthread_create=no
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+
+if test "x$ac_cv_path_SNMPWALK" = "x"; then
+  { echo "$as_me:$LINENO: WARNING: snmpwalk not found - Simultaneous-Use and checkrad.pl may not work" >&5
+echo "$as_me: WARNING: snmpwalk not found - Simultaneous-Use and checkrad.pl may not work" >&2;}
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5
-echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6; }
-if test $ac_cv_lib_pthread_pthread_create = yes; then
-   CFLAGS="$CFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS"
-                  LIBS="$LIBS -lpthread"
-else
-  { echo "$as_me:$LINENO: checking for pthread_create in -lc_r" >&5
-echo $ECHO_N "checking for pthread_create in -lc_r... $ECHO_C" >&6; }
-if test "${ac_cv_lib_c_r_pthread_create+set}" = set; then
+
+# Extract the first word of "rusers", so it can be a program name with args.
+set dummy rusers; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_RUSERS+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lc_r  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+  case $RUSERS in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_RUSERS="$RUSERS" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_RUSERS="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_create ();
-int
-main ()
-{
-return pthread_create ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+  test -z "$ac_cv_path_RUSERS" && ac_cv_path_RUSERS="/usr/bin/rusers"
+  ;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_c_r_pthread_create=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cv_lib_c_r_pthread_create=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_create" >&5
-echo "${ECHO_T}$ac_cv_lib_c_r_pthread_create" >&6; }
-if test $ac_cv_lib_c_r_pthread_create = yes; then
-   CFLAGS="$CFLAGS -pthread -D_THREAD_SAFE"
+RUSERS=$ac_cv_path_RUSERS
+if test -n "$RUSERS"; then
+  { echo "$as_me:$LINENO: result: $RUSERS" >&5
+echo "${ECHO_T}$RUSERS" >&6; }
 else
-   WITH_THREADS="no"
-
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
 
-fi
 
+missing_dir=`cd $ac_aux_dir && pwd`
+{ echo "$as_me:$LINENO: checking for working aclocal" >&5
+echo $ECHO_N "checking for working aclocal... $ECHO_C" >&6; }
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   { echo "$as_me:$LINENO: result: found" >&5
+echo "${ECHO_T}found" >&6; }
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   { echo "$as_me:$LINENO: result: missing" >&5
+echo "${ECHO_T}missing" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking for working autoconf" >&5
+echo $ECHO_N "checking for working autoconf... $ECHO_C" >&6; }
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   { echo "$as_me:$LINENO: result: found" >&5
+echo "${ECHO_T}found" >&6; }
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   { echo "$as_me:$LINENO: result: missing" >&5
+echo "${ECHO_T}missing" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking for working autoheader" >&5
+echo $ECHO_N "checking for working autoheader... $ECHO_C" >&6; }
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   { echo "$as_me:$LINENO: result: found" >&5
+echo "${ECHO_T}found" >&6; }
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   { echo "$as_me:$LINENO: result: missing" >&5
+echo "${ECHO_T}missing" >&6; }
 fi
 
-if test "x$WITH_THREADS" != "xyes"; then
-  CFLAGS=$old_CFLAGS
-  ac_cv_header_pthread_h="no"
-  WITH_THREADS=no
-else
 
-  { echo "$as_me:$LINENO: checking for library containing sem_init" >&5
-echo $ECHO_N "checking for library containing sem_init... $ECHO_C" >&6; }
-if test "${ac_cv_search_sem_init+set}" = set; then
+# Extract the first word of "locate", so it can be a program name with args.
+set dummy locate; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_LOCATE+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_func_search_save_LIBS=$LIBS
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char sem_init ();
-int
-main ()
-{
-return sem_init ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' pthread sem posix4 rt semaphore; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  case $LOCATE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_LOCATE="$LOCATE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_LOCATE="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
   fi
-  rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_search_sem_init=$ac_res
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
+done
+done
+IFS=$as_save_IFS
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext
-  if test "${ac_cv_search_sem_init+set}" = set; then
-  break
+  ;;
+esac
 fi
-done
-if test "${ac_cv_search_sem_init+set}" = set; then
-  :
+LOCATE=$ac_cv_path_LOCATE
+if test -n "$LOCATE"; then
+  { echo "$as_me:$LINENO: result: $LOCATE" >&5
+echo "${ECHO_T}$LOCATE" >&6; }
 else
-  ac_cv_search_sem_init=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_search_sem_init" >&5
-echo "${ECHO_T}$ac_cv_search_sem_init" >&6; }
-ac_res=$ac_cv_search_sem_init
-if test "$ac_res" != no; then
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
+
+# Extract the first word of "dirname", so it can be a program name with args.
+set dummy dirname; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_DIRNAME+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  { { echo "$as_me:$LINENO: error: -lsem not found.  You may want to download it from ftp://ftp.to.gd-es.com/pub/BSDI/libsem.tar.bz2 or ftp://ftp.freeradius.org/pub/radius/contrib/libsem.tar.gz" >&5
-echo "$as_me: error: -lsem not found.  You may want to download it from ftp://ftp.to.gd-es.com/pub/BSDI/libsem.tar.bz2 or ftp://ftp.freeradius.org/pub/radius/contrib/libsem.tar.gz" >&2;}
-   { (exit 1); exit 1; }; }
+  case $DIRNAME in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DIRNAME="$DIRNAME" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_DIRNAME="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
+  ;;
+esac
 fi
-
+DIRNAME=$ac_cv_path_DIRNAME
+if test -n "$DIRNAME"; then
+  { echo "$as_me:$LINENO: result: $DIRNAME" >&5
+echo "${ECHO_T}$DIRNAME" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
 
-{ echo "$as_me:$LINENO: checking for getsockname in -lsocket" >&5
-echo $ECHO_N "checking for getsockname in -lsocket... $ECHO_C" >&6; }
-if test "${ac_cv_lib_socket_getsockname+set}" = set; then
+# Extract the first word of "grep", so it can be a program name with args.
+set dummy grep; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char getsockname ();
-int
-main ()
-{
-return getsockname ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_socket_getsockname=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  case $GREP in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GREP="$GREP" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-       ac_cv_lib_socket_getsockname=no
+  ;;
+esac
 fi
-
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+GREP=$ac_cv_path_GREP
+if test -n "$GREP"; then
+  { echo "$as_me:$LINENO: result: $GREP" >&5
+echo "${ECHO_T}$GREP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_getsockname" >&5
-echo "${ECHO_T}$ac_cv_lib_socket_getsockname" >&6; }
-if test $ac_cv_lib_socket_getsockname = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSOCKET 1
-_ACEOF
 
-  LIBS="-lsocket $LIBS"
 
-fi
 
 
+old_CFLAGS=$CFLAGS
+if test "x$WITH_THREADS" = "xyes"; then
+  if test $ac_cv_prog_suncc = "yes"; then
+    CFLAGS="$CFLAGS -mt"
+  fi
 
-{ echo "$as_me:$LINENO: checking for inet_aton in -lresolv" >&5
-echo $ECHO_N "checking for inet_aton in -lresolv... $ECHO_C" >&6; }
-if test "${ac_cv_lib_resolv_inet_aton+set}" = set; then
+
+for ac_header in pthread.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lresolv  $LIBS"
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char inet_aton ();
-int
-main ()
-{
-return inet_aton ();
-  ;
-  return 0;
-}
+$ac_includes_default
+#include <$ac_header>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -21437,7 +20507,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
+        { ac_try='test -s conftest.$ac_objext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -21447,130 +20517,120 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_resolv_inet_aton=yes
+  ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_resolv_inet_aton=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_inet_aton" >&5
-echo "${ECHO_T}$ac_cv_lib_resolv_inet_aton" >&6; }
-if test $ac_cv_lib_resolv_inet_aton = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBRESOLV 1
-_ACEOF
-
-  LIBS="-lresolv $LIBS"
-
+       ac_header_compiler=no
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-
-{ echo "$as_me:$LINENO: checking for inet_ntoa in -lnsl" >&5
-echo $ECHO_N "checking for inet_ntoa in -lnsl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_nsl_inet_ntoa+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnsl  $LIBS"
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char inet_ntoa ();
-int
-main ()
-{
-return inet_ntoa ();
-  ;
-  return 0;
-}
+#include <$ac_header>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_nsl_inet_ntoa=yes
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_nsl_inet_ntoa=no
+  ac_header_preproc=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_inet_ntoa" >&5
-echo "${ECHO_T}$ac_cv_lib_nsl_inet_ntoa" >&6; }
-if test $ac_cv_lib_nsl_inet_ntoa = yes; then
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBNSL 1
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
-  LIBS="-lnsl $LIBS"
-
+else
+   WITH_THREADS="no"
 fi
 
+done
 
-OPENSSL_LIBS=
-old_LIBS=$LIBS
-if test "x$OPENSSL_LIB_DIR" != "x"; then
-    LIBS="-L$OPENSSL_LIB_DIR $LIBS"
-fi
-{ echo "$as_me:$LINENO: checking for DH_new in -lcrypto" >&5
-echo $ECHO_N "checking for DH_new in -lcrypto... $ECHO_C" >&6; }
-if test "${ac_cv_lib_crypto_DH_new+set}" = set; then
+
+  { echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
+echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6; }
+if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcrypto  $LIBS"
+LIBS="-lpthread  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -21584,11 +20644,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char DH_new ();
+char pthread_create ();
 int
 main ()
 {
-return DH_new ();
+return pthread_create ();
   ;
   return 0;
 }
@@ -21627,34 +20687,31 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_crypto_DH_new=yes
+  ac_cv_lib_pthread_pthread_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_crypto_DH_new=no
+       ac_cv_lib_pthread_pthread_create=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_DH_new" >&5
-echo "${ECHO_T}$ac_cv_lib_crypto_DH_new" >&6; }
-if test $ac_cv_lib_crypto_DH_new = yes; then
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LIBCRYPTO 1
-_ACEOF
-
-       { echo "$as_me:$LINENO: checking for SSL_new in -lssl" >&5
-echo $ECHO_N "checking for SSL_new in -lssl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ssl_SSL_new+set}" = set; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6; }
+if test $ac_cv_lib_pthread_pthread_create = yes; then
+   CFLAGS="$CFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS"
+                  LIBS="$LIBS -lpthread"
+else
+  { echo "$as_me:$LINENO: checking for pthread_create in -lc_r" >&5
+echo $ECHO_N "checking for pthread_create in -lc_r... $ECHO_C" >&6; }
+if test "${ac_cv_lib_c_r_pthread_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl  $LIBS"
+LIBS="-lc_r  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -21668,11 +20725,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char SSL_new ();
+char pthread_create ();
 int
 main ()
 {
-return SSL_new ();
+return pthread_create ();
   ;
   return 0;
 }
@@ -21711,47 +20768,44 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_ssl_SSL_new=yes
+  ac_cv_lib_c_r_pthread_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_ssl_SSL_new=no
+       ac_cv_lib_c_r_pthread_create=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_new" >&5
-echo "${ECHO_T}$ac_cv_lib_ssl_SSL_new" >&6; }
-if test $ac_cv_lib_ssl_SSL_new = yes; then
-
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LIBSSL 1
-_ACEOF
-
-               if test "x$OPENSSL_LIB_DIR" != "x"; then
-                   OPENSSL_LIBS="-L$OPENSSL_LIB_DIR"
-               fi
-               OPENSSL_LIBS="$OPENSSL_LIBS -lcrypto -lssl -lcrypto"
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_c_r_pthread_create" >&6; }
+if test $ac_cv_lib_c_r_pthread_create = yes; then
+   CFLAGS="$CFLAGS -pthread -D_THREAD_SAFE"
+else
+   WITH_THREADS="no"
 
 fi
 
 
 fi
 
-LIBS=$old_LIBS
+fi
 
+if test "x$WITH_THREADS" != "xyes"; then
+  CFLAGS=$old_CFLAGS
+  ac_cv_header_pthread_h="no"
+  WITH_THREADS=no
+else
 
-{ echo "$as_me:$LINENO: checking for htonl in -lws2_32" >&5
-echo $ECHO_N "checking for htonl in -lws2_32... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ws2_32_htonl+set}" = set; then
+  { echo "$as_me:$LINENO: checking for library containing sem_init" >&5
+echo $ECHO_N "checking for library containing sem_init... $ECHO_C" >&6; }
+if test "${ac_cv_search_sem_init+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lws2_32  $LIBS"
+  ac_func_search_save_LIBS=$LIBS
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -21765,16 +20819,23 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char htonl ();
+char sem_init ();
 int
 main ()
 {
-return htonl ();
+return sem_init ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
+for ac_lib in '' pthread sem posix4 rt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -21808,38 +20869,51 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_ws2_32_htonl=yes
+  ac_cv_search_sem_init=$ac_res
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_ws2_32_htonl=no
+
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext
+  if test "${ac_cv_search_sem_init+set}" = set; then
+  break
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ws2_32_htonl" >&5
-echo "${ECHO_T}$ac_cv_lib_ws2_32_htonl" >&6; }
-if test $ac_cv_lib_ws2_32_htonl = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBWS2_32 1
-_ACEOF
+done
+if test "${ac_cv_search_sem_init+set}" = set; then
+  :
+else
+  ac_cv_search_sem_init=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_search_sem_init" >&5
+echo "${ECHO_T}$ac_cv_search_sem_init" >&6; }
+ac_res=$ac_cv_search_sem_init
+if test "$ac_res" != no; then
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: -lsem not found.  You may want to download it from ftp://ftp.to.gd-es.com/pub/BSDI/libsem.tar.bz2 or ftp://ftp.freeradius.org/pub/radius/contrib/libsem.tar.gz" >&5
+echo "$as_me: error: -lsem not found.  You may want to download it from ftp://ftp.to.gd-es.com/pub/BSDI/libsem.tar.bz2 or ftp://ftp.freeradius.org/pub/radius/contrib/libsem.tar.gz" >&2;}
+   { (exit 1); exit 1; }; }
 
-  LIBS="-lws2_32 $LIBS"
+fi
 
 fi
 
 
-PCAP_LIBS=
-{ echo "$as_me:$LINENO: checking for pcap_open_live in -lpcap" >&5
-echo $ECHO_N "checking for pcap_open_live in -lpcap... $ECHO_C" >&6; }
-if test "${ac_cv_lib_pcap_pcap_open_live+set}" = set; then
+{ echo "$as_me:$LINENO: checking for getsockname in -lsocket" >&5
+echo $ECHO_N "checking for getsockname in -lsocket... $ECHO_C" >&6; }
+if test "${ac_cv_lib_socket_getsockname+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpcap  $LIBS"
+LIBS="-lsocket  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -21853,11 +20927,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char pcap_open_live ();
+char getsockname ();
 int
 main ()
 {
-return pcap_open_live ();
+return getsockname ();
   ;
   return 0;
 }
@@ -21896,83 +20970,68 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_lib_pcap_pcap_open_live=yes
+  ac_cv_lib_socket_getsockname=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_pcap_pcap_open_live=no
+       ac_cv_lib_socket_getsockname=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_pcap_pcap_open_live" >&5
-echo "${ECHO_T}$ac_cv_lib_pcap_pcap_open_live" >&6; }
-if test $ac_cv_lib_pcap_pcap_open_live = yes; then
-   PCAP_LIBS="-lpcap"
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LIBPCAP 1
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_getsockname" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_getsockname" >&6; }
+if test $ac_cv_lib_socket_getsockname = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
 _ACEOF
 
+  LIBS="-lsocket $LIBS"
 
-else
-   { echo "$as_me:$LINENO: WARNING: pcap library not found, silently disabling the RADIUS sniffer." >&5
-echo "$as_me: WARNING: pcap library not found, silently disabling the RADIUS sniffer." >&2;}
 fi
 
 
 
-case "$host" in
-*-interix*)
-       CFLAGS="$CFLAGS -D_ALL_SOURCE"
-       ;;
-*-darwin*)
-       CFLAGS="$CFLAGS -DDARWIN"
-       ;;
-esac
-
-
-
-
-
-
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
-  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
-echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+{ echo "$as_me:$LINENO: checking for inet_aton in -lresolv" >&5
+echo $ECHO_N "checking for inet_aton in -lresolv... $ECHO_C" >&6; }
+if test "${ac_cv_lib_resolv_inet_aton+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h>
-#include <$ac_hdr>
 
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
 int
 main ()
 {
-if ((DIR *) 0)
-return 0;
+return inet_aton ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -21989,7 +21048,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -21999,36 +21058,38 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  eval "$as_ac_Header=yes"
+  ac_cv_lib_resolv_inet_aton=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_Header=no"
+       ac_cv_lib_resolv_inet_aton=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_inet_aton" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_inet_aton" >&6; }
+if test $ac_cv_lib_resolv_inet_aton = yes; then
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+#define HAVE_LIBRESOLV 1
 _ACEOF
 
-ac_header_dirent=$ac_hdr; break
+  LIBS="-lresolv $LIBS"
+
 fi
 
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
-  { echo "$as_me:$LINENO: checking for library containing opendir" >&5
-echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; }
-if test "${ac_cv_search_opendir+set}" = set; then
+
+
+{ echo "$as_me:$LINENO: checking for inet_ntoa in -lnsl" >&5
+echo $ECHO_N "checking for inet_ntoa in -lnsl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nsl_inet_ntoa+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_func_search_save_LIBS=$LIBS
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -22042,23 +21103,16 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char opendir ();
+char inet_ntoa ();
 int
 main ()
 {
-return opendir ();
+return inet_ntoa ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' dir; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  rm -f conftest.$ac_objext conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -22092,43 +21146,42 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_search_opendir=$ac_res
+  ac_cv_lib_nsl_inet_ntoa=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_lib_nsl_inet_ntoa=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext
-  if test "${ac_cv_search_opendir+set}" = set; then
-  break
-fi
-done
-if test "${ac_cv_search_opendir+set}" = set; then
-  :
-else
-  ac_cv_search_opendir=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
-echo "${ECHO_T}$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_inet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_inet_ntoa" >&6; }
+if test $ac_cv_lib_nsl_inet_ntoa = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+  LIBS="-lnsl $LIBS"
 
 fi
 
-else
-  { echo "$as_me:$LINENO: checking for library containing opendir" >&5
-echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; }
-if test "${ac_cv_search_opendir+set}" = set; then
+
+OPENSSL_LIBS=
+old_LIBS=$LIBS
+if test "x$OPENSSL_LIB_DIR" != "x"; then
+    LIBS="-L$OPENSSL_LIB_DIR $LIBS"
+fi
+{ echo "$as_me:$LINENO: checking for DH_new in -lcrypto" >&5
+echo $ECHO_N "checking for DH_new in -lcrypto... $ECHO_C" >&6; }
+if test "${ac_cv_lib_crypto_DH_new+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_func_search_save_LIBS=$LIBS
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -22142,23 +21195,16 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char opendir ();
+char DH_new ();
 int
 main ()
 {
-return opendir ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' x; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  rm -f conftest.$ac_objext conftest$ac_exeext
+return DH_new ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
@@ -22192,70 +21238,64 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_search_opendir=$ac_res
+  ac_cv_lib_crypto_DH_new=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_lib_crypto_DH_new=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
-      conftest$ac_exeext
-  if test "${ac_cv_search_opendir+set}" = set; then
-  break
-fi
-done
-if test "${ac_cv_search_opendir+set}" = set; then
-  :
-else
-  ac_cv_search_opendir=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
-echo "${ECHO_T}$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_DH_new" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_DH_new" >&6; }
+if test $ac_cv_lib_crypto_DH_new = yes; then
 
-fi
 
-fi
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBCRYPTO 1
+_ACEOF
 
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
+       { echo "$as_me:$LINENO: checking for SSL_new in -lssl" >&5
+echo $ECHO_N "checking for SSL_new in -lssl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ssl_SSL_new+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lssl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
 
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SSL_new ();
 int
 main ()
 {
-
+return SSL_new ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -22272,7 +21312,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -22282,142 +21322,60 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_header_stdc=yes
+  ac_cv_lib_ssl_SSL_new=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_header_stdc=no
+       ac_cv_lib_ssl_SSL_new=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_new" >&5
+echo "${ECHO_T}$ac_cv_lib_ssl_SSL_new" >&6; }
+if test $ac_cv_lib_ssl_SSL_new = yes; then
 
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <string.h>
 
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBSSL 1
 _ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
+
+               if test "x$OPENSSL_LIB_DIR" != "x"; then
+                   OPENSSL_LIBS="-L$OPENSSL_LIB_DIR"
+               fi
+               OPENSSL_LIBS="$OPENSSL_LIBS -lcrypto -lssl -lcrypto"
 
 fi
 
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
 fi
-rm -f conftest*
 
-fi
+LIBS=$old_LIBS
 
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
 
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
+case "$host" in
+*-interix*)
+       CFLAGS="$CFLAGS -D_ALL_SOURCE"
+       ;;
+*-darwin*)
+       CFLAGS="$CFLAGS -DDARWIN"
+       ;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
 
 
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
 
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
 
-fi
 
-{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
-echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; }
-if test "${ac_cv_header_time+set}" = set; then
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -22427,13 +21385,12 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
+#include <$ac_hdr>
 
 int
 main ()
 {
-if ((struct tm *) 0)
+if ((DIR *) 0)
 return 0;
   ;
   return 0;
@@ -22473,64 +21430,73 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_header_time=yes
+  eval "$as_ac_Header=yes"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_header_time=no
+       eval "$as_ac_Header=no"
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
-echo "${ECHO_T}$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define TIME_WITH_SYS_TIME 1
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
 _ACEOF
 
+ac_header_dirent=$ac_hdr; break
 fi
 
-{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
-echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; }
-if test "${ac_cv_header_sys_wait_h+set}" = set; then
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/wait.h>
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
-#endif
-#ifndef WIFEXITED
-# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
 #endif
-
+char opendir ();
 int
 main ()
 {
-  int s;
-  wait (&s);
-  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+return opendir ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -22547,7 +21513,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -22557,127 +21523,80 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_header_sys_wait_h=yes
+  ac_cv_search_opendir=$ac_res
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_header_sys_wait_h=no
-fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; }
-if test $ac_cv_header_sys_wait_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_SYS_WAIT_H 1
-_ACEOF
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then
+  break
 fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then
+  :
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
+fi
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-for ac_header in \
-       unistd.h \
-       crypt.h \
-       errno.h \
-       resource.h \
-       sys/resource.h \
-       getopt.h \
-       malloc.h \
-       utmp.h \
-       utmpx.h \
-       signal.h \
-       sys/select.h \
-       syslog.h \
-       inttypes.h \
-       stdint.h \
-       stdio.h \
-       netdb.h \
-       semaphore.h \
-       arpa/inet.h \
-       netinet/in.h \
-       sys/types.h \
-       sys/socket.h \
-       winsock.h \
-       sys/time.h \
-       sys/wait.h \
-       sys/security.h \
-       fcntl.h \
-       sys/fcntl.h \
-       net/if.h \
-       prot.h \
-       pwd.h \
-       grp.h \
-       sia.h \
-       siad.h
-
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+else
+  { echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+  ac_func_search_save_LIBS=$LIBS
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -22694,7 +21613,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
+        { ac_try='test -s conftest$ac_exeext'
   { (case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
@@ -22704,132 +21623,61 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_header_compiler=yes
+  ac_cv_search_opendir=$ac_res
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
 fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-  ac_header_preproc=no
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then
+  break
 fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+done
+if test "${ac_cv_search_opendir+set}" = set; then
+  :
 else
-  eval "$as_ac_Header=\$ac_header_preproc"
+  ac_cv_search_opendir=no
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
 fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
 
-done
-
+fi
 
-REGEX=no
-if test "${ac_cv_header_regex_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for regex.h" >&5
-echo $ECHO_N "checking for regex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_regex_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_regex_h" >&5
-echo "${ECHO_T}$ac_cv_header_regex_h" >&6; }
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking regex.h usability" >&5
-echo $ECHO_N "checking regex.h usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-#include <regex.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -22865,198 +21713,162 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_header_compiler=yes
+  ac_cv_header_stdc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
+       ac_cv_header_stdc=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-# Is the header present?
-{ echo "$as_me:$LINENO: checking regex.h presence" >&5
-echo $ECHO_N "checking regex.h presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <regex.h>
+#include <string.h>
+
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
 else
-  ac_cpp_err=yes
+  ac_cv_header_stdc=no
 fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+rm -f conftest*
 
-  ac_header_preproc=no
 fi
 
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: regex.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: regex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: regex.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: regex.h: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: regex.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: regex.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: regex.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: regex.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: regex.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: regex.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: regex.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: regex.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: regex.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: regex.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: regex.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: regex.h: in the future, the compiler will take precedence" >&2;}
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
 
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for regex.h" >&5
-echo $ECHO_N "checking for regex.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_regex_h+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
 else
-  ac_cv_header_regex_h=$ac_header_preproc
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_regex_h" >&5
-echo "${ECHO_T}$ac_cv_header_regex_h" >&6; }
-
+  ac_cv_header_stdc=no
 fi
-if test $ac_cv_header_regex_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_REGEX_H
-_ACEOF
+rm -f conftest*
 
 fi
 
-
-if test "x$ac_cv_header_regex_h" = "xyes"; then
-  REGEX_EXTENDED=no
-  REGEX=yes
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <regex.h>
-     #ifdef REG_EXTENDED
-       yes
-     #endif
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
 
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
 _ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_REG_EXTENDED
-_ACEOF
- REGEX_EXTENDED=yes
+( exit $ac_status )
+ac_cv_header_stdc=no
 fi
-rm -f conftest*
-
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
 
 
-
-if test "x$ac_cv_header_sys_security_h" = "xyes" && test "x$ac_cv_header_prot_h" = "xyes"
-then
-
-cat >>confdefs.h <<\_ACEOF
-#define OSFC2
-_ACEOF
-
 fi
-
-if test "x$ac_cv_header_sia_h" = "xyes" && test "x$ac_cv_header_siad_h" = "xyes"
-then
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
 
 cat >>confdefs.h <<\_ACEOF
-#define OSFSIA
+#define STDC_HEADERS 1
 _ACEOF
 
 fi
 
-OPENSSL_INCLUDE="-DNO_OPENSSL"
-if test "x$OPENSSL_LIBS" = "x"; then
-    { echo "$as_me:$LINENO: skipping test for openssl/ssl.h" >&5
-echo "$as_me: skipping test for openssl/ssl.h" >&6;}
-else
-    old_CPPFLAGS=$CPPFLAGS
-    if test "x$OPENSSL_INCLUDE_DIR" != "x"; then
-       CPPFLAGS="$CPPFLAGS -I$OPENSSL_INCLUDE_DIR"
-    fi
-        CPPFLAGS="$CPPFLAGS -DOPENSSL_NO_KRB5"
-
-
-
-
-for ac_header in \
-       openssl/ssl.h \
-       openssl/crypto.h \
-       openssl/err.h \
-       openssl/engine.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; }
+if test "${ac_cv_header_time+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -23092,170 +21904,188 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_header_compiler=yes
+  ac_cv_header_time=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
+       ac_cv_header_time=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
 
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <$ac_header>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_sys_wait_h=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-  ac_header_preproc=no
+       ac_cv_header_sys_wait_h=no
 fi
 
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
 
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_WAIT_H 1
+_ACEOF
 
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
 
-else
-  OPENSSL_LIBS=
 
-fi
 
-done
 
-    if test "x$OPENSSL_LIBS" != "x"; then
-       { echo "$as_me:$LINENO: checking for OpenSSL version >= 0.9.7" >&5
-echo $ECHO_N "checking for OpenSSL version >= 0.9.7... $ECHO_C" >&6; }
-       cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <openssl/crypto.h>
-            #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-            yes
-            #endif
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then
-  goodssl="yes"
-fi
-rm -f conftest*
 
-       if test "x$goodssl" != "xyes"; then
-           { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-           OPENSSL_LIBS=
-       else
-           { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-           if test "x$OPENSSL_INCLUDE_DIR" != "x"; then
-               OPENSSL_INCLUDE="-I$OPENSSL_INCLUDE_DIR -DOPENSSL_NO_KRB5"
-           else
-               OPENSSL_INCLUDE="-DOPENSSL_NO_KRB5"
-           fi
-       fi
-    fi
-    CPPFLAGS=$old_CPPFLAGS
-fi
 
 
-export OPENSSL_LIBS
 
-if test "x$PCAP_LIBS" = x; then
-    { echo "$as_me:$LINENO: skipping test for pcap.h." >&5
-echo "$as_me: skipping test for pcap.h." >&6;}
-else
-    if test "${ac_cv_header_pcap_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for pcap.h" >&5
-echo $ECHO_N "checking for pcap.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_pcap_h+set}" = set; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in \
+       unistd.h \
+       crypt.h \
+       errno.h \
+       resource.h \
+       getopt.h \
+       malloc.h \
+       utmp.h \
+       utmpx.h \
+       signal.h \
+       sys/select.h \
+       syslog.h \
+       inttypes.h \
+       stdint.h \
+       stdio.h \
+       netdb.h \
+       semaphore.h \
+       arpa/inet.h \
+       netinet/in.h \
+       sys/types.h \
+       sys/socket.h \
+       sys/time.h \
+       sys/wait.h \
+       sys/security.h \
+       fcntl.h \
+       sys/fcntl.h \
+       sys/stat.h \
+       sys/prctl.h \
+       prot.h \
+       sia.h \
+       siad.h
+
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_pcap_h" >&5
-echo "${ECHO_T}$ac_cv_header_pcap_h" >&6; }
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking pcap.h usability" >&5
-echo $ECHO_N "checking pcap.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -23263,7 +22093,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <pcap.h>
+#include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -23312,15 +22142,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking pcap.h presence" >&5
-echo $ECHO_N "checking pcap.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <pcap.h>
+#include <$ac_header>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -23360,80 +22190,71 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: pcap.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: pcap.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: pcap.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: pcap.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: pcap.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: pcap.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: pcap.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: pcap.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: pcap.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: pcap.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: pcap.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: pcap.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: pcap.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: pcap.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: pcap.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: pcap.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for pcap.h" >&5
-echo $ECHO_N "checking for pcap.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_pcap_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_pcap_h=$ac_header_preproc
+  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_pcap_h" >&5
-echo "${ECHO_T}$ac_cv_header_pcap_h" >&6; }
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 
 fi
-if test $ac_cv_header_pcap_h = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_PCAP_H 1
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
-else
-   PCAP_LIBS=
-       { echo "$as_me:$LINENO: WARNING: pcap.h not found, silently disabling the RADIUS sniffer." >&5
-echo "$as_me: WARNING: pcap.h not found, silently disabling the RADIUS sniffer." >&2;}
-
-fi
-
-
 fi
 
+done
 
 
-{ echo "$as_me:$LINENO: checking for off_t" >&5
-echo $ECHO_N "checking for off_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_off_t+set}" = set; then
+REGEX=no
+if test "${ac_cv_header_regex_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for regex.h" >&5
+echo $ECHO_N "checking for regex.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_regex_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_regex_h" >&5
+echo "${ECHO_T}$ac_cv_header_regex_h" >&6; }
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking regex.h usability" >&5
+echo $ECHO_N "checking regex.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-typedef off_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
-  ;
-  return 0;
-}
+#include <regex.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -23469,254 +22290,194 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_off_t=yes
+  ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_type_off_t=no
+       ac_header_compiler=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
-echo "${ECHO_T}$ac_cv_type_off_t" >&6; }
-if test $ac_cv_type_off_t = yes; then
-  :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define off_t long int
-_ACEOF
-
-fi
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-{ echo "$as_me:$LINENO: checking for pid_t" >&5
-echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_pid_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
+# Is the header present?
+{ echo "$as_me:$LINENO: checking regex.h presence" >&5
+echo $ECHO_N "checking regex.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-typedef pid_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
-  ;
-  return 0;
-}
+#include <regex.h>
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_pid_t=yes
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_type_pid_t=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_header_preproc=no
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
-echo "${ECHO_T}$ac_cv_type_pid_t" >&6; }
-if test $ac_cv_type_pid_t = yes; then
-  :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
-_ACEOF
 
-fi
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
-{ echo "$as_me:$LINENO: checking for size_t" >&5
-echo $ECHO_N "checking for size_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_size_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-typedef size_t ac__type_new_;
-int
-main ()
-{
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_size_t=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: regex.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: regex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: regex.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: regex.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: regex.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: regex.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: regex.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: regex.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: regex.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: regex.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: regex.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: regex.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: regex.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: regex.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: regex.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: regex.h: in the future, the compiler will take precedence" >&2;}
 
-       ac_cv_type_size_t=no
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for regex.h" >&5
+echo $ECHO_N "checking for regex.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_regex_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_regex_h=$ac_header_preproc
 fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_regex_h" >&5
+echo "${ECHO_T}$ac_cv_header_regex_h" >&6; }
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
-echo "${ECHO_T}$ac_cv_type_size_t" >&6; }
-if test $ac_cv_type_size_t = yes; then
-  :
-else
-
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
+if test $ac_cv_header_regex_h = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_REGEX_H 1
 _ACEOF
 
 fi
 
-{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
-echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; }
-if test "${ac_cv_type_uid_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
+
+if test "x$ac_cv_header_regex_h" = "xyes"; then
+  REGEX_EXTENDED=no
+  REGEX=yes
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <sys/types.h>
+#include <regex.h>
+     #ifdef REG_EXTENDED
+       yes
+     #endif
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "uid_t" >/dev/null 2>&1; then
-  ac_cv_type_uid_t=yes
-else
-  ac_cv_type_uid_t=no
+  $EGREP "yes" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_REG_EXTENDED 1
+_ACEOF
+ REGEX_EXTENDED=yes
 fi
 rm -f conftest*
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
-echo "${ECHO_T}$ac_cv_type_uid_t" >&6; }
-if test $ac_cv_type_uid_t = no; then
 
-cat >>confdefs.h <<\_ACEOF
-#define uid_t int
+
+
+if test "x$ac_cv_header_sys_security_h" = "xyes" && test "x$ac_cv_header_prot_h" = "xyes"
+then
+  cat >>confdefs.h <<\_ACEOF
+#define OSFC2 1
 _ACEOF
 
+fi
 
-cat >>confdefs.h <<\_ACEOF
-#define gid_t int
+if test "x$ac_cv_header_sia_h" = "xyes" && test "x$ac_cv_header_siad_h" = "xyes"
+then
+  cat >>confdefs.h <<\_ACEOF
+#define OSFSIA 1
 _ACEOF
 
 fi
 
+OPENSSL_INCLUDE="-DNO_OPENSSL"
+if test "x$OPENSSL_LIBS" = "x"; then
+    { echo "$as_me:$LINENO: WARNING: skipping test for openssl/ssl.h" >&5
+echo "$as_me: WARNING: skipping test for openssl/ssl.h" >&2;}
+else
+    old_CPPFLAGS=$CPPFLAGS
+    if test "x$OPENSSL_INCLUDE_DIR" != "x"; then
+       CPPFLAGS="$CPPFLAGS -I$OPENSSL_INCLUDE_DIR"
+    fi
+        CPPFLAGS="$CPPFLAGS -DOPENSSL_NO_KRB5"
+
 
 
-  { echo "$as_me:$LINENO: checking for socklen_t" >&5
-echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_socklen_t+set}" = set; then
+
+for ac_header in \
+       openssl/ssl.h \
+       openssl/crypto.h \
+       openssl/err.h \
+       openssl/engine.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 else
-   ac_cv_type_socklen_t=no
-      cat >conftest.$ac_ext <<_ACEOF
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-int
-main ()
-{
-socklen_t foo
-  ;
-  return 0;
-}
+$ac_includes_default
+#include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -23752,54 +22513,175 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_socklen_t=yes
+  ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_header_compiler=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
 
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
-echo "${ECHO_T}$ac_cv_type_socklen_t" >&6; }
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
 
-  if test "$ac_cv_type_socklen_t" != "yes"; then
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
 
-cat >>confdefs.h <<\_ACEOF
-#define socklen_t int
+else
+  OPENSSL_LIBS=
+
+fi
+
+done
+
+    if test "x$OPENSSL_LIBS" != "x"; then
+       { echo "$as_me:$LINENO: checking for OpenSSL version >= 0.9.7" >&5
+echo $ECHO_N "checking for OpenSSL version >= 0.9.7... $ECHO_C" >&6; }
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/crypto.h>
+            #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+            yes
+            #endif
 
-  fi
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  goodssl="yes"
+fi
+rm -f conftest*
+
+       if test "x$goodssl" != "xyes"; then
+           { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+           OPENSSL_LIBS=
+       else
+           { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+           if test "x$OPENSSL_INCLUDE_DIR" != "x"; then
+               OPENSSL_INCLUDE="-I$OPENSSL_INCLUDE_DIR -DOPENSSL_NO_KRB5"
+           else
+               OPENSSL_INCLUDE="-DOPENSSL_NO_KRB5"
+           fi
+       fi
+    fi
+    CPPFLAGS=$old_CPPFLAGS
+fi
 
 
+export OPENSSL_LIBS
 
-  { echo "$as_me:$LINENO: checking for uint8_t" >&5
-echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_uint8_t+set}" = set; then
+
+{ echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_off_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-   ac_cv_type_uint8_t=no
-      cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
+$ac_includes_default
+typedef off_t ac__type_new_;
 int
 main ()
 {
-uint8_t foo
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
   ;
   return 0;
 }
@@ -23838,54 +22720,48 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_uint8_t=yes
+  ac_cv_type_off_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_type_off_t=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5
-echo "${ECHO_T}$ac_cv_type_uint8_t" >&6; }
-
-  if test "$ac_cv_type_uint8_t" != "yes"; then
+{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6; }
+if test $ac_cv_type_off_t = yes; then
+  :
+else
 
-cat >>confdefs.h <<\_ACEOF
-#define uint8_t unsigned char
+cat >>confdefs.h <<_ACEOF
+#define off_t long int
 _ACEOF
 
-  fi
-
-
+fi
 
-  { echo "$as_me:$LINENO: checking for uint16_t" >&5
-echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_uint16_t+set}" = set; then
+{ echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_pid_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-   ac_cv_type_uint16_t=no
-      cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
+$ac_includes_default
+typedef pid_t ac__type_new_;
 int
 main ()
 {
-uint16_t foo
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
   ;
   return 0;
 }
@@ -23924,54 +22800,48 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_uint16_t=yes
+  ac_cv_type_pid_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_type_pid_t=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
-echo "${ECHO_T}$ac_cv_type_uint16_t" >&6; }
-
-  if test "$ac_cv_type_uint16_t" != "yes"; then
+{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6; }
+if test $ac_cv_type_pid_t = yes; then
+  :
+else
 
-cat >>confdefs.h <<\_ACEOF
-#define uint16_t unsigned short
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
 _ACEOF
 
-  fi
-
-
+fi
 
-  { echo "$as_me:$LINENO: checking for uint32_t" >&5
-echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6; }
-if test "${ac_cv_type_uint32_t+set}" = set; then
+{ echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_size_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-   ac_cv_type_uint32_t=no
-      cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
+$ac_includes_default
+typedef size_t ac__type_new_;
 int
 main ()
 {
-uint32_t foo
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
   ;
   return 0;
 }
@@ -24010,55 +22880,91 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_uint32_t=yes
+  ac_cv_type_size_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_type_size_t=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6; }
+if test $ac_cv_type_size_t = yes; then
+  :
+else
 
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
-echo "${ECHO_T}$ac_cv_type_uint32_t" >&6; }
 
-  if test "$ac_cv_type_uint32_t" != "yes"; then
+{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
+echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; }
+if test "${ac_cv_type_uid_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uid_t" >/dev/null 2>&1; then
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
+echo "${ECHO_T}$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
 
 cat >>confdefs.h <<\_ACEOF
-#define uint32_t unsigned int
+#define uid_t int
 _ACEOF
 
-  fi
+
+cat >>confdefs.h <<\_ACEOF
+#define gid_t int
+_ACEOF
+
+fi
+
 
 
-{ echo "$as_me:$LINENO: checking for struct in6_addr" >&5
-echo $ECHO_N "checking for struct in6_addr... $ECHO_C" >&6; }
-if test "${ac_cv_type_struct_in6_addr+set}" = set; then
+  { echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_socklen_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+   ac_cv_type_socklen_t=no
+      cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
 #endif
 
-
-typedef struct in6_addr ac__type_new_;
 int
 main ()
 {
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
+socklen_t foo
   ;
   return 0;
 }
@@ -24097,55 +23003,53 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_struct_in6_addr=yes
+  ac_cv_type_socklen_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_type_struct_in6_addr=no
+
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_struct_in6_addr" >&5
-echo "${ECHO_T}$ac_cv_type_struct_in6_addr" >&6; }
-if test $ac_cv_type_struct_in6_addr = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
+echo "${ECHO_T}$ac_cv_type_socklen_t" >&6; }
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRUCT_IN6_ADDR 1
+  if test "$ac_cv_type_socklen_t" != "yes"; then
+         cat >>confdefs.h <<\_ACEOF
+#define socklen_t int
 _ACEOF
 
-fi
+  fi
 
 
-{ echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5
-echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6; }
-if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then
+
+  { echo "$as_me:$LINENO: checking for uint8_t" >&5
+echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_uint8_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+   ac_cv_type_uint8_t=no
+      cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
 #endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
 #endif
 
-
-typedef struct sockaddr_storage ac__type_new_;
 int
 main ()
 {
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
+uint8_t foo
   ;
   return 0;
 }
@@ -24184,52 +23088,53 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_struct_sockaddr_storage=yes
+  ac_cv_type_uint8_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_type_struct_sockaddr_storage=no
+
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5
-echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6; }
-if test $ac_cv_type_struct_sockaddr_storage = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint8_t" >&6; }
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+  if test "$ac_cv_type_uint8_t" != "yes"; then
+         cat >>confdefs.h <<\_ACEOF
+#define uint8_t unsigned char
 _ACEOF
 
-fi
+  fi
 
 
-{ echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5
-echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6; }
-if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
+
+  { echo "$as_me:$LINENO: checking for uint16_t" >&5
+echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_uint16_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+   ac_cv_type_uint16_t=no
+      cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
 #endif
 
-
-typedef struct sockaddr_in6 ac__type_new_;
 int
 main ()
 {
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
+uint16_t foo
   ;
   return 0;
 }
@@ -24268,58 +23173,53 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_struct_sockaddr_in6=yes
+  ac_cv_type_uint16_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_type_struct_sockaddr_in6=no
+
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
-echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6; }
-if test $ac_cv_type_struct_sockaddr_in6 = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint16_t" >&6; }
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRUCT_SOCKADDR_IN6 1
+  if test "$ac_cv_type_uint16_t" != "yes"; then
+         cat >>confdefs.h <<\_ACEOF
+#define uint16_t unsigned short
 _ACEOF
 
-fi
+  fi
+
 
 
-{ echo "$as_me:$LINENO: checking for struct addrinfo" >&5
-echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6; }
-if test "${ac_cv_type_struct_addrinfo+set}" = set; then
+  { echo "$as_me:$LINENO: checking for uint32_t" >&5
+echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6; }
+if test "${ac_cv_type_uint32_t+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+   ac_cv_type_uint32_t=no
+      cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
 #endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
 #endif
 
-
-typedef struct addrinfo ac__type_new_;
 int
 main ()
 {
-if ((ac__type_new_ *) 0)
-  return 0;
-if (sizeof (ac__type_new_))
-  return 0;
+uint32_t foo
   ;
   return 0;
 }
@@ -24358,29 +23258,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_type_struct_addrinfo=yes
+  ac_cv_type_uint32_t=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_type_struct_addrinfo=no
+
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_type_struct_addrinfo" >&5
-echo "${ECHO_T}$ac_cv_type_struct_addrinfo" >&6; }
-if test $ac_cv_type_struct_addrinfo = yes; then
 
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRUCT_ADDRINFO 1
-_ACEOF
 
 fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint32_t" >&6; }
 
+  if test "$ac_cv_type_uint32_t" != "yes"; then
+         cat >>confdefs.h <<\_ACEOF
+#define uint32_t unsigned int
+_ACEOF
 
-
-
+  fi
 
 
 
@@ -24426,16 +23324,12 @@ for ac_func in \
        inet_aton \
        inet_pton \
        inet_ntop \
+       gethostname \
        setlinebuf \
        setvbuf \
        getusershell \
        initgroups \
-       getaddrinfo \
-       getnameinfo \
-       closefrom \
-       gettimeofday \
-       strlcat \
-       strlcpy
+       closefrom
 
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -24531,7 +23425,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        eval "$as_ac_var=no"
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 ac_res=`eval echo '${'$as_ac_var'}'`
@@ -24550,6 +23444,7 @@ for ac_func in \
        strncasecmp \
        strcasecmp \
        inet_aton \
+       gethostname \
        setlinebuf \
        getusershell \
        endusershell
@@ -24843,8 +23738,7 @@ echo "${ECHO_T}no" >&6; }
 
  if test "x$ac_cv_type_struct_utmpx_has_ut_xtime" = "x"
  then
-
-cat >>confdefs.h <<\_ACEOF
+   cat >>confdefs.h <<\_ACEOF
 #define ut_xtime ut_tv.tv_sec
 _ACEOF
 
@@ -24933,98 +23827,8 @@ echo "${ECHO_T}no" >&6; }
 
 if test "x$ac_cv_type_struct_in_pktinfo_has_ipi_addr" = "xyes"
 then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_IP_PKTINFO
-_ACEOF
-
-fi
-
-
-  { echo "$as_me:$LINENO: checking for ipi6_addr in struct in6_pktinfo" >&5
-echo $ECHO_N "checking for ipi6_addr in struct in6_pktinfo... $ECHO_C" >&6; }
-
-
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <netinet/in.h>
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
-#endif
-
-int
-main ()
-{
- int foo = offsetof(struct in6_pktinfo, ipi6_addr)
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  has_element=" "
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       has_element=
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-  ac_safe_type=`echo "struct in6_pktinfo" | sed 'y% %_%'`
-  if test "x$has_element" != "x"; then
-    { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-    eval "ac_cv_type_${ac_safe_type}_has_ipi6_addr=yes"
-  else
-    { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-    eval "ac_cv_type_${ac_safe_type}_has_ipi6_addr="
- fi
-
-if test "x$ac_cv_type_struct_in6_pktinfo_has_ipi6_addr" = "xyes"
-then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_IN6_PKTINFO
+       cat >>confdefs.h <<\_ACEOF
+#define HAVE_IP_PKTINFO 1
 _ACEOF
 
 fi
@@ -25049,10 +23853,10 @@ main ()
 #ifndef __cplusplus
   /* Ultrix mips cc rejects this.  */
   typedef int charset[2];
-  const charset x;
+  const charset cs;
   /* SunOS 4.1.1 cc rejects this.  */
-  char const *const *ccp;
-  char **p;
+  char const *const *pcpcc;
+  char **ppc;
   /* NEC SVR4.0.2 mips cc rejects this.  */
   struct point {int x, y;};
   static struct point const zero = {0,0};
@@ -25061,11 +23865,11 @@ main ()
      an arm of an if-expression whose if-part is not a constant
      expression */
   const char *g = "string";
-  ccp = &g + (g ? g-g : 0);
+  pcpcc = &g + (g ? g-g : 0);
   /* HPUX 7.0 cc rejects these. */
-  ++ccp;
-  p = (char**) ccp;
-  ccp = (char const *const *) p;
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
   { /* SCO 3.2v4 cc rejects this.  */
     char *t;
     char const *s = 0 ? (char *) 0 : (char const *) 0;
@@ -25092,7 +23896,7 @@ main ()
     const int foo = 10;
     if (!foo) return 0;
   }
-  return !x[0] && !zero.x;
+  return !cs[0] && !zero.x;
 #endif
 
   ;
@@ -25258,7 +24062,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_crypt_crypt=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -25270,9 +24074,8 @@ if test $ac_cv_lib_crypt_crypt = yes; then
 fi
 
 if test "$CRYPTLIB" != ""; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CRYPT
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_CRYPT 1
 _ACEOF
 
 else
@@ -25368,15 +24171,14 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_func_crypt=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 { echo "$as_me:$LINENO: result: $ac_cv_func_crypt" >&5
 echo "${ECHO_T}$ac_cv_func_crypt" >&6; }
 if test $ac_cv_func_crypt = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CRYPT
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_CRYPT 1
 _ACEOF
 
 fi
@@ -25454,7 +24256,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_cv_lib_cipher_setkey=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
@@ -25555,7 +24357,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 if test "x$ucdsnmp" = "x"; then
   old_CFLAGS="$CFLAGS"
-  for try in /usr/include /usr/local/include $snmp_include_dir; do
+  for try in /usr/include /usr/local/include $with_snmp_include_dir; do
     CFLAGS="$old_CFLAGS -I$try"
     cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -25643,7 +24445,7 @@ fi
 
 if test "x$ucdsnmp" = "x"; then
   old_CFLAGS="$CFLAGS"
-  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $snmp_include_dir; do
+  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $with_snmp_include_dir; do
     CFLAGS="$old_CFLAGS -I$try"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -25730,7 +24532,7 @@ fi
 
 if test "x$ucdsnmp" = "x"; then
   old_CFLAGS="$CFLAGS"
-  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $snmp_include_dir; do
+  for try in /usr/include/ucd-snmp /usr/local/include/ucd-snmp $with_snmp_include_dir; do
     CFLAGS="$old_CFLAGS -I$try"
     cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -25822,17 +24624,15 @@ else
   if test "x$ucdsnmp" = "xyes"; then
     { echo "$as_me:$LINENO: result: (ucd-snmp)yes" >&5
 echo "${ECHO_T}(ucd-snmp)yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H
+    cat >>confdefs.h <<\_ACEOF
+#define HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H 1
 _ACEOF
 
   else
     { echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ASN1_SNMP_SNMPIMPL_H
+    cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASN1_SNMP_SNMPIMPL_H 1
 _ACEOF
 
   fi
@@ -25898,7 +24698,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        SNMP_LIBS=
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 
   if test "x$SNMP_LIBS" = "x"; then
@@ -25961,7 +24761,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        SNMP_LIBS=
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
       if test "x$SNMP_LIBS" != "x"; then
         break;
@@ -26024,7 +24824,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        SNMP_LIBS=
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
       if test "x$SNMP_LIBS" != "x"; then
         break;
@@ -26087,7 +24887,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        SNMP_LIBS=
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
       if test "x$SNMP_LIBS" != "x"; then
         break;
@@ -26104,14 +24904,12 @@ echo "${ECHO_T}no" >&6; }
   else
     { echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6; }
-
-cat >>confdefs.h <<\_ACEOF
-#define WITH_SNMP
+    cat >>confdefs.h <<\_ACEOF
+#define WITH_SNMP 1
 _ACEOF
 
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LIBSNMP
+    cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBSNMP 1
 _ACEOF
 
   fi
 
 fi
 
-
-cat >>confdefs.h <<\_ACEOF
-#define GNUSTYLE 1
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define SYSVSTYLE 2
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define BSDSTYLE 3
-_ACEOF
-
 gethostbyaddrrstyle=""
 { echo "$as_me:$LINENO: checking gethostbyaddr_r() syntax" >&5
 echo $ECHO_N "checking gethostbyaddr_r() syntax... $ECHO_C" >&6; }
 case "$host" in
 *-freebsd*)
-
-cat >>confdefs.h <<\_ACEOF
+       cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYADDRRSTYLE BSDSTYLE
 _ACEOF
 
@@ -26203,8 +24985,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+       cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYADDRRSTYLE GNUSTYLE
 _ACEOF
 
@@ -26217,7 +24998,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 if test "x$gethostbyaddrrstyle" = "x"; then
@@ -26274,8 +25055,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+               cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYADDRRSTYLE SYSVSTYLE
 _ACEOF
 
@@ -26288,7 +25068,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 if test "x$gethostbyaddrrstyle" = "x"; then
@@ -26345,8 +25125,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+               cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYADDRRSTYLE BSDSTYLE
 _ACEOF
 
@@ -26359,7 +25138,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 
@@ -26432,8 +25211,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+       cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYNAMERSTYLE GNUSTYLE
 _ACEOF
 
@@ -26446,7 +25224,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test "x$gethostbynamerstyle" = "x"; then
        cat >conftest.$ac_ext <<_ACEOF
@@ -26502,8 +25280,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+               cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYNAMERSTYLE SYSVSTYLE
 _ACEOF
 
@@ -26516,7 +25293,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 if test "x$gethostbynamerstyle" = "x"; then
@@ -26573,8 +25350,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+               cat >>confdefs.h <<\_ACEOF
 #define GETHOSTBYNAMERSTYLE BSDSTYLE
 _ACEOF
 
@@ -26587,7 +25363,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 
@@ -26604,16 +25380,6 @@ if test "x$gethostbynamerstyle" = "xBSD"; then
 echo "$as_me: WARNING:  ****** BSD-style gethostbyname might NOT be thread-safe! ****** " >&2;}
 fi
 
-
-cat >>confdefs.h <<\_ACEOF
-#define POSIXSTYLE 1
-_ACEOF
-
-
-cat >>confdefs.h <<\_ACEOF
-#define SOLARISSTYLE 2
-_ACEOF
-
 ctimerstyle=""
 { echo "$as_me:$LINENO: checking ctime_r() syntax" >&5
 echo $ECHO_N "checking ctime_r() syntax... $ECHO_C" >&6; }
@@ -26669,8 +25435,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+       cat >>confdefs.h <<\_ACEOF
 #define CTIMERSTYLE SOLARISSTYLE
 _ACEOF
 
@@ -26683,7 +25448,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 if test "x$ctimerstyle" = "x"; then
        cat >conftest.$ac_ext <<_ACEOF
@@ -26738,8 +25503,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
 
-
-cat >>confdefs.h <<\_ACEOF
+               cat >>confdefs.h <<\_ACEOF
 #define CTIMERSTYLE POSIXSTYLE
 _ACEOF
 
@@ -26752,7 +25516,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
 
@@ -26764,6 +25528,116 @@ else
 echo "${ECHO_T}${ctimerstyle}-style" >&6; }
 fi
 
+
+if test x"$rad_enable_largefiles" = xyes ; then
+    { echo "$as_me:$LINENO: checking for largefile linkage" >&5
+echo $ECHO_N "checking for largefile linkage... $ECHO_C" >&6; }
+    case "$host" in
+    *-aix4.01*)
+        { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+        { { echo "$as_me:$LINENO: error: AIX before 4.2 does not support large files" >&5
+echo "$as_me: error: AIX before 4.2 does not support large files" >&2;}
+   { (exit 1); exit 1; }; }
+        ;;
+    *-aix4*)
+        { echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6; }
+        LFS_CFLAGS="-D_LARGE_FILES"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        ;;
+    *-hpux*)
+        { echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6; }
+        LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        ;;
+    *-irix*)
+        { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+        { { echo "$as_me:$LINENO: error: Large files not supported on this platform" >&5
+echo "$as_me: error: Large files not supported on this platform" >&2;}
+   { (exit 1); exit 1; }; }
+        ;;
+    *-linux*)
+        { echo "$as_me:$LINENO: result: maybe" >&5
+echo "${ECHO_T}maybe" >&6; }
+        LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+
+cat >>confdefs.h <<\_ACEOF
+#define _GNU_SOURCE 1
+_ACEOF
+
+        ;;
+    *-solaris*)
+        { echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6; }
+        # Extract the first word of "getconf", so it can be a program name with args.
+set dummy getconf; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_GETCONF+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GETCONF in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+GETCONF=$ac_cv_path_GETCONF
+if test -n "$GETCONF"; then
+  { echo "$as_me:$LINENO: result: $GETCONF" >&5
+echo "${ECHO_T}$GETCONF" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+        if test -z "$GETCONF" ; then
+            { { echo "$as_me:$LINENO: error: getconf required to configure large file support" >&5
+echo "$as_me: error: getconf required to configure large file support" >&2;}
+   { (exit 1); exit 1; }; }
+        fi
+        LFS_CFLAGS=`$GETCONF LFS_CFLAGS`
+        LFS_LDFLAGS=`$GETCONF LFS_LDFLAGS`
+        LFS_LIBS=`$GETCONF LFS_LIBS`
+        ;;
+    *)
+        { echo "$as_me:$LINENO: result: maybe" >&5
+echo "${ECHO_T}maybe" >&6; }
+        LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        ;;
+    esac
+
+
+
+fi
+
 HOSTINFO=$host
 
 
@@ -26777,24 +25651,24 @@ echo "${ECHO_T}top_builddir=$top_builddir" >&6; }
 
 
 
-mysubdirs="$LIBLTDLPATH"
+mysubdirs=
 if test "x$EXPERIMENTAL" = "xyes"; then
-  bar=`ls -1 "${srcdir}"/src/modules/rlm_*/configure | sed 's%/configure%%'`
-    mysubdirs=`echo $mysubdirs $bar`
+  bar=`ls -1 src/modules/rlm_*/configure | sed 's%/configure%%'`
+    mysubdirs=`echo $bar`
 else
-        for bar in `cat "${srcdir}"/src/modules/stable`; do
-    if test -f "${srcdir}"/src/modules/$bar/configure; then
+        for bar in `cat src/modules/stable`; do
+    if test -f src/modules/$bar/configure; then
       mysubdirs="$mysubdirs src/modules/$bar"
     fi
   done
 fi
 
 if test "x$EXPERIMENTAL" = "xyes"; then
-  for foo in `ls -1 "${srcdir}"/src/modules | grep rlm_`; do
+  for foo in `ls -1 src/modules | grep rlm_`; do
     MODULES="$MODULES $foo"
   done
 else
-            for foo in `cat "${srcdir}"/src/modules/stable`; do
+            for foo in `cat src/modules/stable`; do
     MODULES="$MODULES $foo"
    done
 fi
@@ -26804,15 +25678,6 @@ subdirs="$subdirs $LTDL_SUBDIRS $mysubdirs"
 
 
 
-ac_config_commands="$ac_config_commands stamp-h"
-
-ac_config_commands="$ac_config_commands build-radpaths-h"
-
-ac_config_commands="$ac_config_commands main-chmod"
-
-ac_config_commands="$ac_config_commands scripts-chmod"
-
-
 
 
 
@@ -26824,8 +25689,9 @@ USE_STATIC_LIBS=$enable_static
 
 
 
+export CFLAGS LIBS
 
-ac_config_files="$ac_config_files ./Make.inc ./src/include/build-radpaths-h ./src/main/Makefile ./src/main/checkrad.pl ./src/main/radlast ./src/main/radtest ./scripts/rc.radiusd ./scripts/radwatch ./scripts/check-radiusd-config ./scripts/radiusd.cron.daily ./scripts/radiusd.cron.monthly ./scripts/cryptpasswd ./raddb/dictionary ./raddb/radiusd.conf ./raddb/radrelay.conf"
+ac_config_files="$ac_config_files ./Make.inc ./src/include/build-radpaths-h ./src/main/Makefile ./src/main/checkrad.pl ./src/main/radlast ./src/main/radtest ./scripts/rc.radiusd ./scripts/radwatch ./scripts/check-radiusd-config ./scripts/radiusd.cron.daily ./scripts/radiusd.cron.monthly ./scripts/cryptpasswd ./raddb/dictionary ./raddb/radiusd.conf"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -27211,7 +26077,7 @@ exec 6>&1
 # values after options handling.
 ac_log="
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.60a.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -27228,7 +26094,6 @@ cat >>$CONFIG_STATUS <<_ACEOF
 # Files that config.status was made for.
 config_files="$ac_config_files"
 config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
 
 _ACEOF
 
@@ -27240,7 +26105,7 @@ current configuration.
 Usage: $0 [OPTIONS] [FILE]...
 
   -h, --help       print this help, then exit
-  -V, --version    print version number, then exit
+  -V, --version    print version number and configuration settings, then exit
   -q, --quiet      do not print progress messages
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
@@ -27255,16 +26120,13 @@ $config_files
 Configuration headers:
 $config_headers
 
-Configuration commands:
-$config_commands
-
 Report bugs to <bug-autoconf@gnu.org>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.60,
+configured by $0, generated by GNU Autoconf 2.60a,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
 Copyright (C) 2006 Free Software Foundation, Inc.
@@ -27371,10 +26233,6 @@ for ac_config_target in $ac_config_targets
 do
   case $ac_config_target in
     "src/include/autoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/autoconf.h" ;;
-    "stamp-h") CONFIG_COMMANDS="$CONFIG_COMMANDS stamp-h" ;;
-    "build-radpaths-h") CONFIG_COMMANDS="$CONFIG_COMMANDS build-radpaths-h" ;;
-    "main-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS main-chmod" ;;
-    "scripts-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS scripts-chmod" ;;
     "./Make.inc") CONFIG_FILES="$CONFIG_FILES ./Make.inc" ;;
     "./src/include/build-radpaths-h") CONFIG_FILES="$CONFIG_FILES ./src/include/build-radpaths-h" ;;
     "./src/main/Makefile") CONFIG_FILES="$CONFIG_FILES ./src/main/Makefile" ;;
@@ -27389,7 +26247,6 @@ do
     "./scripts/cryptpasswd") CONFIG_FILES="$CONFIG_FILES ./scripts/cryptpasswd" ;;
     "./raddb/dictionary") CONFIG_FILES="$CONFIG_FILES ./raddb/dictionary" ;;
     "./raddb/radiusd.conf") CONFIG_FILES="$CONFIG_FILES ./raddb/radiusd.conf" ;;
-    "./raddb/radrelay.conf") CONFIG_FILES="$CONFIG_FILES ./raddb/radrelay.conf" ;;
 
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@ -27405,7 +26262,6 @@ done
 if $ac_need_defaults; then
   test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
   test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
@@ -27496,13 +26352,11 @@ CPPFLAGS!$CPPFLAGS$ac_delim
 ac_ct_CC!$ac_ct_CC$ac_delim
 EXEEXT!$EXEEXT$ac_delim
 OBJEXT!$OBJEXT$ac_delim
-CXX!$CXX$ac_delim
-CXXFLAGS!$CXXFLAGS$ac_delim
-ac_ct_CXX!$ac_ct_CXX$ac_delim
 CPP!$CPP$ac_delim
 GREP!$GREP$ac_delim
 EGREP!$EGREP$ac_delim
 RANLIB!$RANLIB$ac_delim
+abs_top_builddir!$abs_top_builddir$ac_delim
 GMAKE!$GMAKE$ac_delim
 MAKE!$MAKE$ac_delim
 LTDL_SUBDIRS!$LTDL_SUBDIRS$ac_delim
@@ -27519,6 +26373,9 @@ LN_S!$LN_S$ac_delim
 ECHO!$ECHO$ac_delim
 AR!$AR$ac_delim
 STRIP!$STRIP$ac_delim
+CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
 CXXCPP!$CXXCPP$ac_delim
 F77!$F77$ac_delim
 FFLAGS!$FFLAGS$ac_delim
@@ -27539,16 +26396,15 @@ REGEX!$REGEX$ac_delim
 REGEX_EXTENDED!$REGEX_EXTENDED$ac_delim
 OPENSSL_INCLUDE!$OPENSSL_INCLUDE$ac_delim
 OPENSSL_LIBS!$OPENSSL_LIBS$ac_delim
-PCAP_LIBS!$PCAP_LIBS$ac_delim
 LIBPREFIX!$LIBPREFIX$ac_delim
 CRYPTLIB!$CRYPTLIB$ac_delim
 SNMP_LIBS!$SNMP_LIBS$ac_delim
 SNMP_INCLUDE!$SNMP_INCLUDE$ac_delim
+GETCONF!$GETCONF$ac_delim
+LFS_CFLAGS!$LFS_CFLAGS$ac_delim
+LFS_LDFLAGS!$LFS_LDFLAGS$ac_delim
+LFS_LIBS!$LFS_LIBS$ac_delim
 HOSTINFO!$HOSTINFO$ac_delim
-LIBLTDL!$LIBLTDL$ac_delim
-INCLTDL!$INCLTDL$ac_delim
-subdirs!$subdirs$ac_delim
-MODULES!$MODULES$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -27590,6 +26446,10 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+LIBLTDL!$LIBLTDL$ac_delim
+INCLTDL!$INCLTDL$ac_delim
+subdirs!$subdirs$ac_delim
+MODULES!$MODULES$ac_delim
 INSTALLSTRIP!$INSTALLSTRIP$ac_delim
 USE_SHARED_LIBS!$USE_SHARED_LIBS$ac_delim
 USE_STATIC_LIBS!$USE_STATIC_LIBS$ac_delim
@@ -27601,7 +26461,7 @@ LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 13; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -27658,7 +26518,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF
 fi # test -n "$CONFIG_FILES"
 
 
-for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS
+for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS
 do
   case $ac_tag in
   :[FHLC]) ac_mode=$ac_tag; continue;;
@@ -27992,19 +26852,9 @@ echo "$as_me: $ac_file is unchanged" >&6;}
   rm -f "$tmp/out12"
  ;;
 
-  :C)  { echo "$as_me:$LINENO: executing $ac_file commands" >&5
-echo "$as_me: executing $ac_file commands" >&6;}
- ;;
-  esac
-
-
-  case $ac_file$ac_mode in
-    "stamp-h":C) echo timestamp > src/include/stamp-h ;;
-    "build-radpaths-h":C) (cd ./src/include && /bin/sh ./build-radpaths-h) ;;
-    "main-chmod":C) (cd ./src/main   && chmod +x checkrad.pl radlast radtest) ;;
-    "scripts-chmod":C) (cd ./scripts    && chmod +x rc.radiusd radwatch check-radiusd-config radiusd.cron.daily radiusd.cron.monthly cryptpasswd) ;;
 
   esac
+
 done # for ac_tag
 
 
@@ -28210,3 +27060,12 @@ echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
   done
 fi
 
+
+ac_config_commands="$ac_config_commands default-1"
+
+ac_config_commands="$ac_config_commands default-2"
+
+ac_config_commands="$ac_config_commands default-3"
+
+ac_config_commands="$ac_config_commands default-4"
+
index 6ae6aa7..30d5f11 100644 (file)
@@ -3,7 +3,7 @@ dnl #
 dnl #  For information about autoconf, see:
 dnl #
 dnl #  http://www.gnu.org/software/autoconf/
-dnl #
+dnl #  
 dnl #  The recommended order is:
 dnl #
 dnl #  AC_INIT(file)
@@ -20,17 +20,15 @@ dnl #  AC_OUTPUT([file...])
 dnl #
 dnl #############################################################
 
-AC_PREREQ([2.59])
-export CFLAGS LIBS LDFLAGS CPPFLAGS
 AC_INIT(src/main/radiusd.c)
 AC_CONFIG_HEADER(src/include/autoconf.h)
 AC_REVISION($Revision$)dnl
+AC_PREREQ([2.50])
 
 dnl # The version of the software
-RADIUSD_MAJOR_VERSION=2
-RADIUSD_MINOR_VERSION=0.0-pre1
+RADIUSD_MAJOR_VERSION=1
+RADIUSD_MINOR_VERSION=1.6
 RADIUSD_VERSION="${RADIUSD_MAJOR_VERSION}.${RADIUSD_MINOR_VERSION}"
-PACKAGE=freeradius
 
 dnl #############################################################
 dnl #
@@ -40,7 +38,6 @@ dnl #############################################################
 
 dnl Check for GNU cc
 AC_PROG_CC
-AC_PROG_CXX
 
 dnl #
 dnl # check for AIX, to allow us to use some BSD functions
@@ -52,8 +49,13 @@ AC_PROG_GCC_TRADITIONAL
 AC_PROG_CC_SUNPRO
 AC_PROG_RANLIB
 
-dnl Compile in large (2G+) file support.
-AC_SYS_LARGEFILE
+abs_top_builddir=`pwd`
+AC_SUBST(abs_top_builddir)
+
+dnl # autoconf 2.50 and later
+dnl # AC_SYS_LARGEFILE
+
+PACKAGE=freeradius
 
 dnl # check for system bytesex
 dnl # AC_DEFINES WORDS_BIGENDIAN
@@ -82,7 +84,7 @@ fi
 AC_SUBST(LTDL_SUBDIRS)
 
 dnl use system-wide libtool, if it exists
-AC_ARG_WITH(system-libtool,
+AC_ARG_WITH(system-libtool, 
 [  --with-system-libtool              try to use libtool installed in your system [default=use our own]],
 [ AC_PATH_PROG(LIBTOOL, libtool,,$PATH:/usr/local/bin) ],
 [
@@ -209,7 +211,7 @@ AC_ARG_WITH(ascend-binary,
   esac ]
 )
 if test "X$ASCEND_BINARY" = "Xyes"; then
-  AC_DEFINE(ASCEND_BINARY, [], [Include support for Ascend binary filter attributes])
+  AC_DEFINE(ASCEND_BINARY)
 fi
 
 dnl extra argument: --with-threads
@@ -236,6 +238,20 @@ AC_ARG_WITH(snmp,
   esac ]
 )
 
+dnl extra argument: --with-large-files
+rad_enable_largefiles=no
+AC_ARG_WITH(large-files,
+[  --with-large-files      Compile in large (2G+) file support. (default=no)],
+[ case "$withval" in
+    yes)
+        rad_enable_largefiles=yes
+       ;;
+    *)
+       ;;
+  esac ]
+)
+
+
 dnl #
 dnl #  Allow the user to specify a list of modules to be linked
 dnl #  statically to the server.
@@ -358,9 +374,9 @@ dnl AC_SUBST(INCLUDE)
 dnl AC_SUBST(IQUOTE)
 
 dnl extra argument: --with-udpfromto
-WITH_UDPFROMTO=yes
+WITH_UDPFROMTO=no
 AC_ARG_WITH(udpfromto,
-[  --with-udpfromto        Compile in UDPFROMTO support. (default=yes)],
+[  --with-udpfromto        Compile in UDPFROMTO support. (default=no)],
 [ case "$withval" in
     yes)
        WITH_UDPFROMTO=yes
@@ -371,9 +387,14 @@ AC_ARG_WITH(udpfromto,
 )
 
 if test "x$WITH_UDPFROMTO" = "xyes"; then
-       AC_DEFINE(WITH_UDPFROMTO, [], [define if you want udpfromto])
+       AC_DEFINE(WITH_UDPFROMTO)
 fi
 
+dnl extra argument: --with-edir
+dnl If using Novell eDirectory, enable UP and Novell specific code
+AC_ARG_WITH(edir,
+[  --with-edir             Enable Novell eDirectory integration.  (default=no) ] , [] )
+
 dnl #############################################################
 dnl #
 dnl #  1. Checks for programs
@@ -415,20 +436,20 @@ dnl #############################################################
 
 dnl If using pthreads, check for -lpthread (posix) or -lc_r (*BSD)
 old_CFLAGS=$CFLAGS
-if test "x$WITH_THREADS" = "xyes"; then
+if test "x$WITH_THREADS" = "xyes"; then 
   if test $ac_cv_prog_suncc = "yes"; then
     CFLAGS="$CFLAGS -mt"
   fi
 
   AC_CHECK_HEADERS(pthread.h, [], [ WITH_THREADS="no" ])
 
-dnl #
+dnl # 
 dnl # pthread stuff is usually in -lpthread
 dnl # or in -lc_r, on *BSD
-dnl #
+dnl # 
 dnl # On Some systems, we need extra pre-processor flags, to get them to
 dnl # to do the threading properly.
-dnl #
+dnl # 
   AC_CHECK_LIB(pthread, pthread_create,
                [ CFLAGS="$CFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS"
                   LIBS="$LIBS -lpthread" ],
@@ -439,9 +460,9 @@ dnl #
                )
 fi
 
-dnl #
+dnl # 
 dnl # If we have NO pthread libraries, remove any knowledge of threads.
-dnl #
+dnl # 
 if test "x$WITH_THREADS" != "xyes"; then
   CFLAGS=$old_CFLAGS
   ac_cv_header_pthread_h="no"
@@ -454,9 +475,8 @@ else
   dnl # HP/UX requires linking with librt, too, to get the sem_* symbols.
   dnl # Some systems have them in -lsem
   dnl # Solaris has them in -lposix4
-  dnl # NetBSD has them in -lsemaphore
 
-  AC_SEARCH_LIBS(sem_init, pthread sem posix4 rt semaphore,
+  AC_SEARCH_LIBS(sem_init, pthread sem posix4 rt,
        [],
        [AC_MSG_ERROR(-lsem not found.  You may want to download it from ftp://ftp.to.gd-es.com/pub/BSDI/libsem.tar.bz2 or ftp://ftp.freeradius.org/pub/radius/contrib/libsem.tar.gz)]
    )
@@ -495,17 +515,6 @@ AC_CHECK_LIB(crypto, DH_new,
     ], [])
 LIBS=$old_LIBS
 
-AC_CHECK_LIB(ws2_32, htonl)
-
-dnl Check the pcap library for the RADIUS sniffer.
-PCAP_LIBS=
-AC_CHECK_LIB(pcap, pcap_open_live,
-       [ PCAP_LIBS="-lpcap"
-       AC_DEFINE(HAVE_LIBPCAP, 1,
-               [Define to 1 if you have the `pcap' library (-lpcap).])
-       ],
-       [ AC_MSG_WARN([pcap library not found, silently disabling the RADIUS sniffer.]) ])
-
 dnl #############################################################
 dnl #
 dnl #  3. Checks for header files
@@ -515,8 +524,8 @@ dnl #############################################################
 dnl #
 dnl # Interix requires us to set -D_ALL_SOURCE, otherwise
 dnl # getopt will be #included, but won't link.  <sigh>
-dnl #
-dnl #
+dnl # 
+dnl # 
 case "$host" in
 *-interix*)
        CFLAGS="$CFLAGS -D_ALL_SOURCE"
@@ -536,7 +545,6 @@ AC_CHECK_HEADERS( \
        crypt.h \
        errno.h \
        resource.h \
-       sys/resource.h \
        getopt.h \
        malloc.h \
        utmp.h \
@@ -553,22 +561,20 @@ AC_CHECK_HEADERS( \
        netinet/in.h \
        sys/types.h \
        sys/socket.h \
-       winsock.h \
        sys/time.h \
        sys/wait.h \
        sys/security.h \
        fcntl.h \
        sys/fcntl.h \
-       net/if.h \
+       sys/stat.h \
+       sys/prctl.h \
        prot.h \
-       pwd.h \
-       grp.h \
        sia.h \
        siad.h
 )
 
 REGEX=no
-AC_CHECK_HEADER(regex.h, AC_DEFINE(HAVE_REGEX_H, [], [define this if we have the <regex.h> header file]))
+AC_CHECK_HEADER(regex.h, AC_DEFINE(HAVE_REGEX_H))
 if test "x$ac_cv_header_regex_h" = "xyes"; then
   REGEX_EXTENDED=no
   REGEX=yes
@@ -577,7 +583,7 @@ if test "x$ac_cv_header_regex_h" = "xyes"; then
      #ifdef REG_EXTENDED
        yes
      #endif
-     ], [AC_DEFINE(HAVE_REG_EXTENDED, [], [define this if we have REG_EXTENDED (from <regex.h>)]) REGEX_EXTENDED=yes])
+     ], [AC_DEFINE(HAVE_REG_EXTENDED) REGEX_EXTENDED=yes])
 fi
 AC_SUBST(REGEX)
 AC_SUBST(REGEX_EXTENDED)
@@ -587,18 +593,18 @@ dnl #  other checks which require headers
 dnl #
 if test "x$ac_cv_header_sys_security_h" = "xyes" && test "x$ac_cv_header_prot_h" = "xyes"
 then
-  AC_DEFINE(OSFC2, [], [define if you have OSFC2 authentication])
+  AC_DEFINE(OSFC2)
 fi
 
 if test "x$ac_cv_header_sia_h" = "xyes" && test "x$ac_cv_header_siad_h" = "xyes"
 then
-  AC_DEFINE(OSFSIA, [], [define if you have OSFSIA authentication])
+  AC_DEFINE(OSFSIA)
 fi
 
 dnl Check for OpenSSL includes.
 OPENSSL_INCLUDE="-DNO_OPENSSL"
 if test "x$OPENSSL_LIBS" = "x"; then
-    AC_MSG_NOTICE([skipping test for openssl/ssl.h])
+    AC_MSG_WARN([skipping test for openssl/ssl.h])
 else
     old_CPPFLAGS=$CPPFLAGS
     if test "x$OPENSSL_INCLUDE_DIR" != "x"; then
@@ -640,19 +646,6 @@ AC_SUBST(OPENSSL_INCLUDE)
 AC_SUBST(OPENSSL_LIBS)
 export OPENSSL_LIBS
 
-dnl Check the pcap includes for the RADIUS sniffer.
-if test "x$PCAP_LIBS" = x; then
-    AC_MSG_NOTICE([skipping test for pcap.h.])
-else
-    AC_CHECK_HEADER(pcap.h,
-       AC_DEFINE(HAVE_PCAP_H, 1,
-               [Define to 1 if you have the <pcap.h> header file.]),
-       [ PCAP_LIBS=
-       AC_MSG_WARN([pcap.h not found, silently disabling the RADIUS sniffer.])
-       ])
-fi
-AC_SUBST(PCAP_LIBS)
-
 dnl #############################################################
 dnl #
 dnl #  4. Checks for typedefs
@@ -662,83 +655,50 @@ dnl #############################################################
 dnl #
 dnl # Ensure that these are defined
 dnl #
-AC_TYPE_OFF_T
+AC_TYPE_OFF_T 
 AC_TYPE_PID_T
 AC_TYPE_SIZE_T
 AC_TYPE_UID_T
 
 dnl check for socklen_t
-FR_CHECK_TYPE_INCLUDE([
+AC_CHECK_TYPE_INCLUDE([
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
-],socklen_t, int, [socklen_t is generally 'int' on systems which don't use it])
+],socklen_t, int)
 
 dnl check for uint8_t
-FR_CHECK_TYPE_INCLUDE([
+AC_CHECK_TYPE_INCLUDE([
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif
-],uint8_t, unsigned char, [uint8_t should be the canonical 'octet' for network traffic])
+],uint8_t, unsigned char)
 
 dnl check for uint16_t
-FR_CHECK_TYPE_INCLUDE([
+AC_CHECK_TYPE_INCLUDE([
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif
-],uint16_t, unsigned short, [uint16_t should be the canonical '2 octets' for network traffic])
+],uint16_t, unsigned short)
 
 dnl check for uint32_t
-FR_CHECK_TYPE_INCLUDE([
+AC_CHECK_TYPE_INCLUDE([
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
 #endif
-],uint32_t, unsigned int, [uint32_t should be the canonical 'network integer])
-
-AC_CHECK_TYPE(struct in6_addr, AC_DEFINE(HAVE_STRUCT_IN6_ADDR, 1, [IPv6 address structure]), [], [
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-])
-
-AC_CHECK_TYPE(struct sockaddr_storage, AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, [Generic socket addresses]), [], [
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-])
-
-AC_CHECK_TYPE(struct sockaddr_in6, AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, [IPv6 socket addresses]), [], [
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-])
-
-AC_CHECK_TYPE(struct addrinfo, AC_DEFINE(HAVE_STRUCT_ADDRINFO, 1, [Generic DNS lookups]), [], [
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-])
+],uint32_t, unsigned int)
 
 dnl #############################################################
 dnl #
@@ -764,22 +724,19 @@ AC_CHECK_FUNCS( \
        inet_aton \
        inet_pton \
        inet_ntop \
+       gethostname \
        setlinebuf \
        setvbuf \
        getusershell \
        initgroups \
-       getaddrinfo \
-       getnameinfo \
-       closefrom \
-       gettimeofday \
-       strlcat \
-       strlcpy
+       closefrom
 )
 RADIUSD_NEED_DECLARATIONS( \
        crypt \
        strncasecmp \
        strcasecmp \
        inet_aton \
+       gethostname \
        setlinebuf \
        getusershell \
        endusershell
@@ -792,25 +749,18 @@ dnl # if so, check if struct utmpx has entry ut_xtime
 dnl # if not, set it to define ut_xtime == ut_tv.tv_sec
 if test "x$ac_cv_header_utmpx_h" = "xyes"
 then
FR_CHECK_STRUCT_HAS_MEMBER([#include <utmpx.h>], [struct utmpx], ut_xtime)
AC_CHECK_STRUCT_HAS_MEMBER([#include <utmpx.h>], [struct utmpx], ut_xtime)
  if test "x$ac_cv_type_struct_utmpx_has_ut_xtime" = "x"
  then
-   AC_DEFINE(ut_xtime,ut_tv.tv_sec, [define to something if you don't have ut_xtime in struct utmpx])
+   AC_DEFINE(ut_xtime,ut_tv.tv_sec)
  fi
 fi
 
 dnl # struct ip_pktinfo
-FR_CHECK_STRUCT_HAS_MEMBER([#include <netinet/in.h>], [struct in_pktinfo], ipi_addr)
+AC_CHECK_STRUCT_HAS_MEMBER([#include <netinet/in.h>], [struct in_pktinfo], ipi_addr)
 if test "x$ac_cv_type_struct_in_pktinfo_has_ipi_addr" = "xyes"
 then
-       AC_DEFINE(HAVE_IP_PKTINFO, [], [define if you have IP_PKTINFO (Linux)])
-fi
-
-dnl # struct in6_pktinfo
-FR_CHECK_STRUCT_HAS_MEMBER([#include <netinet/in.h>], [struct in6_pktinfo], ipi6_addr)
-if test "x$ac_cv_type_struct_in6_pktinfo_has_ipi6_addr" = "xyes"
-then
-       AC_DEFINE(HAVE_IN6_PKTINFO, [], [define if you have IN6_PKTINFO (Linux)])
+       AC_DEFINE(HAVE_IP_PKTINFO)
 fi
 
 dnl #############################################################
@@ -822,7 +772,7 @@ dnl #############################################################
 dnl #
 dnl # Ensure that these are defined
 dnl #
-AC_C_CONST
+AC_C_CONST 
 
 dnl #
 dnl # See if this is OS/2
@@ -869,9 +819,9 @@ AC_CHECK_LIB(crypt, crypt,
   CRYPTLIB="-lcrypt"
 )
 if test "$CRYPTLIB" != ""; then
-  AC_DEFINE(HAVE_CRYPT, [], [Do we have the crypt function])
+  AC_DEFINE(HAVE_CRYPT)
 else
-  AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT, [], [Do we have the crypt function]))
+  AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT))
 fi
 
 dnl Check for libcipher
@@ -886,11 +836,8 @@ fi
 
 dnl Check the style of gethostbyaddr, in order of preference
 dnl GNU (_r eight args)
-AC_DEFINE(GNUSTYLE, [1], [GNU-Style get*byaddr_r])
 dnl SYSV (_r six args)
-AC_DEFINE(SYSVSTYLE, [2], [SYSV-Style get*byaddr_r])
 dnl BSD (three args, may not be thread safe)
-AC_DEFINE(BSDSTYLE, [3], [BSD-Style get*byaddr_r])
 dnl Tru64 has BSD version, but it is thread safe
 dnl    http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V51B_HTML/MAN/MAN3/1739____.HTM
 dnl We need #stdio.h to define NULL on FreeBSD (at least)
@@ -898,7 +845,7 @@ gethostbyaddrrstyle=""
 AC_MSG_CHECKING([gethostbyaddr_r() syntax])
 case "$host" in
 *-freebsd*)
-       AC_DEFINE(GETHOSTBYADDRRSTYLE, BSDSTYLE, [style of gethostbyaddr_r functions ])
+       AC_DEFINE(GETHOSTBYADDRRSTYLE, BSDSTYLE)
        gethostbyaddrrstyle=BSD
        AC_MSG_WARN([FreeBSD overridden to BSD-style])
        ;;
@@ -908,7 +855,7 @@ if test "x$gethostbyaddrrstyle" = "x"; then
 #include <stdio.h>
 #include <netdb.h>
 ], [ gethostbyaddr_r(NULL, 0, 0, NULL, NULL, 0, NULL, NULL) ], [
-       AC_DEFINE(GETHOSTBYADDRRSTYLE, GNUSTYLE, [style of gethostbyaddr_r functions ])
+       AC_DEFINE(GETHOSTBYADDRRSTYLE, GNUSTYLE)
        gethostbyaddrrstyle=GNU
 ])
 fi
@@ -917,7 +864,7 @@ if test "x$gethostbyaddrrstyle" = "x"; then
 #include <stdio.h>
 #include <netdb.h>
 ], [ gethostbyaddr_r(NULL, 0, 0, NULL, NULL, 0, NULL) ] , [
-               AC_DEFINE(GETHOSTBYADDRRSTYLE, SYSVSTYLE, [style of gethostbyaddr_r functions ])
+               AC_DEFINE(GETHOSTBYADDRRSTYLE, SYSVSTYLE)
                gethostbyaddrrstyle=SYSV
        ])
 fi
@@ -926,7 +873,7 @@ if test "x$gethostbyaddrrstyle" = "x"; then
 #include <stdio.h>
 #include <netdb.h>
 ], [ gethostbyaddr(NULL, 0, 0)  ], [
-               AC_DEFINE(GETHOSTBYADDRRSTYLE, BSDSTYLE, [style of gethostbyaddr_r functions ])
+               AC_DEFINE(GETHOSTBYADDRRSTYLE, BSDSTYLE)
                gethostbyaddrrstyle=BSD
        ])
 fi
@@ -954,7 +901,7 @@ AC_TRY_LINK([
 #include <stdio.h>
 #include <netdb.h>
 ], [ gethostbyname_r(NULL, NULL, NULL, 0, NULL, NULL) ], [
-       AC_DEFINE(GETHOSTBYNAMERSTYLE, GNUSTYLE, [style of gethostbyname_r functions ])
+       AC_DEFINE(GETHOSTBYNAMERSTYLE, GNUSTYLE)
        gethostbynamerstyle=GNU
 ])
 if test "x$gethostbynamerstyle" = "x"; then
@@ -962,7 +909,7 @@ if test "x$gethostbynamerstyle" = "x"; then
 #include <stdio.h>
 #include <netdb.h>
 ], [ gethostbyname_r(NULL, NULL, NULL, 0, NULL) ] , [
-               AC_DEFINE(GETHOSTBYNAMERSTYLE, SYSVSTYLE, [style of gethostbyname_r functions ])
+               AC_DEFINE(GETHOSTBYNAMERSTYLE, SYSVSTYLE)
                gethostbynamerstyle=SYSV
        ])
 fi
@@ -971,7 +918,7 @@ if test "x$gethostbynamerstyle" = "x"; then
 #include <stdio.h>
 #include <netdb.h>
 ], [ gethostbyname(NULL)  ], [
-               AC_DEFINE(GETHOSTBYNAMERSTYLE, BSDSTYLE, [style of gethostbyname_r functions ])
+               AC_DEFINE(GETHOSTBYNAMERSTYLE, BSDSTYLE)
                gethostbynamerstyle=BSD
        ])
 fi
@@ -987,21 +934,19 @@ if test "x$gethostbynamerstyle" = "xBSD"; then
 fi
 
 dnl check for non-posix solaris ctime_r (extra buflen int arg)
-AC_DEFINE(POSIXSTYLE, [1], [Posix-Style ctime_r])
-AC_DEFINE(SOLARISSTYLE, [2], [Solaris-Style ctime_r])
 ctimerstyle=""
 AC_MSG_CHECKING([ctime_r() syntax])
 AC_TRY_LINK([
 #include <time.h>
 ], [ ctime_r(NULL, NULL, 0) ], [
-       AC_DEFINE(CTIMERSTYLE, SOLARISSTYLE, [style of ctime_r function])
+       AC_DEFINE(CTIMERSTYLE, SOLARISSTYLE)
        ctimerstyle="SOLARIS"
 ])
 if test "x$ctimerstyle" = "x"; then
        AC_TRY_LINK([
 #include <time.h>
 ], [ ctime_r(NULL, NULL) ], [
-               AC_DEFINE(CTIMERSTYLE, POSIXSTYLE, [style of ctime_r function])
+               AC_DEFINE(CTIMERSTYLE, POSIXSTYLE)
                ctimerstyle="POSIX"
        ])
 fi
@@ -1012,6 +957,64 @@ else
         AC_MSG_RESULT([${ctimerstyle}-style])
 fi
 
+
+dnl If configuring with large file support, determine the right flags to
+dnl use based on the platform.  This is the wrong approach; autoconf 2.50
+dnl comes with a macro that takes the right approach.  But this works well
+dnl enough until we switch to autoconf 2.50 or later.
+if test x"$rad_enable_largefiles" = xyes ; then
+    AC_MSG_CHECKING(for largefile linkage)
+    case "$host" in
+    *-aix4.[01]*)
+        AC_MSG_RESULT(no)
+        AC_MSG_ERROR([AIX before 4.2 does not support large files])
+        ;;
+    *-aix4*)
+        AC_MSG_RESULT(ok)
+        LFS_CFLAGS="-D_LARGE_FILES"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        ;;
+    *-hpux*)
+        AC_MSG_RESULT(ok)
+        LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        ;;
+    *-irix*)
+        AC_MSG_RESULT(no)
+        AC_MSG_ERROR([Large files not supported on this platform])
+        ;;
+    *-linux*)
+        AC_MSG_RESULT(maybe)
+        LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        AC_DEFINE([_GNU_SOURCE], 1,
+                  [Some versions of glibc need this defined for pread/pwrite.])
+        ;;
+    *-solaris*)
+        AC_MSG_RESULT(ok)
+        AC_PATH_PROG(GETCONF, getconf)
+        if test -z "$GETCONF" ; then
+            AC_MSG_ERROR([getconf required to configure large file support])
+        fi
+        LFS_CFLAGS=`$GETCONF LFS_CFLAGS`
+        LFS_LDFLAGS=`$GETCONF LFS_LDFLAGS`
+        LFS_LIBS=`$GETCONF LFS_LIBS`
+        ;;
+    *)
+        AC_MSG_RESULT(maybe)
+        LFS_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+        LFS_LDFLAGS=""
+        LFS_LIBS=""
+        ;;
+    esac
+    AC_SUBST(LFS_CFLAGS)
+    AC_SUBST(LFS_LDFLAGS)
+    AC_SUBST(LFS_LIBS)
+fi
+
 AC_SUBST(HOSTINFO, $host)
 
 dnl #############################################################
@@ -1038,17 +1041,17 @@ dnl #  Configure in any module directories.
 dnl #
 dnl #############################################################
 
-mysubdirs="$LIBLTDLPATH"
+mysubdirs=
 if test "x$EXPERIMENTAL" = "xyes"; then
-  bar=`ls -1 "${srcdir}"/src/modules/rlm_*/configure | sed 's%/configure%%'`
+  bar=`ls -1 src/modules/rlm_*/configure | sed 's%/configure%%'`
   dnl # get rid of LF's.
-  mysubdirs=`echo $mysubdirs $bar`
+  mysubdirs=`echo $bar`
 else
-  dnl #
+  dnl # 
   dnl # Find 'configure' in ONLY the stable modules
-  dnl #
-  for bar in `cat "${srcdir}"/src/modules/stable`; do
-    if test -f "${srcdir}"/src/modules/$bar/configure; then
+  dnl # 
+  for bar in `cat src/modules/stable`; do
+    if test -f src/modules/$bar/configure; then
       mysubdirs="$mysubdirs src/modules/$bar"
     fi
   done
@@ -1058,14 +1061,14 @@ dnl ############################################################
 dnl # make modules by list
 dnl #############################################################
 if test "x$EXPERIMENTAL" = "xyes"; then
-  for foo in `ls -1 "${srcdir}"/src/modules | grep rlm_`; do
+  for foo in `ls -1 src/modules | grep rlm_`; do
     MODULES="$MODULES $foo"
   done
 else
    dnl #
    dnl # make ONLY the stable modules
    dnl #
-   for foo in `cat "${srcdir}"/src/modules/stable`; do
+   for foo in `cat src/modules/stable`; do
     MODULES="$MODULES $foo"
    done
 fi
@@ -1083,11 +1086,6 @@ dnl #  And finally, output the results.
 dnl #
 dnl #############################################################
 
-AC_CONFIG_COMMANDS([stamp-h], [echo timestamp > src/include/stamp-h])
-AC_CONFIG_COMMANDS([build-radpaths-h], [(cd ./src/include && /bin/sh ./build-radpaths-h)])
-AC_CONFIG_COMMANDS([main-chmod], [(cd ./src/main   && chmod +x checkrad.pl radlast radtest)])
-AC_CONFIG_COMMANDS([scripts-chmod], [(cd ./scripts    && chmod +x rc.radiusd radwatch check-radiusd-config radiusd.cron.daily radiusd.cron.monthly cryptpasswd)])
-
 dnl #
 dnl #  Substitute whatever libraries we found to be necessary
 dnl #
@@ -1102,6 +1100,7 @@ AC_SUBST(STATIC_MODULES)
 AC_SUBST(RADIUSD_MAJOR_VERSION)
 AC_SUBST(RADIUSD_MINOR_VERSION)
 AC_SUBST(RADIUSD_VERSION)
+export CFLAGS LIBS
 
 AC_OUTPUT(\
        ./Make.inc \
@@ -1117,6 +1116,10 @@ AC_OUTPUT(\
        ./scripts/radiusd.cron.monthly \
        ./scripts/cryptpasswd \
        ./raddb/dictionary \
-       ./raddb/radiusd.conf \
-       ./raddb/radrelay.conf
+       ./raddb/radiusd.conf
 )
+
+AC_OUTPUT_COMMANDS([echo timestamp > src/include/stamp-h])
+AC_OUTPUT_COMMANDS([(cd ./src/include && /bin/sh ./build-radpaths-h)])
+AC_OUTPUT_COMMANDS([(cd ./src/main   && chmod +x checkrad.pl radlast radtest)])
+AC_OUTPUT_COMMANDS([(cd ./scripts    && chmod +x rc.radiusd radwatch check-radiusd-config radiusd.cron.daily radiusd.cron.monthly cryptpasswd)])
index 7b5f083..babf318 100644 (file)
@@ -1,8 +1,14 @@
-freeradius (2.0.0-pre0) unstable; urgency=low
+freeradius (1.1.6-0) unstable; urgency=low
 
-  * Current CVS version.
+  * New upstream release.
+
+ -- Alan DeKok <aland@freeradius.org>  Mon, 26 Mar 2007 14:57:03 +0100
+
+freeradius (1.1.5-0) unstable; urgency=low
+
+  * New upstream release.
 
- -- Nicolas Baradakis <nicolas.baradakis@cegetel.net>  Thu, 13 Jul 2006 16:41:06 +0200
+ -- Nicolas Baradakis <nicolas.baradakis@cegetel.net>  Tue,  6 Mar 2007 23:52:55 +0100
 
 freeradius (1.1.3-0) unstable; urgency=low
 
index a9d00a2..5877fe1 100644 (file)
@@ -44,5 +44,5 @@ rlm_x99_token
 Also, the FreeRADIUS core's SNMP support and the rlm_sql_postgresql
 module transitively depend on OpenSSL via libsnmp{4.2,5} and libpq3
 so they cannot be enabled currently, but this is subject to changes
-in the relevant packages within Debian, or having usable alternate
+in the relevant packages within Debian, or having useable alternate
 libraries in Debian.
diff --git a/debian/freeradius-dialupadmin.dirs b/debian/freeradius-dialupadmin.dirs
deleted file mode 100644 (file)
index 811a901..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-etc/freeradius-dialupadmin/
-usr/share/freeradius-dialupadmin/
diff --git a/debian/freeradius-dialupadmin.docs b/debian/freeradius-dialupadmin.docs
deleted file mode 100644 (file)
index 4083a94..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-dialup_admin/README
-dialup_admin/doc/*
diff --git a/debian/freeradius-dialupadmin.examples b/debian/freeradius-dialupadmin.examples
deleted file mode 100644 (file)
index 5c627ca..0000000
+++ /dev/null
@@ -1 +0,0 @@
-dialup_admin/bin/dialup_admin.cron
diff --git a/debian/freeradius-dialupadmin.links b/debian/freeradius-dialupadmin.links
deleted file mode 100644 (file)
index 8c2e29e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-etc/freeradius-dialupadmin/ usr/share/freeradius-dialupadmin/conf
index e39a366..5511cf1 100755 (executable)
@@ -8,6 +8,8 @@
 # Required-Stop:
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
+# Short-Description: Radius Daemon 
+# Description:       Extensible, configurable radius daemon
 ### END INIT INFO
 
 PROG="freeradius"
index 600a0da..fef9d88 100644 (file)
-Ver 1.80:
-* Remove snmp_clearsession. It is replaced by clearsession which supports both snmp and telnet
-  methods of removing a user from an access server. Add corresponding configuration directives
-  general_sessionclear_method and nasXX_sessionclear_method
-* Create a new function da_sql_limit() and use that to pass LIMIT arguments to the database layer
-  since the syntax is different between db vendors
-* Rename the badusers date field to incidentdate to avoid reserved words in databases. Bug found by
-  Peter Nixon
-* Count online users correctly (through a separate query) in user_finger.
-* Use the correct max results variable in lib/*/find.php3
-* In time2strclock also show days if applicable
-* In lib/sql/attrmap.php3, only register variables once. Go through $show_attrs and set default attribute
-  mappings for any attribute that a mapping does not exist.
-* Change the order of OID's used in snmpfinger for cisco NASes
-Ver 1.78:
-* Add a snmp_clearsession which can disconnect a user by using the Cisco AAA Session MIB
-* Add a configuration directive general_sessionclear_bin
-* Add a session disconnect button in the 'clear open sessions' page
-* Also clear sessions from the sql extra servers in the 'clear open sessions' page
-* In bin/snmpfinger also accept @,. in the username
-* If we are stripping realms, then if needed strip them from the data returned by snmpfinger in
-  user_finger.php3
-* Add a header with the page encoding before sending any page (header added in config.php3)
-  This closes Bug #153
-* Fix a problem when reading username.mappings
-* If date calculation fails, abort
-* Add a backup_radacct script
-* Add an sqlrelay functions file. The user_admin page does not currently work. Looking into it.
-* Add sqlrelay support in the scripts. Add a sqlrelay_query script to run sqlrelay commands
-* Update password_check to work with all password attributes and use the configuration directives
-* Add more documentation for per user counter limit attributes (daily/weekly/monthly limits)
-* Make all counter limits default to none so that people don't get confused
-* In clear_opensessions depending on sql type use either IS NULL or = 0 in the DELETE statement.
-  We need to find a cleaner solution to this. This closes bug#175
-* Log somewhat more verbose error messages when the sql_command binary is not found in the bin scripts
-* Make nasXX_finger_type actually work since the place where nas information was stored was changed a
-  long time ago. Bug noted by Nick Bright
-* In user_finger only set LD_LIBRARY_PATH once, not each time we call snmpfinger
-* Add support for usrhiper in snmpfinger. Patch from Nick Bright
-* urlencode() all occurrences of the $login variable when used in url's. Bug noted by Dag Landau
-* Show the correct nas type in nas_admin. Bug noted by Nick Bright
-* Correctly calculate the nas ip in lib/sql/nas_list.php3. Add a check_ip() function in lib/functions.php3
-  Bug noted by Nick Bright
-* Correctly check nas validity in nas_admin.php3. Bug noted by Nick Bright
-* Don't use $num in stats.php3, change it to $stats_num
-Ver 1.75:
-* A LOT of security related fixes. Now dialupadmin should hopefully be secure enough to
-  be accessed by normal users (not administrators).
-* Move a few elements in the CSS file from the body tag. Suggestion by Gary McKinney
-* Update FAQ about using php with no sql support.
-* Allow the user to select between viewing FAQ,HOWTO or README in the help page.
-* Use $_SERVER instead of $HTTP_SERVER_VARS
-* Add a drop down menu with existing groups in group_new.php3
-* Check for sql in show_groups.php3
-* In lib/sql/group_info.php3 if $login is not set, find available groups and place them in
-  $existing_groups along with a count of users per group. Use the functionality in group_new.php3
-  and show_groups.php3
-* Update TODO
-* Add the style sheet in the content.html
-* Enlarge the width for the left frame
-* Make show_groups and the drop down menu in group_new work
-* Use lower cased row names in badusers page
-* Wrong foreach in show_groups and group_new.
-* Fix operator escaping in lib/sql/change_attrs.php3
-* In user_state also take into account any open sessions when calculating daily/weekly usage.
-  Add two more lines in the output stating the number of current open sessions and the time used.
-* Move a few header() calls after including config.php3 so that we have access to the relevant
-  variables.
-* Make pagesize 'all' work again. Bug found by apellido jr., wilfredo p.
-* Make 'Add NAS' function in the nas admin page more easily accessible
-* Fix a small bug in user_admin.php3 found by Joerg Staedele
-* Fix a small typo in the userinfo mysql schema. Found by Evert Meulie
-* Fix bug #136, bugs found by Pawel Foremski
-* Small type in login_time_create, close bug #141
-* In config.php3 remove whitespaces from $login. Don't remove '-'
-* Add lib/sql/group_change.php3 to add and delete a user from groups
-* Add a new directive sql_show_all_groups. If set to true then in user edit page we show all available
-  groups with the ones the user is a member of highlighted. The administrator can then directly
-  change user group membership by changing membership in this group list.
-* On group creation, if member list is empty report that, not that the group was created.
-* In the show groups page, note that we only show groups with members
-* In lib/sql/group_info.php3 only unset variables if we need to. In lib/sql/defaults.php3 don't run for groups
-  only for users
-* Fix Bug #167
-Ver 1.72:
-* Move the xlat function to a separate file in lib/xlat.php3
-* Add a lib/sql/nas_list.php3 to also get the nas list from sql (naslist.conf still works)
-* add realms nasdb and nasadmin in username.mappings. nasadmin is used to signify if the
-  user is allowed to use the nas_admin page. nasdb is used to shorten the nas list to only
-  a few specific entries. That way administrator responsible for a few access servers will
-  only be able to administer those access servers and not see the rest of the nas list.
-* Add username searching in the find page as suggested by joram agten
-* Don't use nas_list in nas_admin
-* Add postgresql specific sql schema by apellido jr., wilfredo p. Move each sql schema to a
-  separate directory (mysql and postgresql)
-* Change is_int to is_numeric. This closes Bug #90
-* Escape special characters in the sql password. This closes bug #96
-* Do an xlat for general_accounting_attrs_file and general_user_edit_attrs_file. That way we can
-  have different mappings for each administrator.
-* Use require_once instead of require when including xlat.php3
-* Add debug statements in sql connect functions
-* Add a missing.php3 file with functions that may be missing from the PHP version used. Include it
-  if a function is missing. Currently only array_change_key_case() is included
-* Set general_restrict_nasadmin_access to no by default. It causes confusion.
-* Set the general_username_mappings_file variable
-* Fix a small error in lib/sql/find.php3. This closes bug #103
-* Add a small note in the FAQ about checking for sql/ldap driver availability in PHP if the user get's
-  a blank white page back.
+Ver 1.70.3:
+* Test for unset variable, rather than empty variable in clean_radacct,
+  monthly_tot_stats and truncate_radacct.
+
+Ver 1.70.2:
+* Fix redirects in dialup-admin pages on servers with register_globals
+  turned off.
+* HTTP form fields will always fail is_int, use in_numeric instead.
+
+Ver 1.70.1:
+* Report correct data transfer statistics for users
+* Lower-case sql column names to match creation scripts
+* Fix creation of empty groups
+* Put quote around usernames in HTML output
+* Properly notice when we've got a blank password to SQL
+
 Ver 1.70:
 * Add the /bin postgresql compatibility patch from Guy Fraser
 * Add ldap_userdn as a configuration directive. If set we use that for
index 2ea2678..e5f08bd 100644 (file)
@@ -84,8 +84,7 @@ htdocs:: user_state.php3 =>
        overview of the status of a user. It will return the following fields
        separated by new lines:
        account_status(active or inactive),lock message,weekly limit,daily limit,
-       weekly used,weekly connections,daily used,daily connections,
-       active sessions number,active sessions time
+       weekly used,weekly connections,daily used,daily connections
 htdocs:: user_finger.php3 =>
        It will finger the nas(es) and show the logged in users. If an argument server is passed then
        it will only show users for the specific access server.
diff --git a/dialup_admin/bin/backup_radacct b/dialup_admin/bin/backup_radacct
deleted file mode 100755 (executable)
index 1918a49..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/perl
-use POSIX;
-
-$conf=shift||'/data/local/dialupadmin/conf/admin.conf';
-$back_days = 80;
-$backup_directory = "/logs/radiusd/accounting";
-
-open CONF, "<$conf"
-       or die "Could not open configuration file\n";
-while(<CONF>){
-       chomp;
-       ($key,$val)=(split /:\s*/,$_);
-       $sql_server = $val if ($key eq 'sql_server');
-       $sql_type = $val if ($key eq 'sql_type');
-       $sql_port = $val if ($key eq 'sql_port');
-       $sql_username = $val if ($key eq 'sql_username');
-       $sql_password = $val if ($key eq 'sql_password');
-       $sql_database = $val if ($key eq 'sql_database');
-       $sql_accounting_table = $val if ($key eq 'sql_accounting_table');
-       $sqlcmd = $val if ($key eq 'sql_command');
-}
-close CONF;
-
-die "sql_command directive is not set in admin.conf\n" if ($sqlcmd eq '');
-die "sql command '$sqlcmd' not found or does not seem to be executable\n" if (! -x $sqlcmd);
-if ($sql_type eq 'mysql'){
-       $sql_password = ($sql_password eq '') ? '' : "-p$sql_password";
-}
-$sql_password =~ s/(\W)/\\$1/g;
-
-($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
-$date = POSIX::strftime("%Y-%m-%d",$sec,$min,$hour,($mday - ($back_days - 1)),$mon,$year,$wday,$yday,$isdst);
-$date2 = POSIX::strftime("%Y-%m-%d",$sec,$min,$hour,($mday - ($back_days + 1)),$mon,$year,$wday,$yday,$isdst);
-$date3 = POSIX::strftime("%Y%m%d",$sec,$min,$hour,($mday - $back_days),$mon,$year,$wday,$yday,$isdst);
-if (POSIX::strftime("%Y-%m-%d %T",localtime) eq $date){
-       die "Could not set correct back date.\n";
-}
-
-$query = "SELECT * FROM $sql_accounting_table WHERE AcctStopTime < '$date' AND AcctStopTime > '$date2';";
-print "$query\n";
-open TMP, ">/tmp/backup_radacct.query"
-       or die "Could not open tmp file\n";
-print TMP "ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';\n" if ($sql_type eq 'oracle');
-print TMP $query;
-close TMP;
-$comm = "$sqlcmd -B -h $sql_server -u $sql_username $sql_password $sql_database </tmp/backup_radacct.query >$backup_directory/$date3" if ($sql_type eq 'mysql');
-$comm = "$sqlcmd  -U $sql_username -f /tmp/backup_radacct.query $sql_database >$backup_directory/$date3" if ($sql_type eq 'pg');
-$command = "$sqlcmd  $sql_username/$pass" . "@" . "$sql_database <$tmpfile.$server" if ($sql_type eq 'oracle');
-$command = "$sqlcmd '$sql_server' '$sql_port' '' '$sql_username' '$sql_password' </tmp/backup_radacct.query >$backup_directory/$date3" if ($sql_type eq 'sqlrelay');
-`$comm`;
-`/usr/local/bin/gzip -9 $backup_directory/$date3`;
index 168af3f..a2a1ef3 100755 (executable)
@@ -26,19 +26,13 @@ while(<CONF>){
 close CONF;
 
 die "sql_command directive is not set in admin.conf\n" if ($sqlcmd eq '');
-die "sql command '$sqlcmd' not found or does not seem to be executable\n" if (! -x $sqlcmd);
+die "Could not find sql binary. Please make sure that the \$sqlcmd variable points to the right location\n" if (! -x $sqlcmd);
 
-if ($sql_type eq 'mysql'){
-       $sql_password = ($sql_password eq '') ? '' : "-p$sql_password";
-}
-$sql_password =~ s/(\W)/\\$1/g;
+$sql_password = (!$sql_password) ? '' : "-p$sql_password";
 
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
 $date = POSIX::strftime("%Y-%m-%d %T",$sec,$min,$hour,($mday - $back_days),$mon,$year,$wday,$yday,$isdst);
 print "$date\n";
-if (POSIX::strftime("%Y-%m-%d %T",localtime) eq $date){
-       die "Could not set correct back date.\n";
-}
 
 $query = "DELETE FROM $sql_accounting_table WHERE AcctStopTime IS NULL AND AcctStartTime < '$date';";
 print "$query\n";
@@ -48,5 +42,4 @@ print TMP $query;
 close TMP;
 $command = "$sqlcmd -h$sql_server -u$sql_username $sql_password $sql_database </tmp/clean_radacct.query" if ($sql_type eq 'mysql');
 $command = "$sqlcmd  -U $sql_username -f /tmp/clean_radacct.query $sql_database" if ($sql_type eq 'pg');
-$command = "$sqlcmd '$sql_server' '$sql_port' '' '$sql_username' '$sql_password' </tmp/clean_radacct.query" if ($sql_type eq 'sqlrelay');
 `$command`;
diff --git a/dialup_admin/bin/clearsession b/dialup_admin/bin/clearsession
deleted file mode 100755 (executable)
index 35060d7..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/perl
-
-$login = 'nas-login';
-$passwd = 'nas-password';
-
-$host=shift || '';
-$type = shift || 'snmp';
-$nastype = shift || 'cisco';
-$username=shift || '';
-$sessionid = shift || '';
-
-$port = 0;
-$comm = '';
-
-if ($type eq 'snmp'){
-$comm = shift || 'public';
-}
-if ($type eq 'telnet'){
-$port = shift || 0;
-}
-
-
-die "No \$host argument given\n" if ($host eq '');
-die "No \$username argument given\n" if ($username eq '');
-
-if ($nastype eq 'cisco' && $type eq 'telnet'){
-       die "Usage: clearsession \$host telnet cisco \$username \$sessionid \$port\n" if ($port  == 0);
-
-       if (eval require Net::Telnet::Cisco){
-               Net::Telnet::Cisco->import();
-
-               my $session = Net::Telnet::Cisco->new(Host => $host);
-               $session->login($login, $passwd);
-
-               if ($port >= 20000){
-                       my @output = $session->cmd("sh caller user $username");
-                       foreach $line (@output){
-                               if ($line =~ /User: $username, line (Vi\d+),/){
-                                       $session->cmd("clear interface $1");
-                               }
-                       }
-               }
-               else{
-                       $session->cmd("clear line $port\n");
-               }
-
-               $session->close;
-       }
-}
-if ($nastype eq 'cisco' && $type eq 'snmp'){
-
-       $SNMPGET="/usr/local/bin/snmpget";
-       $SNMPSET="/usr/local/bin/snmpset";
-
-       die "Could not find snmpwalk binary. Please make sure that the \$SNMPGET variable points to the right location\n" if (! -x $SNMPGET);
-       die "Could not find snmpset binary. Please make sure that the \$SNMPSET variable points to the right location\n" if (! -x $SNMPSET);
-       die "Usage: clearsession \$host snmp \$username cisco \$sessionid \$community\n" if ($sessionid eq '' || $comm eq '');
-
-       if ($sessionid ne '' && $username ne ''){
-               print "$SNMPGET -v2c -c $comm $host .iso.org.dod.internet.private.enterprises.9.9.150.1.1.3.1.2.$sessionid\n";
-               $walk =`$SNMPGET -v2c -c $comm $host .iso.org.dod.internet.private.enterprises.9.9.150.1.1.3.1.2.$sessionid`;
-               unless ($walk =~ /^$/){
-                       if ($walk =~ /$username/){
-                               print "FOUND: $username\n";
-               `$SNMPSET -v2c -c $comm $host .iso.org.dod.internet.private.enterprises.9.9.150.1.1.3.1.5.$sessionid i 1`;
-                       }
-               }
-       }
-}
index 402b28b..b3bfbb4 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 #
 # Log failed logins in the sql database
-# Works with mysql, postgresql and Oracle
+# Works with mysql and postgresql
 # It will read the sql parameters from the admin.conf file
 #
 # Usage:
@@ -9,7 +9,7 @@
 #
 # Defaults:
 # radius.log: none
-# admin.conf: /usr/local/dialup_admin/conf/admin.conf
+# admin.conf: /usr/local/dialup_admin/conf/admin.conf 
 # all:        no. Go to the end of the file. Don't read it all.
 
 use Date::Manip qw(ParseDate UnixDate);
@@ -31,7 +31,6 @@ $all_file=shift||'no';
 #$regexp = 'from client localhost port 135|from client blabla ';
 $tmpfile='/var/tmp/sql.input';
 #
-$verbose = 0;
 #
 
 open CONF, "<$conf"
@@ -94,17 +93,11 @@ close CLIENTS;
 
 $realm_del = '@' if ($realm_del eq '');
 $realm_for = 'suffix' if ($realm_for eq '');
-if ($sql_type eq 'mysql'){
-       $pass = ($sql_password ne '') ? "-p$sql_password" : '';
-}
-else{
-       $pass = $sql_password;
-}
-$pass =~ s/(\W)/\\$1/g;
+$pass = (!$sql_password) ? '' : "-p$sql_password";
 die "SQL server not defined\n" if ($sql_server eq '');
 
 die "sql_command directive is not set in admin.conf\n" if ($sqlcmd eq '');
-die "sql command '$sqlcmd' not found or does not seem to be executable\n" if (! -x $sqlcmd);
+die "Could not find sql binary. Please make sure that the \$sqlcmd variable points to the right location\n" if (! -x $sqlcmd);
 
 $opt = "";
 $opt = "-O connect_timeout=$sql_timeout" if ($sql_timeout);
@@ -114,13 +107,11 @@ unshift @servers, $sql_server;
 
 open LOG, "<$file"
        or die "Could not open file $file\n";
-if ($verbose > 1) { print STDOUT "DEBUG: Opened $file\n" }
 
 seek LOG, 0, 2 if ($all_file eq 'no');
 for(;;){
        while(<LOG>){
-               if ($verbose > 1) { print STDOUT "DEBUG: Reading $file\n" }
-               $do=0;
+               $do=0;  
                chomp;
                next if ($regexp ne '' && !/$regexp/);
                if ($_ ne ''){
@@ -128,10 +119,8 @@ for(;;){
                        if (/Login incorrect/){
                                if (/Login incorrect \((.+?)\):/){
                                        $cause = "Login-Incorrect ($1)";
-                                       if ($verbose > 1) { print STDOUT "DEBUG: Login-Incorrect ($1)\n" }
                                }else{
                                        $cause='Login-Incorrect';
-                                       if ($verbose > 1) { print STDOUT "DEBUG: Login-Incorrect\n" }
                                }
                                $do=1;
                        }
@@ -198,21 +187,16 @@ for(;;){
                                        $ctx->add($time);
                                        $ctx->add('badlogin');
                                        $uniqueid = $ctx->hexdigest;
-                                       print TMP "ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';\n" if ($sql_type eq 'oracle');
 #DEBUG#                                        print "INSERT INTO $sql_accounting_table (UserName,AcctUniqueId,NASIPAddress,NASPortId,AcctStartTime,AcctStopTime,AcctSessionTime,AcctInputOctets,AcctOutputOctets,CallingStationId,AcctTerminateCause) VALUES ('$user','$uniqueid','$addr','$port','$time','$time','0','0','0','$caller','$cause');\n";
-                                       print TMP "INSERT INTO $sql_accounting_table (UserName,AcctSessionId,AcctUniqueId,NASIPAddress,NASPortId,AcctStartTime,AcctStopTime,AcctSessionTime,AcctInputOctets,AcctOutputOctets,CallingStationId,AcctTerminateCause) VALUES ('$user','$uniqueid','$uniqueid','$addr','$port','$time','$time','0','0','0','$caller','$cause');\n";
+                                       print TMP "INSERT INTO $sql_accounting_table (UserName,AcctUniqueId,NASIPAddress,NASPortId,AcctStartTime,AcctStopTime,AcctSessionTime,AcctInputOctets,AcctOutputOctets,CallingStationId,AcctTerminateCause) VALUES ('$user','$uniqueid','$addr','$port','$time','$time','0','0','0','$caller','$cause');\n";
                                        close TMP;
                                        $command = "$sqlcmd -h$server $opt -u$sql_username $pass $sql_database <$tmpfile.$server" if ($sql_type eq 'mysql');
                                        $command = "$sqlcmd  -U $sql_username -f $tmpfile.$server $sql_database" if ($sql_type eq 'pg');
-                                       $command = "$sqlcmd  $sql_username/$pass" . "@" . "$sql_database <$tmpfile.$server" if ($sql_type eq 'oracle');
-                                       $command = "$sqlcmd '$server' '$sql_port' '' '$sql_username' '$sql_pass' <$tmpfile.$server" if ($sql_type eq 'sqlrelay');
-                                       if ($verbose > 1) { print STDOUT "DEBUG: Sending datafile $tmpfile.$server to \"$sql_type\" database\n" }
                                        `$command`;
-                                       if ($verbose > 1) { print STDOUT "DEBUG: Sent data to \"$sql_type\" database\n" }
 
                                        $exit = $? >> 8;
                                        $delete{$server} = ($exit == 0) ? 1 : 0;
-                                       print STDERR "ERROR: SQL query failed for host $server\n" if ($exit != 0);
+                                       print "ERROR: SQL query failed for host $server\n" if ($exit != 0);
                                }
                        }
                }
index 38ffcab..79f1cba 100755 (executable)
@@ -27,12 +27,9 @@ while(<CONF>){
 close CONF;
 
 die "sql_command directive is not set in admin.conf\n" if ($sqlcmd eq '');
-die "sql command '$sqlcmd' not found or does not seem to be executable\n" if (! -x $sqlcmd);
+die "Could not find sql binary. Please make sure that the \$sqlcmd variable points to the right location\n" if (! -x $sqlcmd);
 
-if ($sql_type eq 'mysql'){
-       $sql_password = ($sql_password eq '') ? '' : "-p$sql_password";
-}
-$sql_password =~ s/(\W)/\\$1/g;
+$sql_password = (!$sql_password) ? '' : "-p$sql_password";
 
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
 if ($mday == 1){
@@ -53,12 +50,9 @@ print "$query1\n";
 print "$query2\n";
 open TMP, ">/tmp/tot_stats.query"
        or die "Could not open tmp file\n";
-print TMP "ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';\n" if ($sql_type eq 'oracle');
 print TMP $query1;
 print TMP $query2;
 close TMP;
 $command = "$sqlcmd -h $sql_server -u $sql_username $sql_password $sql_database </tmp/tot_stats.query" if ($sql_type eq 'mysql');
 $command = "$sqlcmd  -U $sql_username -f /tmp/tot_stats.query $sql_database" if ($sql_type eq 'pg');
-$command = "$sqlcmd  $sql_username/$pass" . "@" . "$sql_database <$tmpfile.$server" if ($sql_type eq 'oracle');
-$command = "$sqlcmd '$sql_server' '$sql_port' '' '$sql_username' '$sql_password' </tmp/tot_stats.query" if ($sql_type eq 'sqlrelay');
 `$command`;
index 5804057..08c73e5 100755 (executable)
@@ -53,7 +53,7 @@ if ($snmp_type = 'net') {
        "v90",
        "v27ter",
 );
-
+                 
 @Protocol = (
        "error",
        "normal",
@@ -66,7 +66,7 @@ if ($snmp_type = 'net') {
        "ara20",
        "unknown",
 );
-#DEBUG#print "$snmpwalkcmd enterprises.9.2.9.2.1.18 | grep $user\n";
+#DEBUG#print "$snmpwalkcmd enterprises.9.2.9.2.1.18 | grep $user\n";            
 $modem=`$snmpwalkcmd enterprises.9.2.9.2.1.18 | grep $user`;
 if($modem=~/enterprises\.9\.2\.9\.2\.1\.18\.(\d+) =/){
   $modem=$1;
@@ -74,32 +74,32 @@ if($modem=~/enterprises\.9\.2\.9\.2\.1\.18\.(\d+) =/){
   $port=$modem%120-1;
   $modem="$slot.$port";
 
-#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.9.$modem\n";
+#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.9.$modem\n";               
   $duration=`$snmpgetcmd enterprises.9.9.47.1.3.1.1.9.$modem` or die "No MIB\n";
   $duration=~/\) (.*)\./;
   $duration=$1;
 
-#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.12.$modem\n";
+#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.12.$modem\n";              
   $modulation=`$snmpgetcmd enterprises.9.9.47.1.3.1.1.12.$modem` or die "No MIB\n";
   $modulation=~/ \= (\d+)/;
   $modulation=$ModulationScheme[$1];
 
-#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.13.$modem\n";
+#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.13.$modem\n";              
   $protocol=`$snmpgetcmd enterprises.9.9.47.1.3.1.1.13.$modem` or die "No MIB\n";
   $protocol=~/ \= (\d+)/;
   $protocol=$Protocol[$1];
 
-#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.14.$modem\n";
+#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.14.$modem\n";              
   $txrate=`$snmpgetcmd enterprises.9.9.47.1.3.1.1.14.$modem` or die "No MIB\n";
   $txrate=~/Gauge32\: (\d+)/;
   $txrate=$1;
 
-#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.15.$modem\n";
+#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.15.$modem\n";              
   $rxrate=`$snmpgetcmd enterprises.9.9.47.1.3.1.1.15.$modem` or die "No MIB\n";
   $rxrate=~/Gauge32\: (\d+)/;
   $rxrate=$1;
 
-#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.17.$modem\n";
+#DEBUG#print "$snmpgetcmd enterprises.9.9.47.1.3.1.1.17.$modem\n";              
   $rxsignal=`$snmpgetcmd enterprises.9.9.47.1.3.1.1.17.$modem` or die "No MIB\n";
 #  $rxsignal=~ s/INTEGER\://;
   $rxsignal=~/ \= (.*)\n/;
index 5fd04a0..68a7cad 100755 (executable)
@@ -25,21 +25,16 @@ $snmpwalkcmd="$snmpwalk -v 1 -c $comm $host" if ($snmp_type = 'net');
 
 if ($type eq 'cisco'){
        $walk =`$snmpwalkcmd  .iso.org.dod.internet.private.enterprises.9.9.150.1.1.3.1.2`;
-       if ($walk =~ /^$/ || $walk =~ /No Such Object/){
-               $walk =`$snmpwalkcmd .iso.org.dod.internet.private.enterprises.9.10.19.1.3.1.1.3`;
-               if ($walk =~ /^$/ || $walk =~ /No Such Object/){
-                       $walk =`$snmpwalkcmd .iso.org.dod.internet.private.enterprises.9.2.9.2.1.18`;
-               }
+       if ($walk =~ /^$/){
+               $walk =`$snmpwalkcmd .iso.org.dod.internet.private.enterprises.9.2.9.2.1.18`;
+               $walk.=`$snmpwalkcmd .iso.org.dod.internet.private.enterprises.9.10.19.1.3.1.1.3`;
        }
 }
 elsif ($type eq 'lucent'){
        $walk =`$snmpwalkcmd .iso.org.dod.internet.private.enterprises.529.10.4.1.12`;
 }
-elsif ($type eq 'usrhiper'){
-       $walk =`$snmpwalkcmd .iso.org.dod.internet.private.enterprises.429.4.10.1.1.18`;
-}
 
-while($walk=~/\"([\@\.\w\-]+?)\"/g){
+while($walk=~/\"([\w\-]+?)\"/g){
  $user=lc($1);
  if($out) {
   $out=$out.",'$user'";
diff --git a/dialup_admin/bin/sqlrelay_query b/dialup_admin/bin/sqlrelay_query
deleted file mode 100755 (executable)
index 20704e7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/perl
-$sqlrelay = '/usr/bin/query';
-$host=shift;
-$port=shift;
-$socket=shift;
-$user=shift;
-$passwd=shift;
-while(<>){
-       chomp;
-       `$sqlrelay '$host' '$port' '$socket' '$user' '$passwd' '$_'`;
-       $exit = $? >> 8;
-       if ($exit != 0){
-               exit $exit;
-       }
-}
index f5659e7..193364c 100755 (executable)
@@ -26,12 +26,9 @@ while(<CONF>){
 close CONF;
 
 die "sql_command directive is not set in admin.conf\n" if ($sqlcmd eq '');
-die "sql command '$sqlcmd' not found or does not seem to be executable\n" if (! -x $sqlcmd);
+die "Could not find sql binary. Please make sure that the \$sqlcmd variable points to the right location\n" if (! -x $sqlcmd);
 
-if ($sql_type eq 'mysql'){
-       $sql_password = ($sql_password eq '') ? '' : "-p$sql_password";
-}
-$sql_password =~ s/(\W)/\\$1/g;
+$sql_password = (!$sql_password) ? '' : "-p$sql_password";
 
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
 $date_start = POSIX::strftime("%Y-%m-%d %T",0,0,0,($mday - 1),$mon,$year,$wday,$yday,$isdst);
@@ -50,12 +47,9 @@ print "$query1\n";
 print "$query2\n";
 open TMP, ">/tmp/tot_stats.query"
        or die "Could not open tmp file\n";
-print TMP "ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';\n" if ($sql_type eq 'oracle');
 print TMP $query1;
 print TMP $query2;
 close TMP;
 $command = "$sqlcmd -h $sql_server -u $sql_username $sql_password $sql_database </tmp/tot_stats.query" if ($sql_type eq 'mysql');
 $command = "$sqlcmd  -U $sql_username -f /tmp/tot_stats.query $sql_database" if ($sql_type eq 'pg');
-$command = "$sqlcmd  $sql_username/$pass" . "@" . "$sql_database <$tmpfile.$server" if ($sql_type eq 'oracle');
-$command = "$sqlcmd '$sql_server' '$sql_port' '' '$sql_username' '$sql_password' </tmp/tot_stats.query" if ($sql_type eq 'sqlrelay');
 `$command`;
index 09f9193..278b910 100755 (executable)
@@ -26,19 +26,13 @@ while(<CONF>){
 close CONF;
 
 die "sql_command directive is not set in admin.conf\n" if ($sqlcmd eq '');
-die "sql command '$sqlcmd' not found or does not seem to be executable\n" if (! -x $sqlcmd);
+die "Could not find sql binary. Please make sure that the \$sqlcmd variable points to the right location\n" if (! -x $sqlcmd);
 
-if ($sql_type eq 'mysql'){
-       $sql_password = ($sql_password eq '') ? '' : "-p$sql_password";
-}
-$sql_password =~ s/(\W)/\\$1/g;
+$sql_password = (!$sql_password) ? '' : "-p$sql_password";
 
 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
 $date = POSIX::strftime("%Y-%m-%d %T",$sec,$min,$hour,($mday - $back_days),$mon,$year,$wday,$yday,$isdst);
 print "$date\n";
-if (POSIX::strftime("%Y-%m-%d %T",localtime) eq $date){
-       die "Could not set correct back date.\n";
-}
 $query = "";
 $query = "LOCK TABLES $sql_accounting_table WRITE;" if ($sql_type eq 'mysql');
 $query .= "DELETE FROM $sql_accounting_table WHERE AcctStopTime < '$date' AND AcctStopTime IS NOT NULL ;";
@@ -46,11 +40,8 @@ $query .= "UNLOCK TABLES;" if ($sql_type eq 'mysql');
 print "$query\n";
 open TMP, ">/tmp/truncate_radacct.query"
         or die "Could not open tmp file\n";
-print TMP "ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';\n" if ($sql_type eq 'oracle');
 print TMP $query;
 close TMP;
 $command = "$sqlcmd -h$sql_server -u$sql_username $sql_password $sql_database </tmp/truncate_radacct.query" if ($sql_type eq 'mysql');
 $command = "$sqlcmd  -U $sql_username -f /tmp/truncate_radacct.query $sql_database" if ($sql_type eq 'pg');
-$command = "$sqlcmd  $sql_username/$pass" . "@" . "$sql_database <$tmpfile.$server" if ($sql_type eq 'oracle');
-$command = "$sqlcmd '$sql_server' '$sql_port' '' '$sql_username' '$sql_password' </tmp/truncate_radacct.query" if ($sql_type eq 'sqlrelay');
 `$command`;
index 784de7b..2062d0b 100644 (file)
@@ -46,7 +46,7 @@ general_most_recent_fl: 30
 #
 # Set general_strip_realms to yes in order  to stip realms from usernames.
 # By default realms are not striped
-#general_strip_realms: yes
+#general_strip_realms : yes
 #
 # The delimiter used  in realms. Default is @
 #
@@ -71,7 +71,6 @@ general_clients_conf: /usr/local/etc/raddb/clients.conf
 general_sql_attrmap: %{general_base_dir}/conf/sql.attrmap
 general_accounting_attrs_file: %{general_base_dir}/conf/accounting.attrs
 general_extra_ldap_attrmap: %{general_base_dir}/conf/extra.ldap-attrmap
-general_username_mappings_file: %{general_base_dir}/conf/username.mappings
 #
 # it can be either ldap or sql
 # This affects the user base not accounting. Accounting is always in sql
@@ -98,19 +97,10 @@ general_default_file: %{general_base_dir}/conf/default.vals
 general_finger_type: snmp
 #
 # Defines the nas type. This is only used by snmpfinger
-# cisco, usrhiper and lucent are supported for now
+# cisco and lucent are supported for now
 #
 general_nas_type: cisco
 general_snmpfinger_bin: %{general_base_dir}/bin/snmpfinger
-#
-# Used by the 'Disconnect User' button in the Clear Open Sessions page
-# Uses the Cisco AAA Session MIB or a telnet session
-#
-general_sessionclear_bin: %{general_base_dir}/bin/clearsession
-#
-# Can be one of telnet or snmp
-#
-general_sessionclear_method: snmp
 general_radclient_bin: %{general_radiusd_base_dir}/bin/radclient
 #
 # this information is used from the server check page
@@ -152,12 +142,6 @@ general_stats_use_totacct: no
 # in the badusers table
 #
 general_restrict_badusers_access: no
-#
-# If set to yes then we restrict access to the nas administration page only to those
-# users which are allowed by their username mapping (nasadmin is set to yes)
-#
-general_restrict_nasadmin_access: no
-
 
 INCLUDE: %{general_base_dir}/conf/naslist.conf
 
@@ -204,7 +188,7 @@ ldap_regular_profile_attr: dialupregularprofile
 #
 # Uncomment to enable ldap debug
 #
-ldap_debug: true
+#ldap_debug: true
 #
 # Allow for defining the ldap filter used when searching for a user
 # Variables supported:
@@ -212,8 +196,6 @@ ldap_debug: true
 # %U: username provided though http authentication
 # %mu: mappings for userdb
 # %ma: mappings for accounting
-# %mn: mappings for nasdb
-# %mN: mappings for nas administration
 #
 # One use of this would be to restrict access to only the user's belonging to
 # a specific administrator like this:
@@ -229,11 +211,9 @@ ldap_debug: true
 
 
 #
-# can be one of mysql,pg,oracle,sqlrelay where:
+# can be one of mysql,pg where:
 # mysq: MySQL database (port 3306)
 # pg: PostgreSQL database (port 5432)
-# oracle: Oracle database (port 1521)
-# sqlrelay: SQL Relay
 #
 sql_type: mysql
 sql_server: localhost
@@ -252,17 +232,10 @@ sql_usergroup_table: usergroup
 sql_total_accounting_table: totacct
 sql_nas_table: nas
 #
-# If set to true then we show all the available groups with the groups
-# that the user is a member of highlighted in the user edit page.
-# Otherwise we only show the groups he is a member of.
-sql_show_all_groups: true
-#
 # This variable is used by the scripts in the bin folder
 # It should contain the path to the sql binary used to run
-# sql commands (mysql, psql, oracle and sqlrelay are only supported for now)
+# sql commands (mysql and psql are only supported for now)
 sql_command: /usr/local/bin/mysql
-#sql_command: /usr/bin/psql
-#sql_command: /usr/bin/sqlplus
 #
 # This variable is used by the scripts in the bin folder
 # It should contain the snmp type and  path to the binary 
@@ -284,13 +257,6 @@ sql_debug: true
 #
 # If set the query will be added to all of the queries on the accounting
 # table
-# Variables supported:
-# %u: username
-# %U: username provided though http authentication
-# %mu: mappings for userdb
-# %ma: mappings for accounting
-# %mn: mappings for nasdb
-# %mN: mappings for nas administration
 #sql_accounting_extra_query: %ma
 
 
@@ -328,16 +294,9 @@ sql_connect_timeout: 3
 # Default values for the various user limits in case the counter module
 # is used to impose such limits.
 # The value should be the user limit in seconds or none for nothing
-# Check out conf/sql.attrmap or extra.ldap-attrmap (depending on if you are
-# using sql or ldap) for per user attributes. The mapping should be made to
-# the attributes configured in the counter module. The attributes used by
-# dialupadmin will always be the ones appearing in the attribute mapping files
-# so you should make sure they are mapped to the correct attributes
-#
-#counter_default_daily: 14400
-#counter_default_weekly: 72000
-counter_default_daily: none
-counter_default_weekly: none
+#
+counter_default_daily: 14400
+counter_default_weekly: 72000
 counter_default_monthly: none
 #
 # Since calculating monthly usage can be quite expensive we make
index cde0b57..412d884 100644 (file)
@@ -9,17 +9,12 @@ if( $curVer >= $testVer )
 # If using sessions set use_session to 1 to also cache the config file
 #
 $use_session = 0;
-unset($config);
-unset($nas_list);
 if ($use_session){
        // Start session
        @session_start();
-       if (isset($_SESSION['config']))
-               $config = $_SESSION['config'];
-       if (isset($_SESSION['nas_list']))
-               $nas_list = $_SESSION['nas_list'];
 }
 if (!isset($config)){
+       unset($nas_list);
        $ARR=file("../conf/admin.conf");
        $EXTRA_ARR = array();
        foreach($ARR as $val) {
@@ -66,12 +61,10 @@ if (!isset($config)){
 if ($use_session == 0 && $config[general_use_session] == 'yes'){
        // Start session
        @session_start();
-       if (isset($nas_list))
-               session_register('nas_list');
 }
 //Make sure we are only passed allowed strings in username
 if ($login != '')
-       $login = preg_replace("/[^\w\.\/\@\:\-]/",'',$login);
+       $login = preg_replace("/[^\w\s\.\/\@\:]\-i\=/",'',$login);
 
 if ($login != '' && $config[general_strip_realms] == 'yes'){
        $realm_del = ($config[general_realm_delimiter] != '') ? $config[general_realm_delimiter] : '@';
@@ -80,35 +73,17 @@ if ($login != '' && $config[general_strip_realms] == 'yes'){
        if (count($new) == 2)
                $login = ($realm_for == 'suffix') ? $new[0] : $new[1];
 }
-unset($mappings);
-if (isset($_SESSION['mappings']))
-       $mappings = $_SESSION['mappings'];
 if (!isset($mappings) && $config[general_username_mappings_file] != ''){
        $ARR = file($config[general_username_mappings_file]);
        foreach($ARR as $val){
                $val=chop($val);
                if (ereg('^[[:space:]]*#',$val) || ereg('^[[:space:]]*$',$val))
                        continue;
-               list($key,$realm,$v)=split(":[[:space:]]*",$val,3);
-               if ($realm == 'accounting' || $realm == 'userdb' || $realm == 'nasdb' || $realm == 'nasadmin')
+               list($key,$realm,$v)=split(":[[:space:]]*",$val,2);
+               if ($realm == 'accounting' || $realm == 'userdb')
                        $mappings["$key"][$realm] = $v;
-               if ($realm == 'nasdb'){
-                       $NAS_ARR = array();
-                       $NAS_ARR = split(',',$v);
-                       foreach ($nas_list as $key => $nas){
-                               foreach ($NAS_ARR as $nas_check){
-                                       if ($nas_check == $nas[name])
-                                               unset($nas_list[$key]);
-                               }
-                       }
-               }
        }
        if ($config[general_use_session] == 'yes')
                session_register('mappings');
 }
-
-//Include missing.php3 if needed
-if (!function_exists('array_change_key_case'))
-       include_once('../lib/missing.php3');
-@header('Content-type: text/html; charset='.$config[general_charset].';');
 ?>
index fb0637a..69b5320 100644 (file)
@@ -5,8 +5,4 @@ checkItem       Dialup-Lock-Msg         radiuslockmsg
 checkItem      User-Password           userpassword
 checkItem      Regular-Profile         radiusProfileDn
 checkItem      Check-Item              radiusCheckItem         generic
-checkItem      Max-Daily-Session       radiusMaxDailySession
-checkItem      Max-Weekly-Session      radiusMaxWeeklySession
-checkItem      Max-Monthly-Session     radiusMaxMonthlySession
-
 replyItem      Reply-Item              radiusReplyItem         generic
index 567893c..4096d25 100644 (file)
@@ -25,7 +25,3 @@ nas3_model: Cisco 5300 access server
 nas3_ip: 147.122.122.124
 nas3_port_num: 210
 nas3_community: public
-#
-# sessionclear method can also be set per NAS
-#
-nas3_sessionclear_method: telnet
index a5a44c9..7fa79fa 100644 (file)
@@ -16,7 +16,6 @@ checkItem     Calling-Station-Id              Calling-Station-Id
 checkItem      Dialup-Access                   none
 checkItem      Max-Daily-Session               Max-Daily-Session
 checkItem      Max-Weekly-Session              Max-Weekly-Session
-checkItem      Max-Monthly-Session             Max-Monthly-Session
 checkItem      Login-Time                      Login-Time
 checkItem      Expiration                      Expiration
 
index 8ec5903..4e96ee3 100644 (file)
@@ -38,7 +38,6 @@ Dialup-Lock-Msg                       <a href="help/lock_message_help.html" target=lm_help onclick=w
 #Reply-Message <a href="help/reply_message_help.html" target=lm_help onclick=window.open("help/reply_message_help.html","lm_help","width=600,height=210,toolbar=no,scrollbars=no,resizable=yes") title="Reply-Message Help Page"><font color="blue">Reply-Message</font></a>
 #Max-Daily-Session             Daily Limit (secs)
 #Max-Weekly-Session            Weekly Limit (secs)
-#Max-Monthly-Session           Monthly Limit (secs)
 #Login-Time                    <a href="login_time_create.php3?val=$name1&first=yes" target=lt_create onclick=window.open("login_time_create.php3?val=$name1&first=yes","lt_create","width=600,height=490,toolbar=no,scrollbars=yes,resizable=yes") title="Login-Time Creation Page"><font color="blue">User Login Period </font></a>(<a href="help/login_time_help.html" target=lt_help onclick=window.open("help/login_time_help.html","lt_help","width=600,height=370,toolbar=no,scrollbars=no,resizable=yes") title="Login-Time Help Page"><font color="blue">UUCP </font></a>Format)
 #Expiration                    <a href="help/expiration_help.html" target=lt_help onclick=window.open("help/expiration_help.html","lt_help","width=600,height=180,toolbar=no,scrollbars=no,resizable=yes") title="Expiration Help Page"><font color="blue">User Expiration Date</font></a>
 #
index 3180365..e7d7b12 100644 (file)
@@ -2,20 +2,7 @@
 # Format:
 # Username:realm:query
 #
-# where realm is:
-# accounting: for the map to be used when querying the accounting db
-# userdb: for the map to be used when querying the user db
-# nasdb: To only map specific NASes to the username (separated by ,)
-# nasadmin: To allow the user to use the nas_admin page (yes or no)
+# where realm is accounting or userdb
 #
 library-admin:accounting:AND nasipaddress = '123.123.123.123'
 library-admin:userdb:AND Admin = 'library-admin'
-library-admin:nasdb:nas.lib.company.com
-library-admin:nasadmin:no
-#
-lab-admin:accounting:AND nasipaddress =  '123.123.124.123'
-lab-admin:userdb:AND Admin = 'lab-admin'
-lab-admin:nasdb:nas.lab.company.com
-lab-admin:nasadmin:no
-#
-admin:nasadmin:yes
index 8ec253f..3b7884b 100644 (file)
@@ -13,9 +13,6 @@ HTML pages layout designer
 Dragan Milivojevic: galileo@MICROSKY.NET
 A number of bug reports and a lot of crash testing
 
-Gary McKinney
-A number of bug reports and a lot of crash testing
-
 Alex Savguira: alexs@ravdata.com
 Ido Shavit
 Patches for auto generate password
index 7c7b13c..9c2b211 100644 (file)
@@ -82,13 +82,6 @@ Set general_prefered_lang to en
 If you are using sessions then remember to use the 'Clear Cache' page after making any changes
 
 >
-> When i try to access a dynamic web page it only shows a blank white page
->
-
-You may have not enabled support for the corresponding sql driver in PHP. If you are also using ldap, check for
-php ldap support.
-
->
 > It is still not working
 >
 
index 5b37592..315d454 100644 (file)
@@ -1,6 +1,8 @@
 * Minimize database (ldap,mysql) connections.
 * Clean up html code to make it smaller
 * More messages
+* Skins
+* Other languages in html
 * Multilanguage support for ldap attributes
 * Add language attributes in user_new.php3
 * Finger facility. Should find a way to make it work with all nases. That will
@@ -14,8 +16,4 @@
   are welcome.
 * Parse the radius dictionary files so that we can show a pull down menu of possible values
   for various attributes.
-* Also be able to keep username mappings in sql. Create an administration page
-* Improve sqlrelay support
-* Make the userinfo attributes configurable and create calculation formulas.Like:
-  Attribute-Name:DB-Attribute:Internal-Attribute:Initial-Value:Editable
-  Administrator:admin:admin:%U:No
+* Check the sql user code for sql injections
index 65172e8..8e4201e 100644 (file)
@@ -3,7 +3,7 @@
 <title>About page</title>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
index 46cd26e..1d42015 100644 (file)
@@ -15,7 +15,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -33,8 +33,6 @@ $link = @da_sql_pconnect ($config) or die('cannot connect to sql databse');
 $fields = @da_sql_list_fields($config[sql_accounting_table],$link,$config);
 $no_fields = @da_sql_num_fields($fields,$config);
 
-unset($items);
-
 for($i=0;$i<$no_fields;$i++){
        $key = strtolower(@da_sql_field_name($fields,$i,$config));
        $val = $sql_attrs[$key][desc];
@@ -59,7 +57,7 @@ class Qi {
                                $this->item=$item;
                                $this->operator=$operator;
        }
-
+                                               
        function show() {       global $operators;
                                global $items;
                $nam = $this->item;
@@ -87,7 +85,7 @@ EOM;
        </td></tr>
 EOM;
        }
-
+       
        function get($designator) {     global ${"item_of_$designator"};
                        global ${"value_of_$designator"};
                        global ${"operator_of_$designator"};
@@ -96,7 +94,7 @@ EOM;
                                $this->operator=${"operator_of_$designator"};
                                $this->item=${"item_of_$designator"};
                        }
-               }
+               }                       
        function query(){
                global $operators;
                global $items;
@@ -111,7 +109,7 @@ EOM;
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 
 <?php
 if(!$queryflag) {
@@ -175,14 +173,14 @@ $offset=0;
 while (${"item_of_w$number"}) {
        if(${"delete_w$number"}==1) {$offset=1;$number++;}
                else {
-               $designator=$number-$offset;
+               $designator=$number-$offset;                    
                ${"w$designator"} = new Qi("w$designator","","");
                ${"w$designator"}->get("w$number");
                ${"w$designator"}->show();
                $number++;
                }
        }
-if($add==1) {
+if($add==1) {  
        ${"w$number"} = new Qi("w$number","$item_name","$operators[0]");
        ${"w$number"}->show();
        }
@@ -224,30 +222,20 @@ while (${"item_of_w$i"}){
 
 $order = ($order_by != '') ? "$order_by" : 'username';
 
-if (preg_match("/[\s;]/",$order))
-       die("ORDER BY pattern is illegal. Exiting abnornally.");
-
-if (!is_numeric($maxresults))
-       die("Max Results is not in numeric form. Exiting abnormally.");
-
-unset($query_view);
 foreach ($accounting_show_attrs as $val)
        $query_view .= $val . ',';
 $query_view = ereg_replace(',$','',$query_view);
-unset($sql_extra_query);
+$sql_extra_query = '';
 if ($config[sql_accounting_extra_query] != '')
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
-       $sql_extra_query = da_sql_escape_string($sql_extra_query);
-$query="SELECT " . da_sql_limit($maxresults,0,$config) . " $query_view FROM $config[sql_accounting_table]
-       $where $sql_extra_query " . da_sql_limit($maxresults,1,$config) .
-       " ORDER BY $order " . da_sql_limit($maxresults,2,$config) . ";";
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
+$query="SELECT $query_view FROM $config[sql_accounting_table] $where $sql_extra_query ORDER BY $order LIMIT $maxresults;";
 
 echo <<<EOM
 <html>
 <head>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <br>
 <table border=0 width=940 cellpadding=1 cellspacing=1>
 <tr valign=top>
@@ -283,10 +271,8 @@ echo "</tr>\n";
                                if ($info == '')
                                        $info = '-';
                                $info = $sql_attrs[$val][func]($info);
-                               if ($val == 'username'){
-                                       $Info = urlencode($info);
-                                       $info = "<a href=\"user_admin.php3?login=$Info\" title=\"Edit user $info\">$info<a/>";
-                               }
+                               if ($val == 'username')
+                                       $info = "<a href=\"user_admin.php3?login=$info\" title=\"Edit user $info\">$info<a/>";
                                echo <<<EOM
                        <td>$info</td>
 EOM;
index 2884c1d..ae0d9df 100644 (file)
@@ -13,7 +13,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -33,7 +33,7 @@ $num = 0;
 $pagesize = ($pagesize) ? $pagesize : 10;
 if (!is_numeric($pagesize) && $pagesize != 'all')
        $pagesize = 10;
-$limit = ($pagesize == 'all') ? '' : "$pagesize";
+$limit = ($pagesize == 'all') ? '' : "LIMIT $pagesize";
 $selected[$pagesize] = 'selected';
 $login = ($login != '') ? $login : 'anyone';
 $usercheck = ($login == 'anyone') ? "LIKE '%'" : "= '$login'";
@@ -48,7 +48,7 @@ echo <<<EOM
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -79,7 +79,7 @@ if ($link){
                $row = @da_sql_fetch_array($search,$config);
                if ($row[id] == $row_id){
                        $admin = "$row[admin]";
-                       if (($admin != '-' && $_SERVER["PHP_AUTH_USER"] == $admin) || $admin == '-'){
+                       if (($admin != '-' && $HTTP_SERVER_VARS["PHP_AUTH_USER"] == $admin) || $admin == '-'){
                                $sql_servers = array();
                                if ($config[sql_extra_servers] != '')
                                        $sql_servers = explode(' ',$config[sql_extra_servers]);
@@ -137,7 +137,7 @@ EOM;
        </tr>
 
 <?php
-$auth_user = $_SERVER["PHP_AUTH_USER"];
+$auth_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
 if ($config[general_restrict_badusers_access] == 'yes'){
        $auth_user = da_sql_escape_string($auth_user);
        $extra_query = "AND admin == '$auth_user'";
@@ -145,17 +145,15 @@ if ($config[general_restrict_badusers_access] == 'yes'){
 $link = @da_sql_pconnect($config);
 if ($link){
        $search = @da_sql_query($link,$config,
-       "SELECT " . da_sql_limit($limit,0,$config) . " * FROM $config[sql_badusers_table]
-       WHERE username $usercheck $extra_query AND incidentdate <= '$now_str'
-       AND incidentdate >= '$prev_str' " . da_sql_limit($limit,1,$config) .
-       " ORDER BY incidentdate $order " . da_sql_limit($limit,2,$config) . " ;");
+       "SELECT * FROM $config[sql_badusers_table]
+       WHERE UserName $usercheck $extra_query AND Date <= '$now_str'
+       AND Date >= '$prev_str' ORDER BY Date $order $limit;");
        if ($search){
                while( $row = @da_sql_fetch_array($search,$config) ){
                        $num++;
                        $id = $row[id];
-                       $user = "$row[username]";
-                       $User = urlencode($user);
-                       $date = "$row[incidentdate]";
+                       $user = "$row[userName]";
+                       $date = "$row[date]";
                        $reason = "$row[reason]";
                        $admin = "$row[admin]";
                        if ($admin == $auth_user || $admin == '-')
@@ -169,7 +167,7 @@ if ($link){
                        echo <<<EOM
                        <tr align=center>
                                <td>$num</td>
-                               <td><a href="user_admin.php3?login=$User" title="Edit user $user">$user</a></td>
+                               <td><a href="user_admin.php3?login=$user" title="Edit user $user">$user</a></td>
                                <td>$date</td>
                                <td>$admin</td>
                                <td>$reason</td>
index 5f29500..12c2c32 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-$auth_user = $_SERVER["PHP_AUTH_USER"];
+$auth_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
 if ($auth_user){
        if (is_file("../html/buttons/$auth_user/buttons.html.php3"))
                include("../html/buttons/$auth_user/buttons.html.php3");
@@ -8,7 +8,7 @@ if ($auth_user){
                        include("../html/buttons/default/buttons.html.php3");
        }
 }
-else{
+else{  
        if (is_file("../html/buttons/default/buttons.html.php3"))
                include("../html/buttons/default/buttons.html.php3");
 }
index 9900ac7..10349dc 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 require('../conf/config.php3');
-require_once('../lib/xlat.php3');
 if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
        include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
 else{
@@ -9,7 +8,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -25,7 +24,7 @@ echo <<<EOM
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -41,10 +40,8 @@ include("../html/user_toolbar.html.php3");
 $open_sessions = 0;
 
 $sql_extra_query = '';
-if ($config[sql_accounting_extra_query] != ''){
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
-       $sql_extra_query = da_sql_escape_string($sql_extra_query);
-}
+if ($config[sql_accounting_extra_query] != '')
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
 
 print <<<EOM
 </table>
@@ -64,78 +61,20 @@ print <<<EOM
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
 EOM;
-
-if ($drop_conns == 1){
-       $method = 'snmp';
-       $nastype = 'cisco';
-       if ($config[general_sessionclear_method] != '')
-               $method = $config[general_sessionclear_method];
-       if ($config[general_nas_type] != '')
-               $nastype = $config[general_nas_type];
-       if ($config[general_ld_library_path] != '')
-               putenv("LD_LIBRARY_PATH=$config[general_ld_library_path]");
-       $nas_by_ip = array();
-       $meth_by_ip = array();
-       $nastype_by_ip = array();
-       foreach ($nas_list as $nas){
-               if ($nas[ip] != ''){
-                       $ip = $nas[ip];
-                       $nas_by_ip[$ip] = $nas[community];
-                       $meth_by_ip[$ip] = $nas[sessionclear_method];
-                       $nastype_by_ip[$ip] = $nas[nas_type];
-               }
-       }
-
+   
+if ($clear_sessions == 1){
        $link = @da_sql_pconnect($config);
        if ($link){
-               $search = @da_sql_query($link,$config,
-               "SELECT nasipaddress,acctsessionid FROM $config[sql_accounting_table]
-               WHERE username = '$login' AND acctstoptime IS NULL;");
-               if ($search){
-                       while($row = @da_sql_fetch_array($search,$config)){
-                               $sessionid = $row[acctsessionid];
-                               $sessionid = hexdec($sessionid);
-                               $nas = $row[nasipaddress];
-                               $port = $row[nasportid];
-                               $meth = $meth_by_ip[$nas];
-                               $nastype = ($nastype_by_ip[$nas] != '') ? $nastype_by_ip[$nas] : $nastype;
-                               $comm = $nas_by_ip[$nas];
-                               if ($meth == '')
-                                       $meth = $method;
-                               if ($meth == 'snmp' && $comm != '')
-                                       exec("$config[general_sessionclear_bin] $nas snmp $nastype $login $sessionid $comm");
-                               if ($meth == 'telnet')
-                                       exec("$config[general_sessionclear_bin] $nas telnet $nastype $login $sessionid $port");
-                       }
-               }
+               $res = @da_sql_query($link,$config,
+               "DELETE FROM $config[sql_accounting_table]
+               WHERE username='$login' AND acctstoptime = 0 $sql_extra_query;");
+               if ($res)
+                       echo "<b>Deleted open sessions from accounting table</b><br>\n";
                else
-                       echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
-       }
+                       echo "<b>Error deleting open sessions for user" . da_sql_error($link,$config) . "</b><br>\n";
+        }
        else
                echo "<b>Could not connect to SQL database</b><br>\n";
-}
-if ($clear_sessions == 1){
-       $sql_servers = array();
-       if ($config[sql_extra_servers] != '')
-               $sql_servers = explode(' ',$config[sql_extra_servers]);
-       $quer = '= 0';
-       if ($config[sql_type] == 'pg')
-               $quer = 'IS NULL';
-       $sql_servers[] = $config[sql_server];
-       foreach ($sql_servers as $server){
-               $link = @da_sql_host_connect($server,$config);
-               if ($link){
-                       $res = @da_sql_query($link,$config,
-                       "DELETE FROM $config[sql_accounting_table]
-                       WHERE username='$login' AND acctstoptime $quer $sql_extra_query;");
-                       if ($res)
-                               echo "<b>Deleted open sessions from accounting table on server $server</b><br>\n";
-                       else
-                               echo "<b>Error deleting open sessions for user" . da_sql_error($link,$config) . "</b><br>\n";
-               }
-               else
-                       echo "<b>Could not connect to SQL database</b><br>\n";
-       }
        echo <<<EOM
 </td></tr>
 </table>
@@ -158,7 +97,7 @@ else{
                }
                else
                        echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
-       }
+        }
        else
                echo "<b>Could not connect to SQL database</b><br>\n";
 }
@@ -176,8 +115,6 @@ Are you sure you want to clear all open user sessions?
        </table>
 <br>
 <input type=submit class=button value="Yes Clear" OnClick="this.form.clear_sessions.value=1">
-<br><br>
-<input type=submit class=button value="Yes Drop Connections" OnClick="this.form.drop_conns.value=1">
 </form>
 </td></tr>
 </table>
index 8e27e24..d8fa823 100644 (file)
@@ -1,8 +1,5 @@
 <html>
-<head>
-<link rel="stylesheet" href="style.css">
-</head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center><img src="images/title2.gif">
 <br><font size=+1><br>
 <b>A web based administration interface for the freeradius radius server</b>
index 6387886..938ed82 100644 (file)
@@ -1,8 +1,6 @@
 <?php
 require('../conf/config.php3');
 require('../lib/attrshow.php3');
-require('../lib/sql/nas_list.php3');
-require_once('../lib/xlat.php3');
 ?>
 <html>
 <?php
@@ -15,7 +13,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -25,10 +23,8 @@ EOM;
 }
 
 $now = time();
-if (!isset($last))
+if ($last == 0)
        $last = ($config[general_most_recent_fl]) ? $config[general_most_recent_fl] : 5;
-if (!is_numeric($last))
-       $last = 5;
 $start = $now - ($last*60);
 $now_str = date($config[sql_full_date_format],$now);
 $prev_str = date($config[sql_full_date_format],$start);
@@ -39,7 +35,7 @@ $prev_str = da_sql_escape_string($prev_str);
 $pagesize = ($pagesize) ? $pagesize : 10;
 if (!is_numeric($pagesize) && $pagesize != 'all')
        $pagesize = 10;
-$limit = ($pagesize == 'all') ? '' : "$pagesize";
+$limit = ($pagesize == 'all') ? '' : "LIMIT $pagesize";
 $selected[$pagesize] = 'selected';
 $order = ($order != '') ? $order : $config[general_accounting_info_order];
 if ($order != 'desc' && $order != 'asc')
@@ -54,10 +50,6 @@ if ($server != '' && $server != 'all'){
        $server_str = "AND nasipaddress = '$server'";
 }
 
-unset($da_name_cache);
-if (isset($_SESSION['da_name_cache']))
-       $da_name_cache = $_SESSION['da_name_cache'];
-
 ?>
 
 <head>
@@ -65,7 +57,7 @@ if (isset($_SESSION['da_name_cache']))
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -103,11 +95,9 @@ if ($acct_attrs['fl'][2] != '') echo "<th>" . $acct_attrs['fl'][2] . "</th>\n";
 if ($acct_attrs['fl'][7] != '') echo "<th>" . $acct_attrs['fl'][7] . "</th>\n";
 if ($acct_attrs['fl'][8] != '') echo "<th>" . $acct_attrs['fl'][8] . "</th>\n";
 if ($acct_attrs['fl'][9] != '') echo "<th>" . $acct_attrs['fl'][9] . "</th>\n";
-unset($sql_extra_query);
-if ($config[sql_accounting_extra_query] != ''){
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
-       $sql_extra_query = da_sql_escape_string($sql_extra_query);
-}
+$sql_extra_query = '';
+if ($config[sql_accounting_extra_query] != '')
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
 ?>
        </tr>
 
@@ -115,13 +105,13 @@ if ($config[sql_accounting_extra_query] != ''){
 $link = @da_sql_pconnect($config);
 if ($link){
        $search = @da_sql_query($link,$config,
-       "SELECT " . da_sql_limit($limit,0,$config) . " acctstoptime,username,nasipaddress,nasportid,acctterminatecause,callingstationid
+       "SELECT acctstoptime,username,nasipaddress,nasportid,acctterminatecause,callingstationid
        FROM $config[sql_accounting_table]
        WHERE acctstoptime <= '$now_str' AND acctstoptime >= '$prev_str'
        AND (acctterminatecause LIKE 'Login-Incorrect%' OR
        acctterminatecause LIKE 'Invalid-User%' OR
-       acctterminatecause LIKE 'Multiple-Logins%') $callerid_str $server_str $sql_extra_query " . da_sql_limit($limit,1,$config) .
-       " ORDER BY acctstoptime $order " . da_sql_limit($limit,2,$config) . " ;");
+       acctterminatecause LIKE 'Multiple-Logins%') $callerid_str $server_str $sql_extra_query
+       ORDER BY acctstoptime $order $limit;");
        if ($search){
                while( $row = @da_sql_fetch_array($search,$config) ){
                        $num++;
@@ -210,8 +200,6 @@ EOM;
 <?php
 foreach ($nas_list as $nas){
        $name = $nas[name];
-       if ($nas[ip] == '')
-               continue;
        $servers[$name] = $nas[ip];
 }
 ksort($servers);
index 0c363c6..f3e90c8 100644 (file)
@@ -10,7 +10,7 @@ $max = ($max_results) ? $max_results : 40;
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -36,7 +36,6 @@ $max = ($max_results) ? $max_results : 40;
 
 <?php
 if ($find_user == 1){
-       unset($found_users);
        if (is_file("../lib/$config[general_lib_type]/find.php3"))
                include("../lib/$config[general_lib_type]/find.php3");
        if (isset($found_users)){
@@ -51,12 +50,11 @@ EOM;
                foreach ($found_users as $user){
                        if ($user == '')
                                $user = '-';
-                       $User = urlencode($user);
                        $num++;
                        $msg .= <<<EOM
                        <tr align=center>
                                <td>$num</td>
-                               <td><a href="user_admin.php3?login=$User" title="Edit user $user">$user</a></td>
+                               <td><a href="user_admin.php3?login=$user" title="Edit user $user">$user</a></td>
                        </tr>
 EOM;
                }
@@ -78,9 +76,8 @@ Search Criteria
 <?php
 echo <<<EOM
 <select name="search_IN" editable onChange="this.form.submit();">
-<option $selected[username] value="username">User Name
 <option $selected[name]  value="name">User Full Name
-<option $selected[department] value="department">User Department
+<option $selected[ou] value="ou">User Department
 <option $selected[radius] value="radius">User Radius Attribute
 EOM;
 ?>
@@ -100,7 +97,7 @@ RADIUS Attribute
 <select name="radius_attr" editable>
 EOM;
        foreach($show_attrs as $key => $desc)
-               echo "<option $selected[$key] value=\"$key\">$desc\n";
+               echo "<option $selected[$key] value=\"$key\">$desc\n";          
        echo <<<EOM
 </select>
 </td>
index 49e7a17..172f4f1 100644 (file)
@@ -10,7 +10,7 @@ if ($config[general_lib_type] != 'sql'){
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>This page is only available if you are using sql as general library type</b>
 </body>
@@ -19,7 +19,6 @@ EOM;
        exit();
 }
 
-unset($group_members);
 if (is_file("../lib/$config[general_lib_type]/group_info.php3")){
        include("../lib/$config[general_lib_type]/group_info.php3");
        if ($group_exists == 'no'){
@@ -28,7 +27,7 @@ if (is_file("../lib/$config[general_lib_type]/group_info.php3")){
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <form action="group_admin.php3" method=get>
 <b>Group Name&nbsp;&nbsp;</b>
@@ -49,7 +48,7 @@ EOM;
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -86,10 +85,10 @@ if ($do_changes == 1){
                include("../lib/$config[general_lib_type]/group_info.php3");
 }
 ?>
-
-
+       
+   
    <form method=post>
-      <input type=hidden name=login value=<?php echo $login ?>>
+      <input type=hidden name=login value="<?php echo $login ?>">
       <input type=hidden name=do_changes value=0>
       <input type=hidden name=show value=0>
        <table border=1 bordercolordark=#ffffe0 bordercolorlight=#000000 width=100% cellpadding=2 cellspacing=0 bgcolor="#ffffe0" valign=top>
@@ -98,7 +97,7 @@ if ($do_changes == 1){
 Group Members (Check to Delete)
 </td>
 <td>
-<select name=del_members[] multiple size=5>
+<select name=del_members[] multiple size=5> 
 <?php
 foreach ($group_members as $member){
        echo "<option value=\"$member\">$member\n";
index ed953e6..bce1d1b 100644 (file)
@@ -11,7 +11,7 @@ if ($config[general_lib_type] != 'sql'){
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>This page is only available if you are using sql as general library type</b>
 </body>
@@ -22,7 +22,6 @@ EOM;
 
 require('../lib/attrshow.php3');
 require('../lib/defaults.php3');
-require("../lib/$config[general_lib_type]/group_info.php3");
 
 if ($config[general_lib_type] == 'sql' && $config[sql_use_operators] == 'true'){
        $colspan=2;
@@ -40,7 +39,7 @@ if ($config[general_lib_type] == 'sql' && $config[sql_use_operators] == 'true'){
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -62,7 +61,7 @@ if ($config[general_lib_type] == 'sql' && $config[sql_use_operators] == 'true'){
 <tr bgcolor="black" valign=top><td colspan=2>
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
-
+   
 <?php
 if (is_file("../lib/$config[general_lib_type]/group_info.php3"))
        include("../lib/$config[general_lib_type]/group_info.php3");
@@ -88,22 +87,6 @@ EOM;
        echo <<<EOM
        <tr>
                <td align=right colspan=$colspan bgcolor="#d0ddb0">
-               Available Groups
-               </td><td>
-EOM;
-               if (!isset($existing_groups))
-                       echo "<b>No groups available</b>\n";
-               else{
-                       echo "<select name=\"existing_groups\">\n";
-                       foreach ($existing_groups as $group => $count)
-                               echo "<option value=\"$group\">$group\n";
-                       echo "</select>\n";
-               }
-       echo <<<EOM
-               </td>
-       </tr>
-       <tr>
-               <td align=right colspan=$colspan bgcolor="#d0ddb0">
                Group name
                </td><td>
                <input type=text name="login" value="$login" size=35>
@@ -116,7 +99,7 @@ EOM;
                <textarea name=members cols="15" wrap="PHYSICAL" rows=5></textarea>
                </td>
        </tr>
-
+               
 EOM;
        foreach($show_attrs as $key => $desc){
                $name = $attrmap["$key"];
index 725797f..54cca94 100644 (file)
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
 <br>
+<pre>
 
-<b>Please choose which file you wish to read:</b><br><br>
-<form name="readhelp" method=post>
-<select name=help_file>
-<?php
-$selected[$help_file] = 'selected';
-
-echo <<<EOM
-<option $selected[readme] value="readme">README File
-<option $selected[howto] value="howto">HOWTO File
-<option $selected[faq] value="faq">FAQ File
-EOM;
-?>
-</select>
-<br><br>
-<input type=submit class=button value="Read File">
-</form>
+<b>For now we just include the README file</b><br>
 
-<pre>
 <?php
-$in_file = '';
-if ($help_file == 'readme')
-       $in_file = '../../README';
-else if ($help_file == 'howto')
-       $in_file = '../../doc/HOWTO';
-else if ($help_file == 'faq')
-       $in_file = '../../doc/FAQ';
-if ($in_file != '')
-       readfile("$in_file");
+readfile('../../README');
 ?>
+
 </pre>
 <br>
 </td></tr>
index fd0659a..b05a435 100644 (file)
@@ -3,7 +3,7 @@
 <title>
 dialup administration</title>
 </head>
-       <frameset cols="130,*" border="0" frameborder="0" framespacing="0">
+       <frameset cols="122,*" border="0" frameborder="0" framespacing="0">
                <frame  name="buttons" src="buttons.php3" marginwidth="8"
                        marginheight="8" noresize >
                <frame  name="content" src="content.html" marginwidth="8"
index 11d06c5..39e437a 100644 (file)
@@ -4,7 +4,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <?php
 
 function check_day($day){
@@ -30,7 +30,7 @@ function check_day($day){
 
 $mapping = array(
        'Mo' => 'Monday',
-       'Tu' => 'Tuesday',
+       'Tu' => 'Tusday',
        'We' => 'Wednesday',
        'Th' => 'Thursday',
        'Fr' => 'Friday',
@@ -144,7 +144,7 @@ foreach ($rules as $rule){
                $rulestr = "$rule";
        else
                $rulestr .= ",$rule";
-}
+} 
 if ($update == 1 && $val != '')
        echo <<<EOM
 <script language="JavaScript1.1" type="text/javascript">
@@ -247,7 +247,7 @@ if (!empty($rules)){
        echo "</select>\n";
 }
 else
-       echo "<i>No rules available</i><br>\n";
+       echo "<i>No rules available</i><br>\n"; 
 ?>
 </td></tr>
 <tr><td colspan=5 align=center><?php echo $err_msg ?></td></tr>
index 622b2dd..3378ff6 100644 (file)
@@ -8,7 +8,7 @@ else{
 <title>NAS Administration Page</title>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -16,25 +16,8 @@ else{
 EOM;
        exit();
 }
-if ($config[general_restrict_nasadmin_access] == 'yes'){
-       $auth_user = $_SERVER["PHP_AUTH_USER"];
-       if ($auth_user == '' || $mappings[$auth_user][nasadmin] != 'yes'){
-               echo <<<EOM
-<title>NAS Administration Page</title>
-<link rel="stylesheet" href="style.css">
-</head>
-<body>
-<center>
-<b>Access is not allowed to this username.</b>
-</body>
-</html>
-EOM;
-               exit();
-       }
-}
 
-
-if ($clear_fields == 1 || ($do_it == 0 && $select_nas == 0))
+if ($clear_fields == 1)
        $selected_nas = $readonly = '';
 else
        $readonly = 'readonly';
@@ -45,8 +28,7 @@ if ($link){
                $selected_nas = da_sql_escape_string($selected_nas);
                switch ($action) {
                        case 'check_nas':
-                               require_once('../lib/functions.php3');
-                               if (!check_ip($selected_nas) && $selected_nas == gethostbyname($selected_nas))
+                               if ($selected_nas == gethostbyname($selected_nas))
                                        $msg = "<b>The NAS name <font color=red>is not</font> valid</b><br>\n";
                                else
                                        $msg = "<b>The NAS name <font color=green>is</font> valid</b><br>\n";
@@ -65,14 +47,6 @@ if ($link){
                                if ($nasname == '' || $nassecret == '' || $nasshortname == '')
                                        $msg = "<b>Error. Required fields are not set</b><br>\n";
                                else{
-                                       $nasshortname = da_sql_escape_string($nasshortname);
-                                       $nastype = da_sql_escape_string($nastype);
-                                       $nasportnum = da_sql_escape_string($nasportnum);
-                                       $nassecret = da_sql_escape_string($nassecret);
-                                       $nascommunity = da_sql_escape_string($nascommunity);
-                                       $nasdescription = da_sql_escape_string($nasdescription);
-                                       $nasname = da_sql_escape_string($nasname);
-
                                        $res = @da_sql_query($link,$config,
                                        "INSERT INTO $config[sql_nas_table]
                                        (nasname,shortname,type,ports,secret,community,description)
@@ -90,14 +64,6 @@ if ($link){
                                if ($nassecret == '' || $nasshortname == '')
                                        $msg = "<b>Error. Required fields are not set</b><br>\n";
                                else{
-                                       $nasshortname = da_sql_escape_string($nasshortname);
-                                       $nastype = da_sql_escape_string($nastype);
-                                       $nasportnum = da_sql_escape_string($nasportnum);
-                                       $nassecret = da_sql_escape_string($nassecret);
-                                       $nascommunity = da_sql_escape_string($nascommunity);
-                                       $nasdescription = da_sql_escape_string($nasdescription);
-                                       $nasname = da_sql_escape_string($nasname);
-
                                        $res = @da_sql_query($link,$config,
                                        "UPDATE $config[sql_nas_table] SET
                                        shortname = '$nasshortname',
@@ -118,22 +84,21 @@ if ($link){
        "SELECT * FROM $config[sql_nas_table] ORDER BY nasname;");
        if ($search){
                $num = 0;
-               unset($my_nas_list);
+               unset($nas_list);
                while($row = @da_sql_fetch_array($search,$config)){
                        $my_nas_name = $row['nasname'];
                        if ($my_nas_name != ''){
                                $num++;
-                               $my_nas_list[$my_nas_name]['name'] = $my_nas_name;
-                               $my_nas_list[$my_nas_name]['shortname'] = $row['shortname'];
-                               $my_nas_list[$my_nas_name]['type'] = $row['type'];
-                               if ($clear_fields == 0 && $selected_nas == $my_nas_name){
+                               if ($clear_fields == 0 && $selected_nas == $my_nas_name)
                                        $selected[$my_nas_name] = 'selected';
-                                       $selected[$my_nas_list[$my_nas_name]['type']] = 'selected';
-                               }
-                               $my_nas_list[$my_nas_name]['ports'] = $row['ports'];
-                               $my_nas_list[$my_nas_name]['secret'] = $row['secret'];
-                               $my_nas_list[$my_nas_name]['community'] = $row['community'];
-                               $my_nas_list[$my_nas_name]['description'] = $row['description'];
+                               $nas_list[$my_nas_name]['name'] = $my_nas_name;
+                               $nas_list[$my_nas_name]['shortname'] = $row['shortname'];
+                               $nas_list[$my_nas_name]['type'] = $row['type'];
+                               $selected[$nas_list[$my_nas_name]['type']] = 'selected';
+                               $nas_list[$my_nas_name]['ports'] = $row['ports'];
+                               $nas_list[$my_nas_name]['secret'] = $row['secret'];
+                               $nas_list[$my_nas_name]['community'] = $row['community'];
+                               $nas_list[$my_nas_name]['description'] = $row['description'];
                        }
                }
        }
@@ -149,7 +114,7 @@ else
 <title>NAS Administration Page</title>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -185,9 +150,9 @@ else
 NAS List
 </td>
 <td>
-<select name=selected_nas size=5 OnChange="this.form.select_nas.value=1;this.form.submit()">
+<select name=selected_nas size=5 OnChange="this.form.select_nas.value=1;this.form.submit()"> 
 <?php
-foreach ($my_nas_list as $member){
+foreach ($nas_list as $member){
        $name = $member[name];
        echo "<option $selected[$name] value=\"$name\">$name\n";
 }
@@ -196,11 +161,11 @@ foreach ($my_nas_list as $member){
 </td>
 </tr>
 <?php
-$array = $my_nas_list[$selected_nas];
+$array = $nas_list[$selected_nas];
 echo <<<EOM
 <tr>
 <td align=right bgcolor="#d0ddb0">
-NAS Name
+NAS Name 
 </td>
 <td>
 <input type=text name=nasname size=40 value="$array[name]" $readonly>
@@ -266,9 +231,9 @@ EOM;
 <br>
 <select name=action size=1>
 <?php
-if ($clear_fields == 1 || ($do_it == 0 && $select_nas == 0))
+if ($clear_fields == 1)
        echo "<option value=\"add_nas\">Add NAS\n";
-if ($clear_fields == 0)
+else
        echo <<<EOM
 <option value="change_nas">Change NAS Info
 <option value="del_nas">Delete Selected NAS
index 1d2f664..85f7381 100644 (file)
@@ -16,7 +16,7 @@
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
        <table border=1 bordercolordark=#ffffe0 bordercolorlight=#000000 width=100% cellpadding=2 cellspacing=0 bgcolor="#ffffe0" valign=top>
-       <tr><td align=center bgcolor="#d0ddb0">Password</td><td><input type="password" name="passwd" value="">&nbsp;<input type="submit" class=button value="check"></td></tr>
+       <tr><td align=center bgcolor="#d0ddb0">Password</td><td><input type="password" name="passwd" value="">&nbsp;<input type="submit" class=button value="check"></td></tr>  
        </table>
        </table>
 </table>
index 7934552..589f75b 100644 (file)
@@ -8,7 +8,7 @@ session_destroy();
 <title>Session Cache Destroy Page</title>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Session Cache Destroyed</b>
 </body>
index b17e314..722f84e 100644 (file)
@@ -12,7 +12,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -20,27 +20,13 @@ else{
 EOM;
        exit();
 }
-if ($config[general_lib_type] != 'sql'){
-       echo <<<EOM
-<title>User Groups</title>
-<meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
-<link rel="stylesheet" href="style.css">
-</head>
-<body>
-<center>
-<b>This page is only available if you are using sql as general library type</b>
-</body>
-</html>
-EOM;
-       exit();
-}
 ?>
 <head>
 <title>User Groups</title>
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -62,31 +48,41 @@ EOM;
 <tr bgcolor="black" valign=top><td colspan=2>
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
-<font size=-2>Only groups with members are shown</font><p>
+<p>
        <table border=1 bordercolordark=#ffffe0 bordercolorlight=#000000 width=100% cellpadding=2 cellspacing=0 bgcolor="#ffffe0" valign=top>
        <tr bgcolor="#d0ddb0">
        <th>#</th><th>group</th><th># of members</th>
        </tr>
 
 <?php
-unset($login);
-$num = 0;
-include_once("../lib/$config[general_lib_type]/group_info.php3");
-if (isset($existing_groups)){
-       foreach ($existing_groups as $group => $num_members){
-               $num++;
-               $Group = urlencode($group);
-               echo <<<EOM
+$link = @da_sql_pconnect($config);
+if ($link){
+       $search = @da_sql_query($link,$config,
+       "SELECT COUNT(*) as counter,groupname,MAX(username) AS usersample FROM $config[sql_usergroup_table] GROUP BY groupname;");
+       if ($search){
+               if (@da_sql_num_rows($search,$config)){
+                       while( $row = @da_sql_fetch_array($search,$config) ){
+                               $num++;
+                               $group = $row[groupname];
+                               $num_members = $row[counter];
+                               if ($row[usersample] == "") $num_members--;
+                               echo <<<EOM
                <tr align=center>
                        <td>$num</td>
-                       <td><a href="group_admin.php3?login=$Group" title="Edit group $group">$group</a></td>
+                       <td><a href="group_admin.php3?login=$group" title="Edit group $group">$group</a></td>
                        <td>$num_members</td>
                </tr>
 EOM;
+                       }
+               }
+               else
+                       echo "<b>Could not find any groups</b><br>\n";
        }
+       else
+               echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
 }
 else
-       echo "<b>Could not find any groups</b><br>\n";
+       echo "<b>Could not connect to SQL database</b><br>\n";
 ?>
        </table>
 </table>
index 65925b9..bade492 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 require('../conf/config.php3');
-require('../lib/sql/nas_list.php3');
-require_once('../lib/xlat.php3');
 ?>
 <html>
 <head>
@@ -9,11 +7,11 @@ require_once('../lib/xlat.php3');
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 
 <?php
-require_once('../lib/functions.php3');
+require('../lib/functions.php3');
 
 if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
        include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
@@ -26,7 +24,6 @@ EOM;
        exit();
 }
 
-$stats_num = array();
 
 $date = strftime('%A, %e %B %Y, %T %Z');
 $now = time();
@@ -40,7 +37,7 @@ $days[0] = $after;
 $counter = $after_time + 86400;
 $i = 1;
 while($counter < $before_time){
-       $days[$i++] = date($config[sql_date_format],$counter);
+       $days[$i++] = date($config[sql_date_format],$counter);  
        $counter += 86400;
 }
 $days[$i] = $before;
@@ -84,8 +81,6 @@ $i = 1;
 $servers[all] = 'all';
 foreach ($nas_list as $nas){
        $name = $nas[name];
-       if ($nas[ip] == '')
-               continue;
        $servers[$name] = $nas[ip];
        $i++;
 }
@@ -96,7 +91,7 @@ if ($server != 'all' && $server != ''){
 }
 $sql_extra_query = '';
 if ($config[sql_accounting_extra_query] != '')
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
 
 $link = @da_sql_pconnect($config);
 if ($link){
@@ -109,19 +104,19 @@ if ($link){
                else
                        $search = @da_sql_query($link,$config,
                        "SELECT $res[1],$res[2],$res[3] FROM $config[sql_accounting_table]
-                       $sql_val[user] AND acctstoptime >= '$day 00:00:00'
+                       $sql_val[user] AND acctstoptime >= '$day 00:00:00' 
                        AND acctstoptime <= '$day 23:59:59' $s $sql_extra_query;");
                if ($search){
                        $row = @da_sql_fetch_array($search,$config);
                        $data[$day][1] = $row[res_1];
                        $data[sum][1] += $row[res_1];
-                       $stats_num[1] = ($data[$day][1]) ? $stats_num[1] + 1 : $stats_num[1];
+                       $num[1] = ($data[$day][1]) ? $num[1] + 1 : $num[1];
                        $data[$day][2] = $row[res_2];
                        $data[sum][2] += $row[res_2];
-                       $stats_num[2] = ($data[$day][2]) ? $stats_num[2] + 1 : $stats_num[2];
+                       $num[2] = ($data[$day][2]) ? $num[2] + 1 : $num[2];
                        $data[$day][3] = $row[res_3];
                        $data[sum][3] += $row[res_3];
-                       $stats_num[3] = ($data[$day][3]) ? $stats_num[3] + 1 : $stats_num[3];
+                       $num[3] = ($data[$day][3]) ? $num[3] + 1 : $num[3];
                }
                else
                        echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
@@ -130,13 +125,13 @@ if ($link){
 else
        echo "<b>Could not connect to SQL database</b><br>\n";
 
-$stats_num[1] = ($stats_num[1]) ? $stats_num[1] : 1;
-$stats_num[2] = ($stats_num[2]) ? $stats_num[2] : 1;
-$stats_num[3] = ($stats_num[3]) ? $stats_num[3] : 1;
+$num[1] = ($num[1]) ? $num[1] : 1;
+$num[2] = ($num[2]) ? $num[2] : 1;
+$num[3] = ($num[3]) ? $num[3] : 1;
 
-$data['avg'][1] = ceil($data['sum'][1] / $stats_num[1]);
-$data['avg'][2] = ceil($data['sum'][2] / $stats_num[2]);
-$data['avg'][3] = ceil($data['sum'][3] / $stats_num[3]);
+$data['avg'][1] = ceil($data['sum'][1] / $num[1]);
+$data['avg'][2] = ceil($data['sum'][2] / $num[2]);
+$data['avg'][3] = ceil($data['sum'][3] / $num[3]);
 
 $data['avg'][1] = $fun[$column[1]]($data['avg'][1]);
 $data['avg'][2] = $fun[$column[2]]($data['avg'][2]);
index 44f19d8..09c0faf 100644 (file)
@@ -29,18 +29,4 @@ body
        scrollbar-highlight-color:#fffff0;
        scrollbar-3dlight-color:#000000;
        scrollbar-darkshadow-color:#000000;
-       bgcolor:#80a040;
-       background-image: url(images/greenlines1.gif);
-}
-a:link {
-       color: #000000;
-}
-a:visited {
-       color:#000000;
-}
-a:hover {
-       color:#000000;
-}
-a:active {
-       color:#000000;
 }
index f362519..81be558 100644 (file)
@@ -15,7 +15,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -31,7 +31,7 @@ $num = 0;
 $pagesize = ($pagesize) ? $pagesize : 10;
 if (!is_numeric($pagesize) && $pagesize != 'all')
        $pagesize = 10;
-$limit = ($pagesize == 'all') ? '' : "$pagesize";
+$limit = ($pagesize == 'all') ? '' : "LIMIT $pagesize";
 $selected[$pagesize] = 'selected';
 $order = ($order != '') ? $order : $config[general_accounting_info_order];
 if ($order != 'desc' && $order != 'asc')
@@ -40,10 +40,6 @@ $selected[$order] = 'selected';
 $now_str = da_sql_escape_string($now_str);
 $prev_str = da_sql_escape_string($prev_str);
 
-unset($da_name_cache);
-if (isset($_SESSION['da_name_cache']))
-       $da_name_cache = $_SESSION['da_name_cache'];
-
 
 echo <<<EOM
 <head>
@@ -51,7 +47,7 @@ echo <<<EOM
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -94,7 +90,7 @@ for($i=1;$i<=9;$i++){
 }
 $sql_extra_query = '';
 if ($config[sql_accounting_extra_query] != '')
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
 ?>
        </tr>
 
@@ -102,10 +98,9 @@ if ($config[sql_accounting_extra_query] != '')
 $link = @da_sql_pconnect($config);
 if ($link){
        $search = @da_sql_query($link,$config,
-       "SELECT " . da_sql_limit($limit,0,$config) . " * FROM $config[sql_accounting_table]
+       "SELECT * FROM $config[sql_accounting_table]
        WHERE username = '$login' AND acctstarttime <= '$now_str'
-       AND acctstarttime >= '$prev_str' $sql_extra_query " . da_sql_limit($limit,1,$config) .
-       " ORDER BY acctstarttime $order " . da_sql_limit($limit,2,$config). " ;");
+       AND acctstarttime >= '$prev_str' $sql_extra_query ORDER BY acctstarttime $order $limit;");
        if ($search){
                while( $row = @da_sql_fetch_array($search,$config) ){
                        $tr_color='white';
index e29f644..9db3177 100644 (file)
@@ -16,7 +16,7 @@ if (is_file("../lib/$config[general_lib_type]/user_info.php3")){
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <form action="user_admin.php3" method=get>
 <b>User Name&nbsp;&nbsp;</b>
@@ -38,7 +38,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -214,9 +214,9 @@ if ($link){
        }
 
        $search = @da_sql_query($link,$config,
-       "SELECT " . da_sql_limit(1,0,$config) . " * FROM $config[sql_accounting_table]
-       WHERE username = '$login' AND acctstoptime IS NULL " . da_sql_limit(1,1,$config) . "
-        ORDER BY acctstarttime DESC " . da_sql_limit(1,2,$config). " ;");
+       "SELECT * FROM $config[sql_accounting_table]
+       WHERE username = '$login' AND acctstoptime IS NULL
+       ORDER BY acctstarttime DESC LIMIT 1;");
        if ($search){
                if (@da_sql_num_rows($search,$config)){
                        $logged_now = 1;
@@ -229,11 +229,11 @@ if ($link){
                                $remaining = $remaining - $lastlog_session_time;
                                if ($remaining < 0)
                                        $remaining = 0;
-                               $log_color = ($remaining) ? 'green' : 'red';
+                               $log_color = ($remaining) ? 'green' : 'red'; 
                        }
                        $lastlog_session_time_jvs = 1000 * $lastlog_session_time;
                        $lastlog_session_time = time2strclock($lastlog_session_time);
-                       $lastlog_client_ip = $row['framedipaddress'];
+                       $lastlog_client_ip = $row['framedipaddress'];   
                        $lastlog_server_name = @gethostbyaddr($lastlog_server_ip);
                        $lastlog_client_name = @gethostbyaddr($lastlog_client_ip);
                        $lastlog_callerid = $row['callingstationid'];
@@ -255,9 +255,9 @@ if ($link){
                echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
        if (! $logged_now){
                $search = @da_sql_query($link,$config,
-               "SELECT " . da_sql_limit(1,0,$config) . " * FROM $config[sql_accounting_table]
-               WHERE username = '$login' AND acctsessiontime != '0' " . da_sql_limit(1,1,$config) . "
-                ORDER BY acctstoptime DESC " . da_sql_limit(1,2,$config). " ;");
+               "SELECT * FROM $config[sql_accounting_table]
+               WHERE username = '$login' AND acctsessiontime != '0'
+               ORDER BY acctstoptime DESC LIMIT 1;");
                if ($search){
                        if (@da_sql_num_rows($search,$config)){
                                $row = @da_sql_fetch_array($search,$config);
@@ -265,7 +265,7 @@ if ($link){
                                $lastlog_server_ip = $row['nasipaddress'];
                                $lastlog_server_port = $row['nasportid'];
                                $lastlog_session_time = time2str($row['acctsessiontime']);
-                               $lastlog_client_ip = $row['framedipaddress'];
+                               $lastlog_client_ip = $row['framedipaddress'];   
                $lastlog_server_name = ($lastlog_server_ip != '') ? @gethostbyaddr($lastlog_server_ip) : '-';
                $lastlog_client_name = ($lastlog_client_ip != '') ? @gethostbyaddr($lastlog_client_ip) : '-';
                                $lastlog_callerid = $row['callingstationid'];
@@ -320,4 +320,3 @@ EOM;
 }
 
 require('../html/user_admin.html.php3');
-?>
index 35f2128..f6da8e7 100644 (file)
@@ -24,7 +24,7 @@ echo <<<EOM
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -58,7 +58,7 @@ print <<<EOM
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
 EOM;
-
+   
 if ($delete_user == 1){
        if ($user_type != 'group'){
                if (is_file("../lib/$config[general_lib_type]/delete_user.php3"))
@@ -80,7 +80,7 @@ EOM;
 }
 ?>
    <form method=post>
-      <input type=hidden name=login value=<?php print $login ?>>
+      <input type=hidden name=login value="<?php print $login ?>">
       <input type=hidden name=delete_user value="0">
        <table border=1 bordercolordark=#ffffe0 bordercolorlight=#000000 width=100% cellpadding=2 cellspacing=0 bgcolor="#ffffe0" valign=top>
 <tr>
index bdb32a9..d8251d9 100644 (file)
@@ -1,19 +1,14 @@
 <?php
 require('../conf/config.php3');
+if ($edit_group == 1){
+       header("Location: group_admin.php3?login=$group_to_edit");
+       exit;
+}
 require('../lib/attrshow.php3');
 require('../lib/defaults.php3');
-$extra_text = '';
 if ($user_type != 'group'){
        if (is_file("../lib/$config[general_lib_type]/user_info.php3"))
                include("../lib/$config[general_lib_type]/user_info.php3");
-       if ($config[general_lib_type] == 'sql' && $config[sql_show_all_groups] == 'true'){
-               $extra_text = "<br><font size=-2><i>(The groups that the user is a member of are highlated)</i></font>";
-               $saved_login = $login;
-               $login = '';
-               if (is_file("../lib/sql/group_info.php3"))
-                       include("../lib/sql/group_info.php3");
-               $login = $saved_login;
-       }
 }
 else{
        if (is_file("../lib/$config[general_lib_type]/group_info.php3"))
@@ -44,7 +39,7 @@ else
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -57,7 +52,7 @@ else
 if ($user_type != 'group')
        include("../html/user_toolbar.html.php3");
 else
-       include("../html/group_toolbar.html.php3");
+       include("../html/group_toolbar.html.php3");     
 
 print <<<EOM
 </table>
@@ -77,20 +72,16 @@ print <<<EOM
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
 EOM;
-
+   
 if ($change == 1){
        if (is_file("../lib/$config[general_lib_type]/change_attrs.php3"))
                include("../lib/$config[general_lib_type]/change_attrs.php3");
        if ($user_type != 'group'){
-               if ($config[general_show_user_password] != 'no' && $passwd != ''
+               if ($config[general_show_user_password] != 'no' && $passwd != '' 
                        && is_file("../lib/$config[general_lib_type]/change_passwd.php3"))
                        include("../lib/$config[general_lib_type]/change_passwd.php3");
                if (is_file("../lib/$config[general_lib_type]/user_info.php3"))
                        include("../lib/$config[general_lib_type]/user_info.php3");
-               if ($group_change && $config[general_lib_type] == 'sql' && $config[sql_show_all_groups] == 'true'){
-                       include("../lib/sql/group_change.php3");
-                       include("../lib/defaults.php3");
-               }
        }
        else{
                if (is_file("../lib/$config[general_lib_type]/group_info.php3"))
@@ -101,15 +92,14 @@ else if ($badusers == 1){
        if (is_file("../lib/add_badusers.php3"))
                include("../lib/add_badusers.php3");
 }
-
+       
 ?>
    <form name="edituser" method=post>
-      <input type=hidden name=login value=<?php print $login ?>>
+      <input type=hidden name=login value="<?php print $login ?>">
       <input type=hidden name=user_type value=<?php print $user_type ?>>
       <input type=hidden name=change value="0">
       <input type=hidden name=add value="0">
       <input type=hidden name=badusers value="0">
-      <input type=hidden name=group_change value="0">
        <table border=1 bordercolordark=#ffffe0 bordercolorlight=#000000 width=100% cellpadding=2 cellspacing=0 bgcolor="#ffffe0" valign=top>
 <?php
 if ($user_type == 'group')
@@ -171,7 +161,7 @@ EOM;
                                $vals[] = $default_vals["$key"][$i];
                                $ops[] = $default_vals["$key"][operator][$i];
                        }
-               }
+               }       
                if ($add && $name == $add_attr){
                        $vals[] = $default_vals["$key"][0];
                        $ops[] = ($default_vals["$key"][operator][0] != '') ? $default_vals["$key"][operator][0] : '=';
@@ -251,25 +241,20 @@ EOM;
 if (isset($member_groups)){
        echo <<<EOM
 <tr>
+<input type=hidden name=edit_group value=0>
 <td align=right colspan=$colspan bgcolor="#d0ddb0">
-Member of $extra_text
+Member of
 </td>
 <td>
-<select size=2 name="edited_groups[]" multiple OnChange="this.form.group_change.value=1">
+<select name="group_to_edit">
 EOM;
-       if ($config[sql_show_all_groups] == 'true'){
-               foreach ($existing_groups as $group => $count){
-                       if ($member_groups[$group] == $group)
-                               echo "<option selected value=\"$group\">$group\n";
-                       else
-                               echo "<option value=\"$group\">$group\n";
-               }
-       }else{
-               foreach ($member_groups as $group)
-                       echo "<option value=\"$group\">$group\n";
+       foreach ($member_groups as $group){
+               echo "<option value=\"$group\">$group\n";
        }
        echo <<<EOM
 </select>
+&nbsp;&nbsp;&nbsp;
+<input type=submit class=button value="Edit Group" OnClick="this.form.edit_group.value=1">
 </td>
 </tr>
 EOM;
index f190c0b..a79021d 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 require('../conf/config.php3');
 require('../lib/attrshow.php3');
-require('../lib/sql/nas_list.php3');
 if (!isset($usage_summary)){
        echo <<<EOM
 <html>
@@ -22,14 +21,14 @@ if ($config[general_decode_normal_attributes] == 'yes'){
        $k = init_decoder();
        $decode_normal = 1;
 }
-require_once('../lib/functions.php3');
+require('../lib/functions.php3');
 require("../lib/$config[general_lib_type]/functions.php3");
 
 if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
        include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
 else{
        echo <<<EOM
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -41,10 +40,8 @@ EOM;
 $date = strftime('%A, %e %B %Y, %T %Z');
 
 $sql_extra_query = '';
-if ($config[sql_accounting_extra_query] != ''){
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
-       $sql_extra_query = da_sql_escape_string($sql_extra_query);
-}
+if ($config[sql_accounting_extra_query] != '')
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
 
 $link = @da_sql_pconnect($config);
 $link2 = connect2db($config);
@@ -52,10 +49,7 @@ $tot_in = $tot_rem = 0;
 if ($link){
        $h = 21;
        $servers_num = 0;
-       if ($config[general_ld_library_path] != '')
-               putenv("LD_LIBRARY_PATH=$config[general_ld_library_path]");
        foreach($nas_list as $nas){
-               $j = 0;
                $num = 0;
 
                if ($server != ''){
@@ -66,62 +60,46 @@ if ($link){
                }
                else
                        $servers_num++;
-               if ($nas[ip] == '')
-                       continue;
                $name_data = $nas[ip];
                $community_data = $nas[community];
                $server_name[$servers_num] = $nas[name];
                $server_model[$servers_num] = $nas[model];
+               if ($config[general_ld_library_path] != '')
+                       putenv("LD_LIBRARY_PATH=$config[general_ld_library_path]");
                $extra = "";
-               $finger_type = $config[general_finger_type];
-               if ($nas[finger_type] != '')
-                       $finger_type = $nas[finger_type];
-               if ($finger_type == 'snmp'){
-                       $nas_type = ($nas[type] != '') ? $nas[type] : $config[general_nas_type];
+               if ($config[$finger_type] != 'database' && $config[general_finger_type] == 'snmp'){
+                       if ($config[$nas_type] == '')
+                               $nas_type = $config[general_nas_type];
+                       else
+                               $nas_type = $nas[type];
                        if ($nas_type == '')
                                $nas_type = 'cisco';
 
                        $users=exec("$config[general_snmpfinger_bin] $name_data $community_data $nas_type");
-                       if (strlen($users)){
+                       if (strlen($users))
                                $extra = "AND username IN ($users)";
-                               if ($config[general_strip_realms] == 'yes'){
-                                       if ($config[general_realm_format] == 'prefix')
-                                               $match = "'[^']+" . $config[general_realm_delimiter];
-                                       else
-                                               $match = $config[general_realm_delimiter] . "[^']+'";
-                                       $extra = preg_replace("/$match/","'",$extra);
-                               }
-                       }
-               }
-               $search = @da_sql_query($link,$config,
-               "SELECT COUNT(*) AS onlineusers FROM $config[sql_accounting_table] WHERE
-               acctstoptime IS NULL AND nasipaddress = '$name_data' $extra $sql_extra_query;");
-               if ($search){
-                       if (($row = @da_sql_fetch_array($search,$config)))
-                               $num = $row[onlineusers];
                }
                $search = @da_sql_query($link,$config,
                "SELECT DISTINCT username,acctstarttime,framedipaddress,callingstationid
                FROM $config[sql_accounting_table] WHERE
                acctstoptime IS NULL AND nasipaddress = '$name_data' $extra $sql_extra_query
-               GROUP BY username,acctstarttime,framedipaddress,callingstationid
-               ORDER BY acctstarttime;");
+               GROUP BY username ORDER BY acctstarttime;");
                if ($search){
                        $now = time();
                        while($row = @da_sql_fetch_array($search,$config)){
-                               $j++;
+                               $num++;
                                $h += 21;
                                $user = $row['username'];
-                               $finger_info[$servers_num][$j]['ip'] = $row['framedipaddress'];
-                               if ($finger_info[$servers_num][$j]['ip'] == '')
-                                       $finger_info[$servers_num][$j]['ip'] = '-';
+                               $finger_info[$servers_num][$num]['ip'] = $row['framedipaddress'];
+                               if ($finger_info[$servers_num][$num]['ip'] == '')
+                                       $finger_info[$servers_num][$num]['ip'] = '-';
                                $session_time = $row['acctstarttime'];
                                $session_time = date2timediv($session_time,$now);
-                               $finger_info[$servers_num][$j]['session_time'] = time2strclock($session_time);
-                               $finger_info[$servers_num][$j]['user'] = $user;
-                               $finger_info[$servers_num][$j]['callerid'] = $row['callingstationid'];
-                               if ($finger_info[$servers_num][$j]['callerid'] == '')
-                                       $finger_info[$servers_num][$j]['callerid'] = '-';
+                               $finger_info[$servers_num][$num]['session_time'] = time2strclock($session_time);
+                               $finger_info[$servers_num][$num]['user'] = $user;
+                               $finger_info[$servers_num][$num]['callerid'] = $row['callingstationid'];
+                               if ($finger_info[$servers_num][$num]['callerid'] == '')
+                                       $finger_info[$servers_num][$num]['callerid'] = '-';
                                if ($user_info["$user"] == ''){
                                        $user_info["$user"] = get_user_info($link2,$user,$config,$decode_normal,$k);
                                        if ($user_info["$user"] == '' || $user_info["$user"] == ' ')
@@ -130,7 +108,6 @@ if ($link){
                        }
                        $height[$servers_num] = $h;
                }
-               $server_counting[$servers_num] = $j;
                $server_loggedin[$servers_num] = $num;
                $server_rem[$servers_num] = ($config[$portnum]) ? ($config[$portnum] - $num) : 'unknown';
                $tot_in += $num;
@@ -146,7 +123,7 @@ if (isset($usage_summary)){
 }
 ?>
 
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -189,18 +166,17 @@ echo <<<EOM
        <th>name</th><th>duration</th>
        </tr>
 EOM;
-       for( $k = 1; $k <= $server_counting[$j]; $k++){
+       for( $k = 1; $k <= $server_loggedin[$j]; $k++){
                $user = $finger_info[$j][$k][user];
                if ($user == '')
                        $user = '&nbsp;';
-               $User = urlencode($user);
                $time = $finger_info[$j][$k][session_time];
                $ip = $finger_info[$j][$k][ip];
                $cid = $finger_info[$j][$k][callerid];
                $inf = $user_info[$user];
                echo <<<EOM
        <tr align=center>
-       <td>$k</td><td><a href="user_admin.php3?login=$User" title="Edit User $user">$user</a></td>
+       <td>$k</td><td><a href="user_admin.php3?login=$user" title="Edit User $user">$user</a></td>
 EOM;
 if ($acct_attrs['uf'][4] != '') echo "<td>$ip</td>\n";
 if ($acct_attrs['uf'][9] != '') echo "<td>$cid</td>\n";
index 18cb42b..03d8266 100644 (file)
@@ -8,7 +8,7 @@ require('../conf/config.php3');
 <title>Personal information page</title>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
@@ -49,7 +49,7 @@ if (is_file("../lib/$config[general_lib_type]/user_info.php3"))
 <tr bgcolor="black" valign=top><td colspan=2>
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
-
+   
    <form method=post>
       <input type=hidden name=login value="<?php echo $login?>">
       <input type=hidden name=change value="0">
index 5ac54de..091b826 100644 (file)
@@ -23,7 +23,7 @@ if ($config[general_lib_type] == 'sql' && $config[sql_use_operators] == 'true'){
 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $config[general_charset]?>">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 
 <?php
 include("password_generator.jsc");
@@ -50,7 +50,7 @@ include("password_generator.jsc");
 <tr bgcolor="black" valign=top><td colspan=2>
        <table border=0 width=100% cellpadding=12 cellspacing=0 bgcolor="#ffffd0" valign=top>
        <tr><td>
-
+   
 <?php
 if ($create == 1){
        if (is_file("../lib/$config[general_lib_type]/user_info.php3"))
index 0e5ec31..233c19d 100644 (file)
@@ -25,8 +25,6 @@ $week = $now - date('w') * 86400;
 $now_str = date("$config[sql_date_format]",$now + 86400);
 $week_str = date("$config[sql_date_format]",$week);
 $today = date("$config[sql_date_format]",$now);
-$open_conns = $daily_conns = $weekly_conns = 0;
-$weekly_used = $daily_used = $online_time = time2strclock(0);
 
 $link = @da_sql_pconnect($config);
 if ($link){
@@ -35,43 +33,24 @@ if ($link){
        username = '$login' AND acctstoptime >= '$week_str' AND
        acctstoptime <= '$now_str';");
        if ($search){
-               if ($row = @da_sql_fetch_array($search,$config)){
-                       $weekly_used = time2strclock($row[sum_sess_time]);
-                       $weekly_conns = $row[counter];
-               }
+               $row = @da_sql_fetch_array($search,$config);
+               $weekly_used = time2strclock($row[sum_sess_time]);
+               $weekly_conns = $row[counter];
        }
        $search = @da_sql_query($link,$config,
        "SELECT COUNT(*) AS counter,sum(acctsessiontime) AS sum_sess_time FROM $config[sql_accounting_table] WHERE
        username = '$login' AND acctstoptime >= '$today 00:00:00'
        AND acctstoptime <= '$today 23:59:59';");
        if ($search){
-               if ($row = @da_sql_fetch_array($search,$config)){
-                       $daily_used = time2strclock($row[sum_sess_time]);
-                       $daily_conns = $row[counter];
-               }
+               $row = @da_sql_fetch_array($search,$config);
+               $daily_used = time2strclock($row[sum_sess_time]);
+               $daily_conns = $row[counter];
        }
-       $search = @da_sql_query($link,$config,
-       "SELECT COUNT(*) AS counter, unix_timestamp() - unix_timestamp(acctstarttime) as diff FROM
-       $config[sql_accounting_table] WHERE acctstoptime is null AND username = '$login'
-       GROUP BY username;");
-       if ($search){
-               if ($row = @da_sql_fetch_array($search,$config)){
-                       $open_conns = $row[counter];
-                       $online_time = $row[diff];
-                       $weekly_used += $online_time;
-                       $daily_used += $online_time;
-                       $daily_conns += $open_conns;
-                       $weekly_conns += $open_conns;
-                       $online_time = time2strclock($online_time);
-               }
-       }
-       $weekly_used = time2strclock($weekly_used);
-       $daily_used = time2strclock($daily_used);
 }
 
 
 foreach($vars as $val){
        echo "$val\n";
 }
-echo "$weekly_used\n$weekly_conns\n$daily_used\n$daily_conns\n$open_conns\n$online_time";
+echo "$weekly_used\n$weekly_conns\n$daily_used\n$daily_conns";
 ?>
index 556e1fe..d1b29db 100644 (file)
@@ -1,8 +1,6 @@
 <?php
 require('../conf/config.php3');
 require('../lib/functions.php3');
-require('../lib/sql/nas_list.php3');
-require_once('../lib/xlat.php3');
 ?>
 <html>
 <?php
@@ -15,7 +13,7 @@ else{
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <b>Could not include SQL library functions. Aborting</b>
 </body>
@@ -34,10 +32,8 @@ $start = da_sql_escape_string($start);
 $stop = da_sql_escape_string($stop);
 $pagesize = ($pagesize) ? $pagesize : 10;
 if (!is_numeric($pagesize) && $pagesize != 'all')
-       $pagezise = 10;
-if ($pagesize > 100)
-       $pagesize = 100;
-$limit = ($pagesize == 'all') ? '100' : "$pagesize";
+       $pagesize = 10;
+$limit = ($pagesize == 'all') ? '' : "LIMIT $pagesize";
 $selected[$pagesize] = 'selected';
 $order = ($order) ? $order : $config[general_accounting_info_order];
 if ($order != 'desc' && $order != 'asc')
@@ -56,14 +52,8 @@ $selected[$order] = 'selected';
 $selected[$sortby] = 'selected';
 
 $sql_extra_query = '';
-if ($config[sql_accounting_extra_query] != ''){
-       $sql_extra_query = xlat($config[sql_accounting_extra_query],$login,$config);
-       $sql_extra_query = da_sql_escape_string($sql_extra_query);
-}
-
-unset($da_name_cache);
-if (isset($_SESSION['da_name_cache']))
-       $da_name_cache = $_SESSION['da_name_cache'];
+if ($config[sql_accounting_extra_query] != '')
+       $sql_extra_query = sql_xlat($config[sql_accounting_extra_query],$login,$config);
 
 ?>
 
@@ -71,7 +61,7 @@ if (isset($_SESSION['da_name_cache']))
 <title>User Statistics</title>
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -110,9 +100,9 @@ EOM;
 $link = @da_sql_pconnect($config);
 if ($link){
        $search = @da_sql_query($link,$config,
-       "SELECT " . da_sql_limit($limit,0,$config) . " * FROM $config[sql_total_accounting_table]
-       WHERE acctdate >= '$start' AND acctdate <= '$stop' $server_str $login_str $sql_extra_query " . da_sql_limit($limit,1,$config)
-       . " ORDER BY $order_attr $order " . da_sql_limit($limit,2,$config) . " ;");
+       "SELECT * FROM $config[sql_total_accounting_table]
+       WHERE acctdate >= '$start' AND acctdate <= '$stop' $server_str $login_str $sql_extra_query
+       ORDER BY $order_attr $order $limit;");
 
        if ($search){
                while( $row = @da_sql_fetch_array($search,$config) ){
@@ -120,10 +110,8 @@ if ($link){
                        $acct_login = $row[username];
                        if ($acct_login == '')
                                $acct_login = '-';
-                       else{
-                               $Acct_login = urlencode($acct_login);
-                               $acct_login = "<a href=\"user_admin.php3?login=$Acct_login\" title=\"Edit user $acct_login\">$acct_login</a>";
-                       }
+                       else
+                               $acct_login = "<a href=\"user_admin.php3?login=$acct_login\" title=\"Edit user $acct_login\">$acct_login</a>";
                        $acct_time = $row[conntotduration];
                        $acct_time = time2str($acct_time);
                        $acct_conn_num = $row[connnum];
@@ -206,8 +194,6 @@ EOM;
 <?php
 foreach ($nas_list as $nas){
        $name = $nas[name];
-       if ($nas[ip] == '')
-               continue;
        $servers[$name] = $nas[ip];
 }
 ksort($servers);
index 9630521..34ed715 100644 (file)
@@ -13,7 +13,7 @@ echo <<<EOM
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 <link rel="stylesheet" href="style.css">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <center>
 <table border=0 width=550 cellpadding=0 cellspacing=0>
 <tr valign=top>
@@ -70,7 +70,7 @@ if ($test_user == 1){
        $req=file($config[general_auth_request_file]);
        if ($config[general_ld_library_path] != '')
                putenv("LD_LIBRARY_PATH=$config[general_ld_library_path]");
-       $comm = $config[general_radclient_bin] . " $server:$port" . ' auth ' . $config[general_radius_server_secret]
+       $comm = $config[general_radclient_bin] . " $server:$port" . ' auth ' . $config[general_radius_server_secret] 
                . ' >' . $tmp_file;
        $fp = popen("$comm","w");
        if ($fp){
index 2777723..7a7b9db 100644 (file)
@@ -12,15 +12,15 @@ function myout(a) {
 }
 </script>
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <form action="user_admin.php3" method=get target="content">
 <table border=0 width=100 cellpadding=1 cellspacing=1>
 <tr><td align=center>
 <img src="images/logo2.gif" vspace=2>
 </td></tr>
 <?php
-if ($_SERVER["PHP_AUTH_USER"])
-       echo "<tr valign=top><td align=center><b>Logged in as " . $_SERVER["PHP_AUTH_USER"] . "...</b><br><br></td></tr>\n";
+if ($HTTP_SERVER_VARS["PHP_AUTH_USER"])
+       echo "<tr valign=top><td align=center><b>Logged in as " . $HTTP_SERVER_VARS["PHP_AUTH_USER"] . "...</b><br><br></td></tr>\n";
 ?>
 <tr bgcolor="black" valign=top><td>
 <table border=0 width=100% cellpadding=2 cellspacing=0>
index c31d599..0763565 100644 (file)
@@ -1,13 +1,12 @@
 <?php
-$Login = urlencode($login);
 print <<<EOM
 <tr valign=top>
 <td align=center bgcolor="black" width=100>
-<a href="group_admin.php3?login=$Login" title="Administer Group"><font color="white"><b>ADMIN</b></font></a></td>
+<a href="group_admin.php3?login=$login" title="Administer Group"><font color="white"><b>ADMIN</b></font></a></td>
 <td align=center bgcolor="black" width=100>
-<a href="user_edit.php3?login=$Login&user_type=group" title="Edit Group Dialup Settings"><font color="white"><b>EDIT</b></font></a></td>
+<a href="user_edit.php3?login=$login&user_type=group" title="Edit Group Dialup Settings"><font color="white"><b>EDIT</b></font></a></td>
 <td align=center bgcolor="black" width=100>
-<a href="user_delete.php3?login=$Login&user_type=group" title="Delete Group"><font color="white"><b>DELETE</b></font></a></td>
+<a href="user_delete.php3?login=$login&user_type=group" title="Delete Group"><font color="white"><b>DELETE</b></font></a></td>
 </tr>
 EOM;
 ?>
index a793531..ce1809e 100644 (file)
@@ -61,7 +61,7 @@ EOM;
        <tr>
                <td colspan=2>
                <center>
-               statistics for
+               statistics for 
 <?php
 if ($login == '')
        echo <<<EOM
@@ -84,7 +84,7 @@ EOM;
        <tr>    <td colspan=2><hr size=1 noshade>
                </td>
                </tr>
-
+               
        </table>
        </td>
        </tr>
index e600369..2f1f85b 100644 (file)
@@ -4,7 +4,7 @@ echo <<<EOM
 <title>user information for $cn</title>
 <meta http-equiv="Content-Type" content="text/html; charset=$config[general_charset]">
 </head>
-<body>
+<body bgcolor="#80a040" background="images/greenlines1.gif" link="black" alink="black">
 <link rel="stylesheet" href="style.css">
 EOM;
 if ($logged_now)
@@ -13,8 +13,8 @@ if ($logged_now)
 <!--
        var start;
        var our_time;
-
-       function startcounter()
+       
+       function startcounter() 
        {
                var start_date = new Date();
                start = start_date.getTime();
@@ -26,21 +26,21 @@ if ($logged_now)
        {
                var now_date = new Date();
                var diff = now_date.getTime() - start + our_time;
-
+                       
                var hours = parseInt(diff / 3600000);
                if(isNaN(hours)) hours = 0;
-
+                       
                var minutes = parseInt((diff % 3600000) / 60000);
                if(isNaN(minutes)) minutes = 0;
-
+                       
                var seconds = parseInt(((diff % 3600000) % 60000) / 1000);
                if(isNaN(seconds)) seconds = 0;
-
+                       
                var timeValue = " " ;
                timeValue += ((hours < 10) ? "0" : "") + hours;
                timeValue += ((minutes < 10) ? ":0" : ":") + minutes;
                timeValue += ((seconds < 10) ? ":0" : ":") + seconds;
-
+               
                document.online.status.value = timeValue;
                setTimeout("showcounter()", 1000);
        }
@@ -92,7 +92,7 @@ if ($logged_now){
        </td></tr>
        <tr><td align=center bgcolor="#d0ddb0">
        Connection Duration
-       </td><td>
+       </td><td>       
        <input type="text" name="status" size=10 value="$lastlog_session_time">
        </form>
        </td></tr>
@@ -207,7 +207,7 @@ lign=top>
        <tr><td align=center bgcolor="#d0ddb0">Average Upload</td><td>
        $avg_input</td></tr></td></tr>
        <tr><td align=center bgcolor="#d0ddb0">Average Download</td><td>
-       $avg_output</td></tr></td></tr>
+       $avg_output</td></tr></td></tr> 
        </table>
        </table>
 </table>
index b2e0a87..c2a533b 100644 (file)
@@ -2,7 +2,7 @@
 echo <<<EOM
        <tr><td align=center bgcolor="#d0ddb0">
        Server
-       </td><td>
+       </td><td>       
        <b>$lastlog_server_name</b> ($lastlog_server_ip)
        </td></tr>
        <tr><td align=center bgcolor="#d0ddb0">
index 892ee43..8ac6db5 100644 (file)
@@ -1,28 +1,27 @@
 <?php
-$Login = urlencode($login);
 print <<<EOM
 <tr valign=top>
 <td align=center bgcolor="black" width=100>
-<a href="user_admin.php3?login=$Login" title="Show User Information"><font color="white"><b>SHOW</b></font></a></td>
+<a href="user_admin.php3?login=$login" title="Show User Information"><font color="white"><b>SHOW</b></font></a></td>
 <td align=center bgcolor="black" width=100>
-<a href="user_edit.php3?login=$Login" title="Change User Dialup Settings"><font color="white"><b>EDIT</b></font></a></td>
+<a href="user_edit.php3?login=$login" title="Change User Dialup Settings"><font color="white"><b>EDIT</b></font></a></td>
 <td align=center bgcolor="black" width=200 colspan=2>
-<a href="user_info.php3?login=$Login" title="Change User Personal Information"><font color="white"><b>USER INFO</b></font></a></td>
+<a href="user_info.php3?login=$login" title="Change User Personal Information"><font color="white"><b>USER INFO</b></font></a></td>
 </tr>
 <tr valign=top>
 <td align=center bgcolor="black" width=100>
-<a href="user_accounting.php3?login=$Login" title="Show User Accounting Information"><font color="white"><b>ACCOUNTING</b></font></a></td>
+<a href="user_accounting.php3?login=$login" title="Show User Accounting Information"><font color="white"><b>ACCOUNTING</b></font></a></td>
 <td align=center bgcolor="black" width=100>
-<a href="badusers.php3?login=$Login" title="Show User Unauthorized Actions"><font color="white"><b>BADUSERS</b></font></a></td>
+<a href="badusers.php3?login=$login" title="Show User Unauthorized Actions"><font color="white"><b>BADUSERS</b></font></a></td>
 <td align=center bgcolor="black" width=100>
-<a href="user_delete.php3?login=$Login" title="Delete User"><font color="white"><b>DELETE</b></font></a></td>
+<a href="user_delete.php3?login=$login" title="Delete User"><font color="white"><b>DELETE</b></font></a></td>
 <td align=center bgcolor="black" width=100>
-<a href="user_test.php3?login=$Login" title="Test User"><font color="white"><b>TEST</b></font></a></td>
+<a href="user_test.php3?login=$login" title="Test User"><font color="white"><b>TEST</b></font></a></td>
 </tr>
 <tr valign=top>
 <td align=center width=100></td>
 <td align=center bgcolor="black" width=200 colspan=2>
-<a href="clear_opensessions.php3?login=$Login" title="Clear Open User Sessions"><font color="white"><b>OPEN SESSIONS</b></font></a></td>
+<a href="clear_opensessions.php3?login=$login" title="Clear Open User Sessions"><font color="white"><b>OPEN SESSIONS</b></font></a></td>
 <td align=center width=100></td>
 </tr>
 EOM;
index de39327..bb2b0e3 100644 (file)
@@ -1,8 +1,5 @@
 <?php
 #Read sql attribute map
-unset($sql_attrs);
-if (isset($_SESSION['sql_attrs']))
-       $sql_attrs = $_SESSION["sql_attrs"];
 if (!isset($sql_attrs)){
        $ARR = file($config[general_sql_attrs_file]);
        foreach($ARR as $val){
index e68b17b..83bbde5 100644 (file)
@@ -10,8 +10,8 @@ $date=date($config[sql_full_date_format]);
 $lockmsg_name = $attrmap['Dialup-Lock-Msg'] . '0';
 $msg = $$lockmsg_name;
 $admin = '-';
-if ($_SERVER["PHP_AUTH_USER"] != '')
-       $admin = $_SERVER["PHP_AUTH_USER"];
+if ($HTTP_SERVER_VARS["PHP_AUTH_USER"] != '')
+       $admin = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
 if ($msg == '')
        echo "<b>Lock Message should not be empty</b><br>\n";
 else{
@@ -23,7 +23,7 @@ else{
                $link = @da_sql_host_connect($server,$config);
                if ($link){
                        $r = da_sql_query($link,$config,
-                       "INSERT INTO $config[sql_badusers_table] (username,incidentdate,admin,reason)
+                       "INSERT INTO $config[sql_badusers_table] (username,date,admin,reason)
                        VALUES ('$login','$date','$admin','$msg');");
                        if (!$r)
                                echo "<b>SQL Error:" . da_sql_error($link,$config) . "</b><br>\n";
index 98f90e7..e837b60 100644 (file)
@@ -1,12 +1,7 @@
 <?php
-include_once('../lib/xlat.php3');
 #Read user_edit attribute map
-unset($show_attrs);
-if (isset($_SESSION['show_attrs']))
-       $show_attrs = $_SESSION['show_attrs'];
 if (!isset($show_attrs)){
-       $infile = xlat($config[general_user_edit_attrs_file],$login,$config);
-       $ARR = file($infile);
+       $ARR = file($config[general_user_edit_attrs_file]);
        foreach($ARR as $val){
                $val=chop($val);
                if (ereg('^[[:space:]]*#',$val) || ereg('^[[:space:]]*$',$val))
@@ -17,12 +12,8 @@ if (!isset($show_attrs)){
        if ($config[general_use_session] == 'yes')
                session_register('show_attrs');
 }
-unset($acct_attrs);
-if (isset($_SESSION['acct_attrs']))
-       $acct_attrs = $_SESSION['acct_attrs'];
 if (!isset($acct_attrs) && isset($config[general_accounting_attrs_file])){
-       $infile = xlat($config[general_accounting_attrs_file],$login,$config);
-       $ARR = file($infile);
+       $ARR = file($config[general_accounting_attrs_file]);
        foreach ($ARR as $val){
                $val=chop($val);
                if (ereg('^[[:space:]]*#',$val) || ereg('^[[:space:]]*$',$val))
index c821fa2..6aec80c 100644 (file)
@@ -1,8 +1,4 @@
 <?php
-unset($text_default_vals);
-unset($default_vals);
-if (isset($_SESSION['text_default_vals']))
-       $text_default_vals = $_SESSION['text_default_vals'];
 if (!isset($text_default_vals)){
        $ARR=file("$config[general_default_file]");
        foreach($ARR as $val) {
index f3bda86..c0cd1ce 100644 (file)
@@ -35,16 +35,7 @@ function time2strclock($time)
        if (!$time)
                return "00:00:00";
 
-       $str["days"] = $str["hour"] = $str["min"] = $str["sec"] = "00";
-
-       $d = $time/86400;
-       $d = floor($d);
-       if ($d){
-               if ($d < 10)
-                       $d = "0" . $d;
-               $str["days"] = "$d";
-               $time = $time % 86400;
-       }
+       $str["hour"] = $str["min"] = $str["sec"] = "00";
        $h = $time/3600;
        $h = floor($h);
        if ($h){
@@ -68,10 +59,7 @@ function time2strclock($time)
        else
                $time = "00";
        $str["sec"] = "$time";
-       if ($str["days"] != "00")
-               $ret = "$str[days]:$str[hour]:$str[min]:$str[sec]";
-       else
-               $ret = "$str[hour]:$str[min]:$str[sec]";
+       $ret = "$str[hour]:$str[min]:$str[sec]";
 
        return $ret;
 }
@@ -122,14 +110,4 @@ function check_defaults($val,$op,$def)
 
        return 0;
 }
-
-function check_ip($ipaddr) {
-    if(ereg("^([0-9]{1,3})\x2E([0-9]{1,3})\x2E([0-9]{1,3})\x2E([0-9]{1,3})$", $ipaddr,$digit)) {
-         if(($digit[1] <= 255) && ($digit[2] <= 255) && ($digit[3] <= 255) && ($digit[4] <= 255)) {
-        return(1);
-      }
-    }
-    return(0);
-  }
-
 ?>
index c79b6c4..6469c86 100644 (file)
@@ -1,8 +1,5 @@
 <?php
 #Read ldap attribute map
-unset($attrmap);
-if (isset($_SESSION['attrmap']))
-       $attrmap = $_SESSION['attrmap'];
 if (!isset($attrmap)){
        $ARR = file("$config[general_ldap_attrmap]");
        foreach($ARR as $val){
index 1ac4f1a..60b2f57 100644 (file)
@@ -15,7 +15,7 @@ require_once('../lib/ldap/functions.php3');
                                $i = 0;
                                $j = -1;
                                $name = $attrmap["$key"] . $i;
-
+               
                                while (isset($$name)){
                                        $val = $$name;
                                        $i++;
@@ -36,7 +36,7 @@ require_once('../lib/ldap/functions.php3');
 //     if values is the same as the default or if the value is null and the ldap attribute exists
 //     then delete them
 //
-                                       if ((check_defaults($val,'',$default_vals["$key"]) || $val == '') &&
+                                       if ((check_defaults($val,'',$default_vals["$key"]) || $val == '') && 
                                                isset($item_vals["$key"][$j]))
                                                $del[$attrmap["$key"]][] = $item_vals["$key"][$j];
 //
index 492ab14..4e37504 100644 (file)
@@ -23,7 +23,7 @@ require_once('../lib/ldap/functions.php3');
                        $mod['givenname'] = ($decode_normal) ? encode_string($mod['givenname'],$k) : $mod['givenname'];
                                $mod['sn'] = $sn;
                                $mod['sn'] = ($decode_normal) ? encode_string($mod['sn'],$k) : $mod['sn'];
-
+                               
                        }
                        if ($Fmail != '' && $Fmail != '-' && $Fmail != $mail)
                                $mod['mail'] = $Fmail;
index 9db4af2..3583098 100644 (file)
@@ -28,7 +28,7 @@ if ($config[ldap_default_dn] != ''){
                if ($regular_profile_attr != ''){
                        $get_attrs = array("$regular_profile_attr");
                        if ($config[ldap_filter] != '')
-                               $filter = xlat($config[ldap_filter],$login,$config);
+                               $filter = ldap_xlat($config[ldap_filter],$login,$config);
                        else
                                $filter = 'uid=' . $login;
                        if ($config[ldap_debug] == 'true')
index 3d24e7e..5b9e4a3 100644 (file)
@@ -2,10 +2,6 @@
 require_once('../lib/ldap/functions.php3');
 $ds=@ldap_connect("$config[ldap_server]");  // must be a valid ldap server!
 if ($ds) {
-       if (!is_numeric($max))
-               $max = 10;
-       if ($max > 500)
-               $max = 10;
        $r=@da_ldap_bind($ds,$config);
        if ($search_IN == 'name' || $search_IN == 'ou')
                $attr = ($search_IN == 'name') ? 'cn' : 'ou';
@@ -15,7 +11,7 @@ if ($ds) {
        }
        if ($config[ldap_debug] == 'true')
                print "<b>DEBUG(LDAP): Search Query: BASE='$config[ldap_base]',FILTER='$attr=*$search*'</b><br>\n";
-       $sr=@ldap_search($ds,"$config[ldap_base]", "$attr=*$search*",array('uid'),0,$max);
+       $sr=@ldap_search($ds,"$config[ldap_base]", "$attr=*$search*",array('uid'),0,$max_results);
        if (($info = @ldap_get_entries($ds, $sr))){
                for ($i = 0; $i < $info["count"]; $i++)
                        $found_users[] = $info[$i]['uid'][0];
index 72592dd..6cb3ad5 100644 (file)
@@ -1,12 +1,24 @@
 <?php
-require_once('../lib/xlat.php3');
+function ldap_xlat($filter,$login,$config)
+{
+       $string = $filter;
+       if ($filter != ''){
+               $string = preg_replace('/%u/',$login,$string);
+               $string = preg_replace('/%U/',$HTTP_SERVER_VARS["PHP_AUTH_USER"],$string);
+               $string = preg_replace('/%ma/',$mappings[$http_user][accounting],$string);
+               $string = preg_replace('/%mu/',$mappings[$http_user][userdb],$string);
+       }
+
+       return $string;
+}
 
 function da_ldap_bind($ds,$config)
 {
        if ($ds){
                if ($config[ldap_use_http_credentials] == 'yes'){
-                       $din = $_SERVER["PHP_AUTH_USER"];
-                       $pass = $_SERVER["PHP_AUTH_PW"];
+                       global $HTTP_SERVER_VARS;
+                       $din = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
+                       $pass = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
                        if ($config[ldap_map_to_directory_manager] != '' &&
                        $din == $config[ldap_map_to_directory_manager] &&
                        $config[ldap_directory_manager] != '')
@@ -54,12 +66,12 @@ function get_user_info($ds,$user,$config,$decode_normal,$k)
                $attrs = array('cn');
                if ($config[ldap_userdn] == ''){
                        if ($config[ldap_filter] != '')
-                               $filter = xlat($config[ldap_filter],$login,$config);
+                               $filter = ldap_xlat($config[ldap_filter],$login,$config);
                        else
                                $filter = 'uid=' . $login;
                }
                else
-                       $filter = xlat($config[ldap_userdn],$login,$config);
+                       $filter = ldap_xlat($config[ldap_userdn],$login,$config);
                if ($config[ldap_debug] == 'true'){
                        if ($config[ldap_userdn] == '')
        print "<b>DEBUG(LDAP): Search Query: BASE='$config[ldap_base]',FILTER='$filter'</b><br>\n";
@@ -86,12 +98,12 @@ function get_user_dn($ds,$user,$config)
                $attrs = array('dn');
                if ($config[ldap_userdn] == ''){
                        if ($config[ldap_filter] != '')
-                               $filter = xlat($config[ldap_filter],$login,$config);
+                               $filter = ldap_xlat($config[ldap_filter],$login,$config);
                        else
                                $filter = 'uid=' . $login;
                }
                else
-                       $filter = xlat($config[ldap_userdn],$login,$config);
+                       $filter = ldap_xlat($config[ldap_userdn],$login,$config);
                if ($config[ldap_debug] == 'true'){
                        if ($config[ldap_userdn] == '')
        print "<b>DEBUG(LDAP): Search Query: BASE='$config[ldap_base]',FILTER='$filter'</b><br>\n";
@@ -123,7 +135,7 @@ function check_user_passwd($dn,$passwd,$config)
                return FALSE;
 
        return FALSE;
-}
+}      
 
 function closedb($ds,$config)
 {
index 6939bd1..45116b8 100644 (file)
@@ -23,9 +23,6 @@ $homephone = '-';
 $mobile = '-';
 $mail = '-';
 $mailalt = '-';
-$dn = '';
-$user_exists = 'no';
-unset($item_vals);
 
 if ($config[general_decode_normal_attributes] == 'yes')
        $decode_normal = 1;
@@ -35,12 +32,12 @@ if ($ds) {
        $r=@da_ldap_bind($ds,$config);
        if ($config[ldap_userdn] == ''){
                if ($config[ldap_filter] != '')
-                       $filter = xlat($config[ldap_filter],$login,$config);
+                       $filter = ldap_xlat($config[ldap_filter],$login,$config);
                else
                        $filter = 'uid=' . $login;
        }
        else
-               $filter = xlat($config[ldap_userdn],$login,$config);
+               $filter = ldap_xlat($config[ldap_userdn],$login,$config);
        if ($config[ldap_debug] == 'true'){
                if ($config[ldap_userdn] == '')
                        print "<b>DEBUG(LDAP): Search Query: BASE='$config[ldap_base]',FILTER='$filter'</b><br>\n";
@@ -58,6 +55,7 @@ if ($ds) {
        else{
                $user_exists = 'yes';
                $user_info = 1;
+               unset($item_vals);
                $k = init_decoder();
                $cn = ($info[0]['cn'][0]) ? $info[0]['cn'][0] : '-';
                if ($decode_normal)
diff --git a/dialup_admin/lib/missing.php3 b/dialup_admin/lib/missing.php3
deleted file mode 100644 (file)
index af2bb8e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-function array_change_key_case($input,$case)
-{
-       $NEW_ARR = array();
-       foreach ($input as $val => $key){
-               if ($case == CASE_UPPER)
-                       $K = strtoupper($key);
-               else if ($case == CASE_LOWER)
-                       $K = strtolower($key);
-               $NEW_ARR[$K] = $val;
-       }
-
-       return $NEW_ARR;
-}
index 20cb6e0..95525cb 100644 (file)
@@ -22,7 +22,7 @@ $op_nexst = '!*';
 function check_operator($op,$type)
 {
        switch($op){
-               case '=':
+               case '=': 
                case ':=':
                case '+=':
                        return 0;
index ae3a5cd..b4c02ef 100644 (file)
@@ -1,37 +1,12 @@
 <?php
 #Read sql attribute map
-unset($attrmap);
-unset($rev_attrmap);
-unset($attr_type);
-if (isset($_SESSION['attrmap'])){
-       #If attrmap is set then the rest will also be set
-        $attrmap = $_SESSION['attrmap'];
-       $rev_attrmap =$_SESSION['rev_attrmap'];
-       $attr_type = $_SESSION['attr_type'];
-}
-else{
-       $ARR = file("$config[general_sql_attrmap]");
-       foreach($ARR as $val){
-               $val=chop($val);
-               if (ereg('^[[:space:]]*#',$val) || ereg('^[[:space:]]*$',$val))
-                       continue;
-               list($type,$key,$v)=split('[[:space:]]+',$val);
-               $attrmap["$key"]=$v;
-               $rev_attrmap["$v"] = $key;
-               $attr_type["$key"]=$type;
-       }
-       if (isset($show_attrs)){
-               foreach($show_attrs as $key => $desc){
-                       if ($attrmap["$key"] == ''){
-                               $attrmap["$key"] = $key;
-                               $attr_type["key"] = 'replyItem';
-                               $rev_attrmap["$key"] = $key;
-                       }
-               }
-       }
-       if ($config[general_use_session] == 'yes'){
-               session_register('attrmap');
-               session_register('rev_attrmap');
-               session_register('attr_type');
-       }
+$ARR = file("$config[general_sql_attrmap]");
+foreach($ARR as $val){
+       $val=chop($val);
+       if (ereg('^[[:space:]]*#',$val) || ereg('^[[:space:]]*$',$val))
+               continue;
+       list($type,$key,$v)=split('[[:space:]]+',$val);
+       $attrmap["$key"]=$v;
+       $rev_attrmap["$v"] = $key;
+       $attr_type["$key"]=$type;
 }
index 04f99f6..1c80c2b 100644 (file)
@@ -46,16 +46,14 @@ if ($link){
                        if ($use_ops){
                                $op_val = $$op_name;
                                if ($op_val != ''){
-                                       $op_val = da_sql_escape_string($op_val);
                                        if (check_operator($op_val,$type) == -1){
                                                echo "<b>Invalid operator ($op_val) for attribute $key</b><br>\n";
                                                continue;
                                        }
+                                       $op_val1 = "'$op_val'";
                                        $op_val2 = ",'$op_val'";
                                }
                        }
-                       $sql_attr = da_sql_escape_string($sql_attr);
-                       $val = da_sql_escape_string($val);
        // if we have operators, the operator has changed and the corresponding value exists then update
                        if ($use_ops && isset($item_vals["$key"][operator][$j]) &&
                                $op_val != $item_vals["$key"][operator][$j] ){
@@ -76,14 +74,13 @@ if ($link){
                                if (!$res || !@da_sql_affected_rows($link,$res,$config))
                                        echo "<b>Delete failed for attribute $key: " . da_sql_error($link,$config) . "</b><br>\n";
                        }
-       //      if value is null or equals the default value then don't add it
+       //      if value is null or equals the default value then don't add it 
                        else if ($val == '' || check_defaults($val,$op_val,$default_vals["$key"]))
                                continue;
        //      if value differs from the sql value then update
                        else{
                                if (isset($item_vals["$key"][$j])){
                                        $old_val = $item_vals["$key"][$j];
-                                       $old_val = da_sql_escape_string($old_val);
                                        $res = @da_sql_query($link,$config,
                                        "UPDATE $table SET value = '$val' WHERE $query_key = '$login' AND
                                        attribute = '$sql_attr' AND value = '$old_val';");
index c519a1f..5485b3f 100644 (file)
@@ -50,7 +50,7 @@ if ($link){
        }
        else
                echo "<b>Cannot use the user info table. Check the sql_use_user_info_table directive in admin.conf</b><br>\n";
-
+       
 }
 else
        echo "<b>Could not connect to SQL database</b><br>\n";
index e80a827..856b17b 100644 (file)
@@ -5,10 +5,10 @@ else{
        echo "<b>Could not include SQL library</b><br>\n";
        exit();
 }
-if ($config[sql_use_operators] == 'true'){
+if ($config[sql_use_operator] == 'true'){
        $text1 = ',op';
        $text2  = ",':='";
-       $text3 = ", op = ':='";
+       $text3 = "AND op = ':='";
 }
 else{
        $text1 = '';
@@ -20,7 +20,6 @@ if ($link){
        if (is_file("../lib/crypt/$config[general_encryption_method].php3")){
                include("../lib/crypt/$config[general_encryption_method].php3");
                $passwd = da_encrypt($passwd);
-               $passwd = da_sql_escape_string($passwd);
                $res = @da_sql_query($link,$config,
                        "SELECT value FROM $config[sql_check_table] WHERE username = '$login'
                        AND attribute = '$config[sql_password_attribute]';");
@@ -31,7 +30,7 @@ if ($link){
                                "UPDATE $config[sql_check_table] SET value = '$passwd' $text3 WHERE
                                attribute = '$config[sql_password_attribute]' AND username = '$login';");
                                if (!$res || !@da_sql_affected_rows($link,$res,$config))
-                                       echo "<b>Error while changing password: " . da_sql_error($link,$config) . "</b><br>\n";
+                                       echo "<b>Error while changing password: " . da_sql_error($link,$config) . "</b><br>\n"; 
                        }
                        else{
                                $res = @da_sql_query($link,$config,
index 0539b99..c602d64 100644 (file)
@@ -12,7 +12,6 @@ if ($config[sql_use_operators] == 'true'){
        $passwd_op = ",':='";
 }
 $da_abort=0;
-$op_val2 = '';
 $link = @da_sql_pconnect($config);
 if ($link){
        $Members = preg_split("/[\n\s]+/",$members,-1,PREG_SPLIT_NO_EMPTY);
@@ -27,9 +26,15 @@ if ($link){
                                $da_abort=1;
                        }
                }
+       } else {
+               $res = @da_sql_query($link,$config,
+               "INSERT INTO $config[sql_usergroup_table] (groupname)
+               VALUES ('$login');");
+               if (!$res || !@da_sql_affected_rows($link,$res,$config)){
+                       echo "<b>Unable to create group $login: " . da_sql_error($link,$config) . "</b><br>\n";
+                       $da_abort=1;
+               }
        }
-       else
-               echo "<b>Members list is empty!!</b><br>\n";
        if (!$da_abort){
                foreach($show_attrs as $key => $attr){
                        if ($attrmap["$key"] == 'none')
@@ -52,7 +57,6 @@ if ($link){
                        $op_name = $attrmap["$key"] . '_op';
                        $op_val = $$op_name;
                        if ($op_val != ''){
-                               $op_val = da_sql_escape_string($op_val);
                                if (check_operator($op_val,$type) == -1){
                                        echo "<b>Invalid operator ($op_val) for attribute $key</b><br>\n";
                                        coninue;
@@ -67,8 +71,8 @@ if ($link){
                        if (!$res || !@da_sql_affected_rows($link,$res,$config))
                                echo "<b>Query failed for attribute $key: " . da_sql_error($link,$config) . "</b><br>\n";
                }
-               echo "<b>Group created successfully</b><br>\n";
        }
+       echo "<b>Group created successfully</b><br>\n";
 }
 else
        echo "<b>Could not connect to SQL database</b><br>\n";
index 6896081..ab6131d 100644 (file)
@@ -12,13 +12,11 @@ if ($config[sql_use_operators] == 'true'){
        $passwd_op = ",':='";
 }
 $da_abort=0;
-$op_val2 = '';
 $link = @da_sql_pconnect($config);
 if ($link){
        if (is_file("../lib/crypt/$config[general_encryption_method].php3")){
                include("../lib/crypt/$config[general_encryption_method].php3");
                $passwd = da_encrypt($passwd);
-               $passwd = da_sql_escape_string($passwd);
                $res = @da_sql_query($link,$config,
                "INSERT INTO $config[sql_check_table] (attribute,value,username $text)
                VALUES ('$config[sql_password_attribute]','$passwd','$login' $passwd_op);");
@@ -37,7 +35,7 @@ if ($link){
                                        $Fou = da_sql_escape_string($Fou);
                                        $Fhomephone = da_sql_escape_string($Fhomephone);
                                        $Fworkphone = da_sql_escape_string($Fworkphone);
-                                       $Fmobile = da_sql_escape_string($Fmobile);
+                                       $Fmobile = da_sql_escape_string($Fmobile);      
                                        $res = @da_sql_query($link,$config,
                                        "INSERT INTO $config[sql_user_info_table]
                                        (username,name,mail,department,homephone,workphone,mobile) VALUES
@@ -94,7 +92,6 @@ if ($link){
                                $op_name = $attrmap["$key"] . '_op';
                                $op_val = $$op_name;
                                if ($op_val != ''){
-                                       $op_val = da_sql_escape_string($op_val);
                                        if (check_operator($op_val,$type) == -1){
                                                echo "<b>Invalid operator ($op_val) for attribute $key</b><br>\n";
                                                coninue;
index 21ea439..f201ebe 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 require('../lib/sql/attrmap.php3');
-if ($login != '' && $user_type != 'group'){
+if ($login != ''){
        if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
                include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
        else{
@@ -27,19 +27,15 @@ if ($login != '' && $user_type != 'group'){
                        $res = @da_sql_query($link,$config,
                        "SELECT groupname FROM $config[sql_usergroup_table] WHERE username = '$login';");
                        if ($res){
-                               while(($row = @da_sql_fetch_array($res,$config))){
-                                       $group = $row[groupname];
-                                       $member_groups[$group] = $group;
-                               }
-                               if (isset($member_groups))
-                                       ksort($member_groups);
+                               while(($row = @da_sql_fetch_array($res,$config)))
+                                       $member_groups[] = $row[groupname];
                        }
                        if (isset($member_groups)){
                                $in = '(';
                                foreach ($member_groups as $group)
                                        $in .= "'$group',";
                                $in = substr($in,0,-1);
-                               $in .= ')';
+                               $in .= ')';     
                                $res = @da_sql_query($link,$config,
                                "SELECT attribute,value $op FROM $config[sql_groupcheck_table]
                                WHERE groupname IN $in;");
diff --git a/dialup_admin/lib/sql/drivers/dbx/functions.php3 b/dialup_admin/lib/sql/drivers/dbx/functions.php3
deleted file mode 100644 (file)
index 11890d0..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-function da_sql_limit($limit,$point,$config)
-{
-       switch($point){
-               case 0:
-                       return '';
-               case 1:
-                       return '';
-               case 2:
-                       return "LIMIT $limit";
-       }
-}
-
-function da_sql_host_connect($server,$config)
-{
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-       // FIXME: This function is still Postgres specific. Needs to be configurable.
-       return @dbx_connect(DBX_PGSQL, "$server", "$config[sql_database]",
-                       "$SQL_user", "$SQL_passwd", DBX_PERSISTENT);
-}
-
-function da_sql_connect($config)
-{
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-       // FIXME: This function is still Postgres specific. Needs to be configurable.
-       return @dbx_connect(DBX_PGSQL, "$server", "$config[sql_database]",
-                       "$SQL_user", "$SQL_passwd");
-}
-
-function da_sql_pconnect($config)
-{
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-       // FIXME: This function is still Postgres specific. Needs to be configurable.
-       return @dbx_connect(DBX_PGSQL, "$server", "$config[sql_database]",
-                       "$SQL_user", "$SQL_passwd", DBX_PERSISTENT);
-}
-
-function da_sql_close($link,$config)
-{
-       @dbx_close($link);
-}
-
-function da_sql_escape_string($string)
-{
-       return addslashes($string);
-}
-
-function da_sql_query($link,$config,$query)
-{
-       if ($config[sql_debug] == 'true') {
-               print "<b>DEBUG(SQL,PG DRIVER): Query: <i>$query</i></b><br>\n";
-       }
-       return @dbx_query($link,$query);
-}
-
-function da_sql_num_rows($result,$config)
-{
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,PG DRIVER): Query Result: Num rows:: " . $result->rows . "</b><br>\n";
-       return $result->rows;
-}
-
-$dbx_global_record_counter = array() ;
-function da_sql_fetch_array($result,$config)
-{
-
-       global $dbx_global_record_counter;
-       if (!$dbx_global_record_counter[$result->handle]){
-               $dbx_global_record_counter[$result->handle] = 0;
-       }
-
-       if ($dbx_global_record_counter[$result->handle] <= $result->rows - 1 ){
-               return $result->data[$dbx_global_record_counter[$result->handle]++];
-       } elseif ($dbx_global_record_counter[$result->handle] > $result->rows - 1 ) {
-               $dbx_global_record_counter[$result->handle]++;
-               return NULL;
-       } else {
-               $dbx_global_record_counter[$result->handle]++;
-               return FALSE;
-       }
-}
-
-function da_sql_affected_rows($link,$result,$config)
-{
-       // FIXME: This function is still Postgres specific.
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,PG DRIVER): Query Result: Affected rows:: " . @pg_cmdtuples($result->handle) . "</b><br>\n";
-       return @pg_cmdtuples($result->handle);
-}
-
-function da_sql_list_fields($table,$link,$config)
-{
-       $res = @dbx_query($link,"SELECT * FROM ".$table." LIMIT 1 ;");
-       if ($res){
-               $fields[num] = $res->cols;
-       }
-       $res = @dbx_query($link,"SELECT * FROM ".$table." LIMIT 1 ;");
-       if ($res)
-               $fields[res] = $res->info[name];
-       else
-               return NULL;
-
-       return $fields;
-}
-
-function da_sql_num_fields($fields,$config)
-{
-       if ($fields)
-               return $fields[num];
-}
-
-function da_sql_field_name($fields,$num,$config)
-{
-       if ($fields)
-               return $fields[res][$num];
-}
-
-function da_sql_error($link,$config)
-{
-       return dbx_error($link);
-}
-?>
index ce5e2c9..8f313c6 100644 (file)
@@ -1,16 +1,4 @@
 <?php
-function da_sql_limit($limit,$point,$config)
-{
-       switch($point){
-               case 0:
-                       return '';
-               case 1:
-                       return '';
-               case 3:
-                       return "LIMIT $limit";
-       }
-}
-
 function da_sql_host_connect($server,$config)
 {
        if ($config[sql_use_http_credentials] == 'yes'){
@@ -23,10 +11,6 @@ function da_sql_host_connect($server,$config)
                $SQL_passwd = $config[sql_password];
        }
 
-       if ($config[sql_connect_timeout] != 0)
-               @ini_set('mysql.connect_timeout',$config[sql_connect_timeout]);
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,MYSQL DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
        return @mysql_connect("$server:$config[sql_port]",$SQL_user,$SQL_passwd);
 }
 
@@ -44,8 +28,6 @@ function da_sql_connect($config)
 
        if ($config[sql_connect_timeout] != 0)
                @ini_set('mysql.connect_timeout',$config[sql_connect_timeout]);
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,MYSQL DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
        return @mysql_connect("$config[sql_server]:$config[sql_port]",$SQL_user,$SQL_passwd);
 }
 
@@ -63,8 +45,6 @@ function da_sql_pconnect($config)
 
        if ($config[sql_connect_timeout] != 0)
                @ini_set('mysql.connect_timeout',$config[sql_connect_timeout]);
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,MYSQL DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
        return @mysql_pconnect("$config[sql_server]:$config[sql_port]",$SQL_user,$SQL_passwd);
 }
 
diff --git a/dialup_admin/lib/sql/drivers/oracle/functions.php3 b/dialup_admin/lib/sql/drivers/oracle/functions.php3
deleted file mode 100644 (file)
index 194266f..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-// $Id$
-function da_sql_limit($limit,$point,$config)
-{
-       switch($point){
-               case 0:
-                       return '';
-               case 1:
-                       return "AND ROWNUM <= $limit";
-               case 2:
-                       return '';
-       }
-}
-
-function da_sql_host_connect($server,$config)
-{
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-       $link = @ocilogon($SQL_user, $SQL_passwd, $config[sql_database]);
-        $res = @da_sql_query($link,$config,"ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM'");
-       return $link;
-}
-
-function da_sql_connect($config)
-{
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-       $link = @ocilogon($SQL_user, $SQL_passwd, $config[sql_database]);
-        $res = @da_sql_query($link,$config,"ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM'");
-       return $link;
-}
-
-function da_sql_pconnect($config)
-{
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-       $link = @ociplogon($SQL_user, $SQL_passwd, $config[sql_database]);
-        $res = @da_sql_query($link,$config,"ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS.FF TZH:TZM'");
-       return $link;
-}
-
-function da_sql_close($link,$config)
-{
-       @ociclose($link);
-}
-
-function da_sql_escape_string($string)
-{
-       return addslashes($string);
-}
-
-function da_sql_query($link,$config,$query)
-{
-       $trimmed_query = rtrim($query, ";");
-       if ($config[sql_debug] == 'true') {
-               print "<b>DEBUG(SQL,OCI DRIVER): Query: <i>$trimmed_query</i></b><br>\n";
-       }
-       $statement = OCIParse($link,$trimmed_query);
-       OCIExecute($statement);
-       return $statement;
-}
-
-function da_sql_num_rows($statement,$config)
-{
-       // Unfortunately we need to fetch the statement as ocirowcount doesn't work on SELECTs
-       $rows = OCIFetchStatement($statement,$res);
-
-        if ($config[sql_debug] == 'true'){
-                print "<b>DEBUG(SQL,OCI DRIVER): Query Result: Num rows:: " . $rows . "</b><br>\n";
-        }
-       // Unfortunately we need to re-execute because the statement cursor is reset after OCIFetchStatement :-(
-       OCIExecute($statement);
-        return $rows;
-}
-
-
-function da_sql_fetch_array($statement,$config)
-{
-       OCIFetchInto($statement, $temprow, OCI_ASSOC);
-       $row = array_change_key_case($temprow, CASE_LOWER);
-        if ($config[sql_debug] == 'true') {
-                print "<b>DEBUG(SQL,OCI DRIVER): Query Result: <pre>";
-                print_r($row);
-                print "</b></pre>\n";
-        }
-        return $row;
-}
-
-
-function da_sql_affected_rows($link,$statement,$config)
-{
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,OCI DRIVER): Query Result: Affected rows:: " . @ocirowcount($statement) . "</b><br>\n";
-       return @ocirowcount($statement);
-}
-
-function da_sql_list_fields($table,$link,$config)
-{
-        $res = @da_sql_query($link,$config,"SELECT * from $table WHERE ROWNUM <=1");
-        if ($res){
-               $fields[res]=Array();
-               for ($i = 1;$i<=ocinumcols($res);$i++) {
-                       array_push($fields[res],strtolower(OCIColumnName($res,$i)));
-               }
-                $fields[num]=@ocinumcols($res);
-        }else{
-                return NULL;
-        }
-        return $fields;
-}
-
-function da_sql_num_fields($fields,$config)
-{
-        return $fields[num];
-}
-
-function da_sql_field_name($fields,$num,$config)
-{
-       return $fields[res][$num];
-}
-
-function da_sql_error($link,$config)
-{
-       return ocierror($link);
-}
-?>
index 4f85653..ec20319 100644 (file)
@@ -1,15 +1,4 @@
 <?php
-function da_sql_limit($limit,$point,$config)
-{
-       switch($point){
-               case 0:
-                       return '';
-               case 1:
-                       return '';
-               case 2:
-                       return "LIMIT $limit";
-       }
-}
 function da_sql_host_connect($server,$config)
 {
        if ($config[sql_use_http_credentials] == 'yes'){
@@ -21,8 +10,6 @@ function da_sql_host_connect($server,$config)
                $SQL_user = $config[sql_username];
                $SQL_passwd = $config[sql_password];
        }
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,PG DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
        return @pg_connect("host=$server port=$config[sql_port]
                        dbname=$config[sql_database] user=$SQL_user
                        password=$SQL_passwd");
@@ -39,8 +26,6 @@ function da_sql_connect($config)
                $SQL_user = $config[sql_username];
                $SQL_passwd = $config[sql_password];
        }
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,PG DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
        return @pg_connect("host=$config[sql_server] port=$config[sql_port]
                        dbname=$config[sql_database] user=$SQL_user
                        password=$SQL_passwd");
@@ -57,8 +42,6 @@ function da_sql_pconnect($config)
                $SQL_user = $config[sql_username];
                $SQL_passwd = $config[sql_password];
        }
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,PG DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
        return @pg_pconnect("host=$config[sql_server] port=$config[sql_port]
                        dbname=$config[sql_database] user=$SQL_user
                        password=$SQL_passwd");
@@ -78,7 +61,7 @@ function da_sql_query($link,$config,$query)
 {
        if ($config[sql_debug] == 'true')
                print "<b>DEBUG(SQL,PG DRIVER): Query: <i>$query</i></b><br>\n";
-       return @pg_query($link,$query);
+       return @pg_exec($link,$query);
 }
 
 function da_sql_num_rows($result,$config)
@@ -110,7 +93,7 @@ function da_sql_affected_rows($link,$result,$config)
 
 function da_sql_list_fields($table,$link,$config)
 {
-       $res = @pg_query($link,
+       $res = @pg_exec($link,
                "select count(*) from pg_attribute where attnum > '0' and
                attrelid = (select oid from pg_class where relname='$table');");
        if ($res){
@@ -121,7 +104,7 @@ function da_sql_list_fields($table,$link,$config)
                        $fields[num] = $row[0];
                }
        }
-       $res = @pg_query($link,
+       $res = @pg_exec($link,
                "select attname from pg_attribute where attnum > '0' and
                attrelid = (select oid from pg_class where relname='$table');");
        if ($res)
@@ -141,7 +124,7 @@ function da_sql_num_fields($fields,$config)
 function da_sql_field_name($fields,$num,$config)
 {
        if ($fields){
-               $row = @pg_fetch_row($fields[res],$num);
+               $row = @pg_fetch_row($fields[res],$num);        
                if ($row)
                        return $row[0];
        }
diff --git a/dialup_admin/lib/sql/drivers/sqlrelay/functions.php3 b/dialup_admin/lib/sql/drivers/sqlrelay/functions.php3
deleted file mode 100644 (file)
index 9f76451..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-function da_sql_limit($limit,$point,$config)
-{
-       switch($point){
-               case 0:
-                       return '';
-               case 1:
-                       return '';
-               case 2:
-                       return "LIMIT $limit";
-       }
-}
-
-function da_sql_host_connect($server,$config)
-{
-       $retrytime = 0;
-
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-
-       if ($config[sql_connect_timeout] != 0)
-               $retrytime = $config[sql_connect_timeout];
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
-       $link[con] = @sqlrcon_alloc($server,$port,'',$SQL_user,$SQL_passwd,$retrytime,1);
-       if ($link[con]){
-               $link[cur] = @sqlrcur_alloc($link[con]);
-               if ($link[cur])
-                       return $link;
-               else
-                       return 0;
-       }
-       else
-               return 0;
-}
-
-function da_sql_connect($config)
-{
-       $retrytime = 0;
-
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-
-       if ($config[sql_connect_timeout] != 0)
-               $retrytime = $config[sql_connect_timeout];
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Connect: User=$SQL_user,Password=$SQL_passwd </b><br>\n";
-       $link[con] = @sqlrcon_alloc($config[sql_server],$config[sql_port],'',$SQL_user,$SQL_passwd,$retrytime,1);
-       if ($link[con]){
-               $link[cur] = @sqlrcur_alloc($link[con]);
-               if ($link[cur])
-                       return $link;
-               else
-                       return 0;
-       }
-       else
-               return 0;
-}
-
-function da_sql_pconnect($config)
-{
-       $retrytime = 0;
-
-
-       if ($config[sql_use_http_credentials] == 'yes'){
-               global $HTTP_SERVER_VARS;
-               $SQL_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
-               $SQL_passwd = $HTTP_SERVER_VARS["PHP_AUTH_PW"];
-       }
-       else{
-               $SQL_user = $config[sql_username];
-               $SQL_passwd = $config[sql_password];
-       }
-
-       if ($config[sql_connect_timeout] != 0)
-               $retrytime = $config[sql_connect_timeout];
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Connect: Host=$config[sql_server],Port=$config[sql_port],User=$SQL_user,Password=$SQL_passwd </b><br>\n";
-       $link[con] = sqlrcon_alloc($config[sql_server],$config[sql_port],'',$SQL_user,$SQL_passwd,$retrytime,1);
-       if ($link[con]){
-               sqlrcon_debugOn($link[con]);
-               $link[cur] = sqlrcur_alloc($link[con]);
-               if ($link[cur]){
-                       sqlrcur_setResultSetBufferSize($link[cur], 4);
-                       sqlrcur_lowerCaseColumnNames($link[cur]);
-                       return $link;
-               }
-               else
-                       return false;
-       }
-       else{
-               return false;
-       }
-}
-
-function da_sql_close($link,$config)
-{
-       if (sqlrcur_free($link[cur]))
-               return sqlrcon_free($link[con]);
-       else
-               return 0;
-}
-
-function da_sql_escape_string($string)
-{
-       return addslashes($string);
-}
-
-function da_sql_query($link,$config,$query)
-{
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Query: <i>$query</i></b><br>\n";
-       if (sqlrcur_sendQuery($link[cur],$query)){
-               sqlrcon_endSession($link[con]);
-               $link[count] = sqlrcur_rowCount($link[cur]);
-               return $link;
-       }
-       else{
-               return false;
-       }
-}
-
-function da_sql_num_rows($result,$config)
-{
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Query Result: Num rows:: " . @sqlrcur_rowCount($result[cur]) . "</b><br>\n";
-       return sqlrcur_rowCount($result[cur]);
-       return 0;
-}
-
-function da_sql_fetch_array($result,$config)
-{
-       static $counter = 0;
-       if ($counter < $result[count]){
-               $row = sqlrcur_getRowAssoc($result[cur],$counter);
-               $counter++;
-       }
-       else{
-               $counter = 0;
-               return false;
-       }
-       if ($config[sql_debug] == 'true'){
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Query Result: <pre>";
-       }
-       return $row;
-}
-
-function da_sql_affected_rows($link,$result,$config)
-{
-       if ($config[sql_debug] == 'true')
-               print "<b>DEBUG(SQL,SQLRELAY DRIVER): Query Result: Affected rows:: " . @sqlrcur_affectedRows($result[cur]) . "</b><br>\n";
-       return sqlrcur_affectedRows($result[cur]);
-}
-
-function da_sql_list_fields($table,$link,$config)
-{
-       if (sqlrcur_sendQuery($link[cur],"SELECT * FROM $table WHERE  1 = 0;")){
-               sqlrcon_endSession($link[con]);
-               return $link[cur];
-       }
-       else
-               return false;
-}
-
-function da_sql_num_fields($fields,$config)
-{
-       return sqlrcur_colCount($fields);
-}
-
-function da_sql_field_name($fields,$num,$config)
-{
-       return sqlrcur_getColumnName($fields,$num);
-}
-
-function da_sql_error($link,$config)
-{
-       return sqlrcur_errorMessage($link[cur]);
-}
-?>
index d5b280a..7440c37 100644 (file)
@@ -6,21 +6,16 @@ else{
        exit();
 }
 
-unset($found_users);
-
 $link = @da_sql_pconnect($config);
 if ($link){
        $search = da_sql_escape_string($search);
-       if (!is_numeric($max))
-               $max = 10;
-       if ($max > 500)
-               $max = 10;
-       if (($search_IN == 'name' || $search_IN == 'department' || $search_IN == 'username') &&
-                       $config[sql_use_user_info_table] == 'true'){
+       if (!is_numeric($max_results))
+               $max_results = 10;
+       if (($search_IN == 'name' || $search_IN == 'ou') && $config[sql_use_user_info_table] == 'true'){
+               $attr = ($search_IN == 'name') ? 'name' : 'department';
                $res = @da_sql_query($link,$config,
-               "SELECT " . da_sql_limit($max,0,$config) . " username FROM $config[sql_user_info_table] WHERE
-               lower($search_IN) LIKE '%$search%' " .
-               da_sql_limit($max,1,$config) . " " . da_sql_limit($max,2,$config) . " ;");
+               "SELECT username FROM $config[sql_user_info_table] WHERE
+               lower($attr) LIKE '%$search%' LIMIT $max_results;");
                if ($res){
                        while(($row = @da_sql_fetch_array($res,$config)))
                                $found_users[] = $row[username];
@@ -36,10 +31,8 @@ if ($link){
                }
                $table = ($attr_type[$radius_attr] == 'checkItem') ? $config[sql_check_table] : $config[sql_reply_table];
                $attr = $attrmap[$radius_attr];
-               $attr = da_sql_escape_string($attr);
                $res = @da_sql_query($link,$config,
-               "SELECT " . da_sql_limit($max,0,$config) . " username FROM $table WHERE attribute = '$attr'
-               AND value LIKE '%$search%' " . da_sql_limit($max,1,$config) . " " . da_sql_limit($max,2,$config) . " ;");
+               "SELECT username FROM $table WHERE attribute = '$attr' AND value LIKE '%$search%' LIMIT $max_results;");
                if ($res){
                        while(($row = @da_sql_fetch_array($res,$config)))
                                $found_users[] = $row[username];
index d7178c0..98fdc66 100644 (file)
@@ -5,7 +5,6 @@ else{
        echo "<b>Could not include SQL library</b><br>\n";
        exit();
 }
-require_once('../lib/xlat.php3');
 
 function connect2db($config)
 {
@@ -24,7 +23,7 @@ function get_user_info($link,$user,$config)
                        $row = @da_sql_fetch_array($res,$config);
                        if ($row)
                                return $row[name];
-               }
+               }       
        }
 }
 
@@ -32,4 +31,16 @@ function closedb($link,$config)
 {
        return 1;
 }
+function sql_xlat($filter,$login,$config)
+{
+       $string = $filter;
+       $http_user = $HTTP_SERVER_VARS["PHP_AUTH_USER"];
+       if ($filter != ''){
+               $string = preg_replace('/%u/',$login,$string);
+               $string = preg_replace('/%U/',$http_user,$string);
+               $string = preg_replace('/%m/',$mappings[$http_user],$string);
+       }
+
+       return $string;
+}
 ?>
index c5492ce..6eecd65 100644 (file)
@@ -27,7 +27,7 @@ if ($link){
                                if ($res){
                                        if (@da_sql_num_rows($res,$config))
                                                echo "<b>User $new_member already is a member of the group</b><br>\n";
-                                       else{
+                                       else{   
                                                $res = @da_sql_query($link,$config,
                                                "INSERT INTO $config[sql_usergroup_table] (groupname,username)
                                                VALUES ('$login','$new_member');");
diff --git a/dialup_admin/lib/sql/group_change.php3 b/dialup_admin/lib/sql/group_change.php3
deleted file mode 100644 (file)
index eed00e7..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
-       include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
-else{
-       echo "<b>Could not include SQL library</b><br>\n";
-       exit();
-}
-$link = @da_sql_pconnect($config);
-if ($link){
-       if (isset($member_groups) && isset($edited_groups)){
-               $del_groups = array_diff($member_groups,$edited_groups);
-               if (isset($del_groups)){
-                       foreach ($del_groups as $del){
-                               $del = da_sql_escape_string($del);
-                               $res = @da_sql_query($link,$config,
-                       "DELETE FROM $config[sql_usergroup_table] WHERE username = '$login' AND groupname = '$del';");
-                               if (!$res)
-                                       echo "<b>Could not delete user $login from group $del: " . da_sql_error($link,$config) . "</b><br>\n";
-                               else
-                                       echo "<b>User $login deleted from group $del</b><br>\n";
-                       }
-               }
-               $new_groups = array_diff($edited_groups,$member_groups);
-               if (isset($new_groups)){
-                       foreach($new_groups as $new){
-                               $new = da_sql_escape_string($new);
-                               $res = @da_sql_query($link,$config,
-                               "INSERT INTO $config[sql_usergroup_table] (groupname,username)
-                               VALUES ('$new','$login');");
-                               if (!$res)
-                                       echo "<b>Error while adding user $login to group $login: " . da_sql_error($link,$config) . "</b><br>\n";
-                               else
-                                       echo "<b>User $login added to group $new</b><br>\n";
-                       }
-               }
-       }
-}
-else
-       echo "<b>Could not connect to SQL database</b><br>\n";
-?>
index edb450d..fda77a6 100644 (file)
@@ -14,33 +14,28 @@ if ($config[sql_use_operators] == 'true'){
        $use_op = 0;
 }
 $group_exists = 'no';
+unset($item_vals);
+unset($tmp);
+unset($group_members);
 $link = @da_sql_pconnect($config);
 if ($link){
-       if ($login == ''){
-               unset($existing_groups);
-
-               $res = @da_sql_query($link,$config,
-               "SELECT COUNT(*) as counter,groupname FROM $config[sql_usergroup_table]
-               GROUP BY groupname;");
-               if ($res){
-                       while(($row = @da_sql_fetch_array($res,$config))){
-                               $name = $row[groupname];
-                               $existing_groups["$name"] = $row[counter];
+       $res = @da_sql_query($link,$config,
+       "SELECT attribute,value $op FROM $config[sql_groupcheck_table] WHERE groupname = '$login';");
+       if ($res){
+               if (@da_sql_num_rows($res,$config))
+                       $group_exists = 'yes';
+               while(($row = @da_sql_fetch_array($res,$config))){
+                       $attr = $row[attribute];
+                       $val = $row[value];
+                       if ($use_op){
+                               $oper = $row[op];
+                               $tmp["$attr"][operator][]="$oper";
                        }
-                       if (isset($existing_groups))
-                               ksort($existing_groups);
+                       $tmp["$attr"][]="$val";
+                       $tmp["$attr"][count]++;
                }
-               else
-                       echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
-       }
-       else{
-               unset($item_vals);
-               unset($tmp);
-               unset($group_members);
-               unset($existing_groups);
-
                $res = @da_sql_query($link,$config,
-               "SELECT attribute,value $op FROM $config[sql_groupcheck_table] WHERE groupname = '$login';");
+               "SELECT attribute,value $op FROM $config[sql_groupreply_table] WHERE groupname = '$login';");
                if ($res){
                        if (@da_sql_num_rows($res,$config))
                                $group_exists = 'yes';
@@ -51,60 +46,45 @@ if ($link){
                                        $oper = $row[op];
                                        $tmp["$attr"][operator][]="$oper";
                                }
-                               $tmp["$attr"][]="$val";
+                               $tmp["$attr"][] = "$val";
                                $tmp["$attr"][count]++;
                        }
-                       $res = @da_sql_query($link,$config,
-                       "SELECT attribute,value $op FROM $config[sql_groupreply_table] WHERE groupname = '$login';");
-                       if ($res){
-                               if (@da_sql_num_rows($res,$config))
-                                       $group_exists = 'yes';
-                               while(($row = @da_sql_fetch_array($res,$config))){
-                                       $attr = $row[attribute];
-                                       $val = $row[value];
-                                       if ($use_op){
-                                               $oper = $row[op];
-                                               $tmp["$attr"][operator][]="$oper";
-                                       }
-                                       $tmp["$attr"][] = "$val";
-                                       $tmp["$attr"][count]++;
-                               }
-                       }
-                       else
-                               echo "<b>Database query failed partially: " . da_sql_error($link,$config) . "</b><br>\n";
-                       $res = @da_sql_query($link,$config,
-                       "SELECT username FROM $config[sql_usergroup_table] WHERE groupname = '$login' ORDER BY username;");
-                       if ($res){
-                               if (@da_sql_num_rows($res,$config))
-                                       $group_exists = 'yes';
-                               while(($row = @da_sql_fetch_array($res,$config))){
-                                       $member = $row[username];
-                                       $group_members[] = "$member";
-                               }
+               }
+               else
+                       echo "<b>Database query failed partially: " . da_sql_error($link,$config) . "</b><br>\n";
+               $res = @da_sql_query($link,$config,
+               "SELECT username FROM $config[sql_usergroup_table] WHERE groupname = '$login' ORDER BY username;");
+               if ($res){
+                       if (@da_sql_num_rows($res,$config))
+                               $group_exists = 'yes';
+                       while(($row = @da_sql_fetch_array($res,$config))){
+                               $member = $row[username];
+                               $group_members[] = "$member";
                        }
-                       else
-                               echo "<b>Database query failed partially: " . da_sql_error($link,$config) . "</b><br>\n";
-                       if (isset($tmp)){
-                               foreach(array_keys($tmp) as $val){
-                                       if ($val == '')
-                                               continue;
-                                       $key = $rev_attrmap["$val"];
-                                       if ($key == ''){
-                                               $key = $val;
-                                               $attrmap["$key"] = $val;
-                                               $attr_type["$key"] = 'replyItem';
-                                               $rev_attrmap["$val"] = $key;
-                                       }
-                                       $item_vals["$key"] = $tmp[$val];
-                                       $item_vals["$key"][count] = $tmp[$val][count];
-                                       if ($use_op)
-                                               $item_vals["$key"][operator] = $tmp[$val][operator];
+               }       
+               else
+                       echo "<b>Database query failed partially: " . da_sql_error($link,$config) . "</b><br>\n";
+               if (isset($tmp)){
+                       foreach(array_keys($tmp) as $val){
+                               if ($val == '')
+                                       continue;
+                               $key = $rev_attrmap["$val"];
+                               if ($key == ''){
+                                       $key = $val;
+                                       $attrmap["$key"] = $val;
+                                       $attr_type["$key"] = 'replyItem';
+                                       $rev_attrmap["$val"] = $key;
                                }
+                               $item_vals["$key"] = $tmp[$val];
+                               $item_vals["$key"][count] = $tmp[$val][count];
+                               if ($use_op)
+                                       $item_vals["$key"][operator] = $tmp[$val][operator];
                        }
                }
-               else
-                       echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
+
        }
+       else
+               echo "<b>Database query failed: " . da_sql_error($link,$config) . "</b><br>\n";
 }
 else
        echo "<b>Could not connect to SQL database</b><br>\n";
diff --git a/dialup_admin/lib/sql/nas_list.php3 b/dialup_admin/lib/sql/nas_list.php3
deleted file mode 100644 (file)
index aee4f08..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-require('../conf/config.php3');
-require_once('../lib/functions.php3');
-
-unset($da_name_cache);
-if (isset($_SESSION['da_name_cache']))
-       $da_name_cache = $_SESSION['da_name_cache'];
-if ($config[sql_nas_table] != ''){
-
-       if (is_file("../lib/sql/drivers/$config[sql_type]/functions.php3"))
-               include_once("../lib/sql/drivers/$config[sql_type]/functions.php3");
-       else{
-               echo "<b>Could not include SQL library</b><br>\n";
-               exit();
-       }
-       $link = @da_sql_pconnect($config);
-       if ($link){
-               $auth_user = $_SERVER["PHP_AUTH_USER"];
-               $extra = '';
-               if (isset($mappings[$auth_user][nasdb])){
-                       $NAS_ARR = array();
-                       $NAS_ARR = split(',',$mappings[$auth_user][nasdb]);
-                       $extra = 'WHERE nasname IN (';
-                       foreach ($NAS_ARR as $nas)
-                               $extra .= "'$nasname',";
-                       unset($NAS_ARR);
-                       $extra = rtrim($extra,",");
-                       $extra .= ')';
-               }
-               $search = @da_sql_query($link,$config,
-               "SELECT * FROM $config[sql_nas_table] $extra;");
-               if ($search){
-                       while($row = @da_sql_fetch_array($search,$config)){
-                               $num = 0;
-                               $my_nas_name = $row['nasname'];
-                               if ($my_nas_name != ''){
-                                       $nas_list[$my_nas_name]['name'] = $my_nas_name;
-                                       $nas_server = $da_name_cache[$my_nas_name];
-                                       if (!isset($nas_server)){
-                                               if (!check_ip($my_nas_name))
-                                                       $nas_server = @gethostbyname($my_nas_name);
-                                               else
-                                                       $nas_server = $my_nas_name;
-                                               if (!isset($da_name_cache) && $config[general_use_session] == 'yes'){
-                                                       $da_name_cache[$my_nas_name] = $nas_server;
-                                                       session_register('da_name_cache');
-                                               }
-                                       }
-                                       if ($nas_server != $my_nas_name || check_ip($nas_server))
-                                               $nas_list[$my_nas_name]['ip'] = $nas_server;
-                                       $nas_list[$my_nas_name]['port_num'] = $row['ports'];
-                                       $nas_list[$my_nas_name]['community'] = $row['community'];
-                                       $nas_list[$my_nas_name]['model'] = $row['description'];
-                               }
-                       }
-               }
-       }
-       else
-               echo "<b>Could not connect to SQL database</b><br>\n";
-}
-
-?>
index 582d059..a2f8f11 100644 (file)
@@ -12,13 +12,15 @@ if ($action == 'checkpass'){
        if ($link){
                $res = @da_sql_query($link,$config,
                        "SELECT attribute,value FROM $config[sql_check_table] WHERE username = '$login'
-                       AND attribute = '$config[sql_password_attribute]';");
+                       AND (attribute = 'User-Password' OR attribute = 'Crypt-Password');");
                if ($res){
                        $row = @da_sql_fetch_array($res,$config);
                        if (is_file("../lib/crypt/$config[general_encryption_method].php3")){
                                include("../lib/crypt/$config[general_encryption_method].php3");
                                $enc_passwd = $row[value];
-                               $passwd = da_encrypt($passwd,$enc_passwd);
+                               if ($row[attribute] == 'Crypt-Password') {
+                                       $passwd = da_encrypt($passwd,$enc_passwd);
+                               }
                                if ($passwd == $enc_passwd)
                                        $msg = '<font color=blue><b>YES It is that</b></font>';
                                else
index 0be9587..4c56a29 100644 (file)
@@ -78,7 +78,7 @@ if ($link){
                                                $user_exists = 'yes';
                                                $user_info = 1;
                                        }
-                                       if (($row = @da_sql_fetch_array($res,$config))){
+                                       if (($row = @da_sql_fetch_array($res,$config))){        
                                                $cn = ($row[name] != '') ? $row[name] : '-';
                                                $telephonenumber = ($row[workphone] != '') ? $row[workphone] : '-';
                                                $homephone = ($row[homephone] != '') ? $row[homephone] : '-';
@@ -86,7 +86,7 @@ if ($link){
                                                $mail = ($row[mail] != '') ? $row[mail] : '-';
                                                $mobile = ($row[mobile] != '') ? $row[mobile] : '-';
                                        }
-                               }
+                               }                       
                                else
                                        echo "<b>Database query failed partially: " . da_sql_error($link,$config) . "</b><br>\n";
                        }
diff --git a/dialup_admin/lib/xlat.php3 b/dialup_admin/lib/xlat.php3
deleted file mode 100644 (file)
index ac282ee..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-function xlat($filter,$login,$config)
-{
-       $string = $filter;
-       if ($filter != ''){
-               $string = preg_replace('/%u/',$login,$string);
-               $string = preg_replace('/%U/',$_SERVER["PHP_AUTH_USER"],$string);
-               $string = preg_replace('/%ma/',$mappings[$http_user][accounting],$string);
-               $string = preg_replace('/%mu/',$mappings[$http_user][userdb],$string);
-               $string = preg_replace('/%mn/',$mappings[$http_user][nasdb],$string);
-               $string = preg_replace('/%mN/',$mappings[$http_user][nasadmin],$string);
-       }
-
-       return $string;
-}
-?>
similarity index 80%
rename from dialup_admin/sql/mysql/badusers.sql
rename to dialup_admin/sql/badusers.sql
index c8b5032..c5011b9 100644 (file)
@@ -4,7 +4,7 @@
 CREATE TABLE badusers (
   id int(10) DEFAULT '0' NOT NULL auto_increment,
   UserName varchar(30),
-  IncidentDate datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+  Date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
   Reason varchar(200),
   Admin varchar(30) DEFAULT '-',
   PRIMARY KEY (id),
diff --git a/dialup_admin/sql/oracle/badusers.sql b/dialup_admin/sql/oracle/badusers.sql
deleted file mode 100644 (file)
index 06b0820..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * $Id$
- *
- */
-
-/*
- * Table structure for table 'radcheck'
- */
-
-CREATE TABLE badusers (
-       id              INT PRIMARY KEY,
-       username        VARCHAR(30) DEFAULT '' NOT NULL,
-       incidentdate    TIMESTAMP WITH TIME ZONE DEFAULT sysdate NOT NULL,
-       reason          VARCHAR(128) DEFAULT '' NOT NULL,
-       admin           VARCHAR(128) DEFAULT '-' NOT NULL
-);
-CREATE SEQUENCE badusers_seq START WITH 1 INCREMENT BY 1;
-CREATE INDEX badusers_incidentdate_idx ON badusers (incidentdate);
-CREATE INDEX badusers_username_idx ON badusers (username);
-
-/* Trigger to emulate a serial # on the primary key */
-CREATE OR REPLACE TRIGGER badusers_serialnumber
-        BEFORE INSERT OR UPDATE OF id ON badusers
-        FOR EACH ROW
-        BEGIN
-                if ( :new.id = 0 or :new.id is null ) then
-                        SELECT badusers_seq.nextval into :new.id from dual;
-                end if;
-        END;
-/
-
diff --git a/dialup_admin/sql/oracle/mtotacct.sql b/dialup_admin/sql/oracle/mtotacct.sql
deleted file mode 100644 (file)
index b623ece..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * $Id$
- *
- */
-
-
-/*
- * Table structure for table 'mtotacct'
- */
-CREATE TABLE mtotacct (
-       mtotacctid      INT PRIMARY KEY,
-       username        varchar(64) DEFAULT '' NOT NULL,
-       acctdate        DATE DEFAULT sysdate NOT NULL,
-       connnum         NUMERIC(12),
-       conntotduration NUMERIC(12),
-       connmaxduration NUMERIC(12),
-       connminduration NUMERIC(12),
-       inputoctets     NUMERIC(12),
-       outputoctets    NUMERIC(12),
-       nasipaddress    varchar(15) default NULL
-);
-
-CREATE INDEX mtotacct_acctdate_idx ON mtotacct (acctdate);
-CREATE INDEX mtotacct_nasipaddress_idx ON mtotacct (nasipaddress);
-CREATE INDEX mtotacct_username_idx ON mtotacct (username);
-CREATE INDEX mtotacct_userondate_idx ON mtotacct (username, acctdate);
-
-CREATE SEQUENCE mtotacct_seq START WITH 1 INCREMENT BY 1;
-
-/* Trigger to emulate a serial # on the primary key */
-CREATE OR REPLACE TRIGGER mtotacct_serialnumber
-        BEFORE INSERT OR UPDATE OF mtotacctid ON mtotacct
-        FOR EACH ROW
-        BEGIN
-                if ( :new.mtotacctid = 0 or :new.mtotacctid is null ) then
-                        SELECT mtotacct_seq.nextval into :new.mtotacctid from dual;
-                end if;
-        END;
-/
-
diff --git a/dialup_admin/sql/oracle/totacct.sql b/dialup_admin/sql/oracle/totacct.sql
deleted file mode 100644 (file)
index 144c2f4..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * $Id$
- *
- */
-
-
-/*
- * Table structure for table 'totacct'
- */
-CREATE TABLE totacct (
-        totacctid      INT PRIMARY KEY,
-        username        varchar(64) DEFAULT '' NOT NULL,
-        acctdate        DATE DEFAULT sysdate NOT NULL,
-        connnum         NUMERIC(12),
-        conntotduration NUMERIC(12),
-        connmaxduration NUMERIC(12),
-        connminduration NUMERIC(12),
-        inputoctets     NUMERIC(12),
-        outputoctets    NUMERIC(12),
-        nasipaddress    varchar(15) default NULL
-);
-CREATE INDEX totacct_acctdate_idx ON totacct (acctdate);
-CREATE INDEX totacct_nasipaddress_idx ON totacct (nasipaddress);
-CREATE INDEX totacct_nasondate_idx ON totacct (acctdate, nasipaddress);
-CREATE INDEX totacct_username_idx ON totacct (username);
-CREATE INDEX totacct_userondate_idx ON totacct (username, acctdate);
-
-CREATE SEQUENCE totacct_seq START WITH 1 INCREMENT BY 1;
-
-/* Trigger to emulate a serial # on the primary key */
-CREATE OR REPLACE TRIGGER totacct_serialnumber
-        BEFORE INSERT OR UPDATE OF totacctid ON totacct
-        FOR EACH ROW
-        BEGIN
-                if ( :new.totacctid = 0 or :new.totacctid is null ) then
-                        SELECT totacct_seq.nextval into :new.totacctid from dual;
-                end if;
-        END;
-/
-
diff --git a/dialup_admin/sql/oracle/userinfo.sql b/dialup_admin/sql/oracle/userinfo.sql
deleted file mode 100644 (file)
index 7ecd6cc..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * $Id$
- *
- */
-
-/*
- * Table structure for table 'userinfo'
- */
-
-CREATE TABLE userinfo (
-       id              INT PRIMARY KEY,
-       username        VARCHAR(128) DEFAULT '' NOT NULL,
-       name            VARCHAR(128) DEFAULT '' NOT NULL,
-       mail            VARCHAR(128) DEFAULT '' NOT NULL,
-       department      VARCHAR(128) DEFAULT '' NOT NULL,
-       workphone       VARCHAR(128) DEFAULT '' NOT NULL,
-       homephone       VARCHAR(128) DEFAULT '' NOT NULL,
-       mobile          VARCHAR(128) DEFAULT '' NOT NULL 
-);
-CREATE INDEX userinfo_department_idx ON userinfo (department);
-CREATE INDEX userinfo_username_idx ON userinfo (username);
-CREATE SEQUENCE userinfo_seq START WITH 1 INCREMENT BY 1;
-
-
-/* Trigger to emulate a serial # on the primary key */
-CREATE OR REPLACE TRIGGER userinfo_serialnumber
-        BEFORE INSERT OR UPDATE OF id ON userinfo
-        FOR EACH ROW
-        BEGIN
-                if ( :new.id = 0 or :new.id is null ) then
-                        SELECT userinfo_seq.nextval into :new.id from dual;
-                end if;
-        END;
-/
diff --git a/dialup_admin/sql/postgresql/badusers.sql b/dialup_admin/sql/postgresql/badusers.sql
deleted file mode 100644 (file)
index 93e5ca0..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-SET search_path = public, pg_catalog;
-
---Table structure for table 'badusers'
---
-CREATE TABLE badusers (
-    id BIGSERIAL PRIMARY KEY,
-    username TEXT NOT NULL,
-    incidentdate timestamp with time zone DEFAULT 'now' NOT NULL,
-    reason TEXT,
-    admin TEXT DEFAULT '-'
-);
-CREATE INDEX badusers_incidentdate_idx ON badusers USING btree (incidentdate);
-CREATE INDEX badusers_username_idx ON badusers USING btree (username);
diff --git a/dialup_admin/sql/postgresql/mtotacct.sql b/dialup_admin/sql/postgresql/mtotacct.sql
deleted file mode 100644 (file)
index f8502e1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-SET search_path = public, pg_catalog;
-
---
--- Table structure for table 'mtotacct'
---
-CREATE TABLE mtotacct (
-    mtotacctid BIGSERIAL PRIMARY KEY,
-    username TEXT DEFAULT '' NOT NULL,
-    acctdate DATE DEFAULT 'now' NOT NULL,
-    connnum BIGINT,
-    conntotduration BIGINT,
-    connmaxduration BIGINT,
-    connminduration BIGINT,
-    inputoctets BIGINT,
-    outputoctets BIGINT,
-    nasipaddress INET
-);
-CREATE INDEX mtotacct_acctdate_idx ON mtotacct USING btree (acctdate);
-CREATE INDEX mtotacct_nasipaddress_idx ON mtotacct USING btree
-(nasipaddress);
-CREATE INDEX mtotacct_username_idx ON mtotacct USING btree (username);
-CREATE INDEX mtotacct_userondate_idx ON mtotacct USING btree (username,
-acctdate);
diff --git a/dialup_admin/sql/postgresql/totacct.sql b/dialup_admin/sql/postgresql/totacct.sql
deleted file mode 100644 (file)
index 373aae4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-SET search_path = public, pg_catalog;
-
---
--- Table structure for table 'totacct'
---
-CREATE TABLE totacct (
-    totacctid bigSERIAL PRIMARY KEY,
-    username TEXT DEFAULT '' NOT NULL,
-    acctdate DATE DEFAULT 'now' NOT NULL,
-    connnum BIGINT,
-    conntotduration BIGINT,
-    connmaxduration BIGINT,
-    connminduration BIGINT,
-    inputoctets BIGINT,
-    outputoctets BIGINT,
-    nasipaddress INET
-);
-CREATE INDEX totacct_acctdate_idx ON totacct USING btree (acctdate);
-CREATE INDEX totacct_nasipaddress_idx ON totacct USING btree (nasipaddress);
-CREATE INDEX totacct_nasondate_idx ON totacct USING btree (acctdate,
-nasipaddress);
-CREATE INDEX totacct_username_idx ON totacct USING btree (username);
-CREATE INDEX totacct_userondate_idx ON totacct USING btree (username,
-acctdate);
diff --git a/dialup_admin/sql/postgresql/userinfo.sql b/dialup_admin/sql/postgresql/userinfo.sql
deleted file mode 100644 (file)
index 644bc95..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-SET search_path = public, pg_catalog;
-
---
--- Table structure for table 'userinfo'
---
-CREATE TABLE userinfo (
-    id SERIAL PRIMARY KEY,
-    username TEXT,
-    name TEXT,
-    mail TEXT,
-    department TEXT,
-    workphone TEXT,
-    homephone TEXT,
-    mobile TEXT
-);
-CREATE INDEX userinfo_department_idx ON userinfo USING btree (department);
-CREATE INDEX userinfo_username_idx ON userinfo USING btree (username);
-
-
similarity index 91%
rename from dialup_admin/sql/mysql/userinfo.sql
rename to dialup_admin/sql/userinfo.sql
index ba9d721..aacb4d2 100644 (file)
@@ -12,5 +12,5 @@ CREATE TABLE userinfo (
   Mobile varchar(200),
   PRIMARY KEY (id),
   KEY UserName (UserName),
-  KEY Department (Department)
+  KEY Departmet (Department)
 );
index c4a3bd4..8efdb09 100644 (file)
-FreeRADIUS 2.0.0-pre0 ; $Date$, urgency=low
+FreeRADIUS 1.1.6 ; $Date$, urgency = high
        Feature improvements
-       * Initial pre-release of 2.0.
-       * Debugging mode is much clearer and easier to read.
-       * EAP-TLS and OpenSSL certificates "just work".
-         See raddb/certs/README for details.
-       * Proxying works much better than in 1.x.  We mean *MUCH* better.
-         See proxy.conf for details.
-       * rlm_unix no longer has an "authenticate" section.
-         See "man rlm_unix" for details.
-       * The server has full support for IPv6.
-       * The server has much more complete support for SNMP MIBs.
-       * radiusd.conf has limited support for "if/then/else".
-         See doc/configurable_failover for details.
-       * "listen" sections can have per-socket clients.
-       * Replaced "radrelay" and "radsqlrelay".
-         See "man radrelay.conf" for details.
-       * Post-Proxy-Type "Fail" section is executed when a home server
-         fails to respond to a request.  See "radiusd.conf" for details.
-       * Many internal data structures have been updated to use trees
-         rather than linked lists for performance.
-       * "virtual" modules can now be used.
-         See "virtual" in the "instantiate" section of "radiusd.conf".
-       * The server header files have been cleaned up.
-       * Configuration files can now "$INCLUDE directory/", to automatically
-         load all files in that directory.  Use with caution!
+       * Added dictionary.rfc4372 (Chargeable User Identity)
+       * Added dictionary.rfc4675 (VLAN and Priority)
+       * Added dictionary.rfc4679 (ADSL Forum)
+         NOTE some name differences from the RFC, due to dictionary.redback
+
+       Bug fixes
+       * Corrected typo in rlm_pap.c (closes #440)
+       * Corrected typo in src/main/auth.c (closes #437)
+       * Suppress SSL error messages if error is zero.  (closes #436)
+       * Don't complain about "Error in read client certificate A"
+         if we expect to read it in the next packet.  Fix based on patch
+         by Dan Lukes.
+       * Corrected nearly 30 bugs found by Coverity
+         See also http://scan.coverity.com
+       * Don't die on HUP.  Instead leak memory (sorry).  After a few
+         hundred HUP's, the server will have leaked a few megabytes of
+         memory, and you should probably re-start it.  It's ugly, but
+         better than dying.  (Closes #426)
+       * Corrected a few double free's
+       * Corrected typo in radrelay, which prevented it from working
+       * Made Firebird module build
+       * Fixed bug in PostgreSQL module that caused server crash.
+       * Fixed bug in SQL module that could cause server to crash.
        
+FreeRADIUS 1.1.5 ; Date: 2007/03/05 13:13:43  , urgency=low
+       Feature improvements
+       * Updated rlm_python to something usable
+       * Added experimental sql "HPW" IPPools.
+       * Added more dictionaries
+       * Dictionary files now MUST NOT be globally writable.
+       * Configuration files now MUST NOT be globally readable,
+         or globally writable.
+       * Be more aggressive about freeing memory on clean exit.
+         This helps track down run-time leaks.
+       * Updated rlm_python to something usable
+       * Added experimental sql "HPW" IPPools.
+
+       Bug fixes
+       * Corrected base64 decoding in rlm_pap
+       * Don't retransmit accounting packets.  The NAS should do this.
+       * Handle Client-Error in EAP-SIM.  This closes #419
+       * Port OpenSSL locking fixes from CVS head.  This makes PEAP
+         more stable on some systems.
+       * Require Message-Authenticator in Status-Server packets
+       * Correct Tunnel-Medium-Type VALUEs in dictionary.rfc2868
+       * Be more aggressibe about freeing memory on clean exit.
+         This isn't strictly a bug fix, but it makes it easier to
+         find memory leaks
+       * Increase buffer size for dynamic expansion, which allows
+         longer SQL qeuries.  (close: #405)
+       * Use correct line number when there's a parse error in one
+         of the configuration sections. (close #421)
+       * Terminate SSL sessions in EAP on error, rather than continuing
+         in some cases.
+       * Increase buffer size to allow parsing of long octet strings
+       * Fix string termination on xlat in rlm_perl
+
+FreeRADIUS 1.1.4 ; Date: 2007/01/14 00:37:15 , urgency=medium
+
+       Feature improvements
+       * Major enhancements to rlm_pap, that make "encryption_scheme"
+         a thing of the past.  See "man rlm_pap" for details.
+       * Added SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS flag to use
+         work-arounds that enable Windows Vista clients to work.
+       * Added preliminary code to support Firebird. (closes: #378)
+         Use at your own risk!
+       * Send MS-CHAP2-Success, which makes EAP-TTLS/MSCHAP work on more
+         platforms.  (closes: #402)
+       * Add a new "reply-name" directive in rlm_sqlcounter to define the
+         name of the reply attribute. (closes: #403)
+       * Added more dictionaries and attributes (closes: #408, among others)
+       * Print ntlm_auth failure reason in Module-Failure-Message
+         (closes: #398)
+       * radsqlrelay is able to get the DB password from a file instead
+         of command line. (closes: #395)
+
+       Bug fixes
+       * Fix a parse error in the digest module, where malformed
+         digest requests would result in the user being accepted.  Oops...
+       * VALUEs can only be defined for 'integer', to catch mistakes
+         with setting VALUEs for type 'string'.
+       * Better parsing of VALUE names, so that values starting with
+         a digit work correctly.
+       * Check return from malloc (closes: #407)
+       * Fix a double free() in rlm_eap_tls.c (closes: #404)
+       * Check return code of malloc() during initialization. (closes: #407)
+       * Fix a corner case where the proxy port isn't set either in
+         radiusd.conf or in proxy.conf.
+
+FreeRADIUS 1.1.3 ; Date: 2006/08/22 23:09:20, urgency=low
+
+       Feature improvements
+       * rlm_otp now talks to otpd for OTP verification, rather than
+         doing the work itself; this improves portability and security
+         (access to OTP token keys is now much more limited)
+       * More dictionary updates
+       * Added Oracle support to radsqlrelay
+       * Added experimental module sql_ippool.  See doc/rlm_sqlippool
+
+       Bug fixes
+       * Allow rlm_dbm to load empty check items (Bug #380)
+       * Better handling of Framed-MTU in EAP-TLS (Bug #383)
+       * Handle Access-Challenge verification properly
+       * Fixed configure/make error for Solaris (set HAVE_CLOSEFROM).
+       * Update libtool and ltdl to 1.5.22, to fix 'make install R=';
+         also improve integration by importing unmodified original
+         source (except a small patch to ltdl)
+
+FreeRADIUS 1.1.2 ; Date: 2006/06/23 04:57:51 , urgency=low
+
+       Feature improvements
+       * Allow tagged VSA's for Juniper.  Closes bugs #367 and #368.
+       * Allow Ascend "abinary" format to be specified as octets,
+        (e.g. Ascend-Data-Filter = 0x010203...)
+       * Added "cipher_list" configuration to the EAP-TLS module.
+         See "eap.conf" and "man 1 cipher" for details.
+       * Added "check_cert_issuer" configuration to the EAP-TLS module.
+         See "eap.conf" for details. (closes: #346)
+       * Added "suppress" configuration entry to rlm_detail,
+         to suppress certain attributes (e.g. User-Password).
+         This closes bug #359.
+       * More dictionary updates
+       * Write SSL errors to log file, rather than stderr.
+         This closes bug #347.
+       * Allow a core dump on uid change on Linux (closes: #361)
+
        Bug fixes
-       * 
+       * Return better error codes in SQL IODBC module.  Closes bug #341.
+       * Corrected list of EAP handlers.
+       * Initialize variable in rlm_ldap.c.  This fixes RedHat
+         bug #136468.
+       * Escape more ldap strings, so configuration entries
+         that have magic LDAP characters don't break LDAP.
+         This closes bug #360.
+       * Updated doc/rlm_ldap.  This closes bug #353.
+       * Updated redhat/freeradius.spec.  This closes bug #330.
+       * Don't forcibly over-write Auth-Type in the mschap module.
+         This prevents an earlier module from forcing reject.
+       * Use the correct module reference in the authenticate section,
+         where Auth-Type wasn't explicitely specified.
+       * If there are typos in a subsection in radiusd.conf, exit
+         after printing an error, rather than continuing.
+       * Print Ascend "abinary" format as text rather than octets
+         when we receive it.
+       * Silently drop packets with bad Message-Authenticators, as per RFC3579
+       * Unbreak ./configure --disable-static (closes: #350)
+       * Unbreak ./configure --prefix (closes: #354)
+
+FreeRADIUS 1.1.1 ; Date: 2006/03/17 19:50:34, urgency=low
+
+       Security fixes
+       * Additional state checking in the EAP-MSCHAPv2 module.
+         Bug found by Steffen Schuster.
+       
+       Feature improvements
+       * More dictionary updates
+       * Additional tests and fixes for Digest module from Phillipe Sultan.
+       * Add new "phone" response mode to rlm_otp/cryptocard.
+       * Put the eap sessions into a tree, so that looking them up is very
+         fast, and no longer O(n) in the number of sessions.
+       * Install the schema examples for a set of backends with the rest
+         of the documentation.
+       * Add support for xlat expansion of attributes from LDAP.
+
+       Bug fixes
+       * Fix rlm_perl crash. (closes: #348)
+       * Fix handling of CoA-Request packets (close #344).  Also correct
+         name of CoA packets.
+       * Fix an error on x86_64 machines when reading dictionaries.
+         (closes: #312)
+       * Fix compilation errors on FreeBSD and NetBSD because of rlm_otp
+         module. (closes: #314 #328)
+       * Workaround Cisco bug in State attribute handling in rlm_otp.
+       * Support LP64 for async mode in rlm_otp.
+       * Fix libtool problems on Debian with rlm_eap_peap and rlm_eap_ttls
+         modules. (closes: #75)
+       * Make "use_tunneled_reply" work properly for PEAP.
+       * Copy the whole string when getting a one-to-one-mapped attribute
+         from LDAP (closes: #261)
+       * Fix net-snmp's ucd-snmp compatibility mode.
+
+FreeRADIUS 1.1.0 ; Date: 2006/01/04 05:55:19, urgency=low
+
+       Feature improvements
+       * rlm_ldap has "set_auth_type" configuration option, which should
+         address some configuration problems when using it.
+       * Fix MIT Kerberos bug
+       * Modules can be load balanced, both in isolation and redundantly.
+         See doc/load-balance.txt for more information.
+       * rlm_perl is now marked "stable"
+       * N-tier certificate patch from Mohammed Petiwala.
+       * Copied dictionaries from the CVS head (many, many, more vendors)
+       * Enabled support for weird VSA formats, like Lucent and Starent.
+       * Support encrypted IP address and integers, for Juniper clients.
+       * Add PEAP machine authentication support in module "rlm_mschap".
+       * Support User-Password field encryption in digest mode.
+       * rlm_x99_token has become rlm_otp (with lots of changes).
+       * Add rlm_sqlcounter to the list of stable modules.
+       * Read MySQL specific options in sections [freeradius] and [client]
+         from file "my.cnf".
+       * Support the ${Cisco-AVPair[n]} syntax.
+       * Execute modules in {Pre,Post}-Proxy-Type stanzas.
+       * Add new options to radclient to run stress tests on the server.
+       * New module "rlm_sql_log" to postpone the storage of accounting data
+         in a SQL database. See rlm_sql_log(5) manpage.
+       * New program "radsqlrelay" which sends the SQL logfile according to
+         the SQL server's capabilities.
+
+       Bug fixes
+       * #306 (HUP when built with threads, but executed with -s)
+       * #285 (more attributes in dictionary.cisco.vpn3000)
+       * rlm_digest has a number of bug fixes to authentication types.
+       * Don't leak memory in module "rlm_sql".
+       * Update the dictionaries, so that VALUEs with the same name,
+         but different numbers, aren't allowed.
+       * Queue the request before looking for available threads.
+       * Don't free the check items after we received the proxy reply.
+       * Expand config variables in included files, too.
+       * Check the return value of accounting modules and don't proxy
+         invalid requests.
+       * In rlm_passwd, don't close a file stream more than once.
+       * Fix format string errors in rlm_sql.c, spotted by Primoz Bratanic.
+       * Walk the whole string in when escaping strings in rlm_ldap.
+       * Include crypt.h if it is available so we get a prototype for crypt(),
+         spotted by Konstantin Kubatkin.
+       * Removed (for almost all uses) length restrictions on vendor names
+         and VALUE names.
+       * Don't leak memory when proxying an Access-Challenge response.
+       * Make the sleep time user-defined, so radrelay can send more than
+         7 requests/s.
+       * Fix a memory leak in rlm_checkval.
+       * radclient doesn't resend countless times packets with invalid
+         signature.
+       * Fix segfault and mem leak in rlm_pam.
+
+FreeRADIUS 1.0.5 ; Date: 2005/09/04 16:23:00, urgency=medium
+
+       Security Fixes
+       * SQL injection attack in the module "rlm_sqlcounter".
+       * Buffer overflows in the module "rlm_sqlcounter".
+       * Expansion of variable %t may write 26 bytes beyond the buffer
+         bound. Primoz Bratanic is credited with the discovery of these
+         three bugs.
+
+       Bug fixes
+       * Don't de-reference a NULL pointer if the auth-type is unknown
+         in the function rad_check_password().
+       * Escape more characters in the LDAP queries.
+         Bug found by Suse engineers.
+       * In rlm_sql_unixodbc, don't call rad_malloc from sql_error(),
+         it leaks memory.
+       * Fix an off-by-one error in the module rlm_sql_unixodbc.
+         Bug found by Suse engineers.
+       * In rlm_sql, resize the buffer for the value of SQL-User-Name.
+       * Initialize memory for a new SQL socket in the module rlm_sql.
+       * Don't add too many attributes after running an external program.
+         Bug found by Suse engineers.
+       * Fix an off-by-one error in the function getthing().
+       * snprintf() and vsnprintf() replacements were not compiled if
+         the autoconf tests didn't find the functions.
+       * Don't use vsprintf() anymore, but the replacement for vsnprintf()
+         in libradius instead.
+       * The function decode_attribute() may write beyond buffer bounds.
+         Bug found by Suse engineers.
+       * Fix a memset() in the function request_enqueue() which was
+         begining at the wrong address. Bug found by Matthias Ruttman.
+       * Fix an off-by-one error in the function xlat_copy().
+         Bug found by Primoz Bratanic.
+       * Fix other off-by-one errors in module "rlm_unix", too.
+         Bug found by Allan Bazinet.
+       * Fix a 2-byte over-run read in function rad_decode().
+       * Update thread pool queue properly.
+       * Autonconf tests try first any user-specified directory,
+         otherwise they may pick up the wrong version.
+       * Delete the autoconf tests for the libldap dependancies.
+       * Install all the regular files under the "doc" directory.
+       * Distinguish between exit code <0 (failure) and >0 (reject)
+         in Exec-Program-Wait. Patch from Thor Spruyt.
+       * Make Expiration work.
+       * Clean up the code for opening a proxy socket.
+       * When finding a realm to proxy to, if all are dead, wake them
+         if wake_all_if_all_dead is true.
+       * In radwho, print the NAS-Port as unsigned int.
+       * Use extended regex instead of basic regex in rlm_attr_filter.
+       * Catch the case where someone deletes a directory that rlm_detail
+         is using.
+       * Use the variable $(LDFLAGS) when linking a module.
+       * Ignore the Stripped-User-Name when a realm has the "nostrip"
+         directive.
+       * Add support for NT-Password in rlm_pap.
+       * In rlm_sqlcounter, use the time left to the next reset if it's
+         inferior to the time left in the counter.
+       * Calculate Message-Authenticator correctly for Accounting-Request
+         and Accounting-Response.  Bug found by Paolo Rotela.
+       * Build on MAC OS X.  Still need --disable-shared, though.
+       * Fix bug #255 (crash with expired CRL's, etc.)
+       * Fix quote removal of the values from a SQL database.
+       * Reap the zombie process after a command run from "Exec-Program".
+       * Allow to cancel proxy of accounting with "Proxy-To-Realm := LOCAL".
+       * Don't copy VSA's to an Access-Reject packet.
+
+FreeRADIUS 1.0.4 ; Date: 2005/06/11 22:46:52, urgency=medium
+
+       * Fix installation problem.
+       * Increase a buffer size, so radrelay doesn't truncate values.
+       * Updates in the documentation. Patches from Thor Spruyt.
+
+FreeRADIUS 1.0.3 ; Date: 2005/06/03 17:15:11, urgency=high
+
+       Security Fixes
+       * Always escape the strings in the SQL module.
+       * Check buffer bound when input character needs escaping in
+         the SQL module. Bug found by Primoz Bratanic.
+
+       Bug fixes
+       * Return EAP-Fail in Access-Reject, rather than an empty Access-Reject
+       * Don't send Proxy-State from home server in TTLS.
+       * Fixes for forking external programs, so the server doesn't
+         suddenly stop processing requests, or stop forking programs.
+       * radzap now works, but it's command-line options have changed
+         completely, and it's a shell script.
+       * radwho has updated command-line options, and no longer reads
+         Unix "utmp" files.
+       * Fix bug in calling checkrad script with NAS port > 9999999
+       * Fix long-standing bug when both crypt and pthreads are in use
+       * Don't SEGV when rlm_sql gets 'NULL' value from request.
+       * Re-arrange code in radrelay to not duplicate accounting packets.
+       * In rlm_attr_rewrite, change the value when the attribute type
+         is different from string.
+
+FreeRADIUS 1.0.2 ; Date: 2005/02/13 01:03:20, urgency=medium
+
+       * Novell eDirectoty support.  Patch from Novell.
+       * localweb & Trapeze dictionary updates.
+       * EAP-SIM fixes.
+       * Make "Strip-User-Name = No" work.
+       * Don't declare zero-length arrays in rlm_passwd
+       * Bug fix to make udpfromto code work
+       * radrelay shouldn't dump core if it can't read a VP from the
+         detail file.
+       * Only initialize the random pool once.
+       * In rlm_sql, don't escape characters twice.
+       * Fix MD4 calculation on big-endian machines.
+       * In rlm_ldap, only claim Auth-Type if a plain text password is present.
+       * Treat Quintium VSAs like Cisco VSAs
+       * Locking fixes in threading code
+       * rlm_krb5 includes /usr/include/et for Fedora Core
+       * Fix post-auth REJECT stanza processing for rejections from external
+         processes or home RADIUS servers
+       * Fix building on gcc-4.0 by not trying to access static auth_port from
+         other files.
+       * Fix building SNMP support on Solaris 9, which needs -lkstat
+
+FreeRADIUS 1.0.1 ; Date: 2004/09/02 10:52:03 , urgency=high
+
+       Denial-of-Service Security Fix
+       * Fix two remote crashes and a memory leak in RADIUS packet
+         decoding.
+
+       Bug fixes
+       * Fix premature "success" during EAP/TLS handshake.
+       * Dictionary handling now complains about identically named
+         values with different values, and rejects dictionary
+         entries with bad data
+       * Update dictionaries to deal with the above change.
+
+FreeRADIUS 1.0.0 ; Date: 2004/07/17 06:31:32, urgency=low
+
+       pre3 -> release
+       * Fix LDAP dictionary map loading.
+       * Check login time allowance to packet timestampe where available.
+       * Compilation fix for machines withouth <pthread.h>.
+       * Man page improvements.
+       * Grab latest config.sub and config.guess (2004-03-12).
+
+       pre2 -> pre3
+       * Make IPv6 support work better.
+       * Updated 3com dictionary.
+       * Fixed MD5 code to be more portable.
+
+       pre1 -> pre2
+       * Updated SQL onoff query
+       * Updated Nomadix, RedBack and Valemont dictionaries.
+       * MD4/MD5 fixes.
+       * Don't complain about ports we're listening on when HUP'd.
+       * Permit -i to work for radclient.
+       * Fix bug in new proxy code.
+       * rlm_passwd is now a little friendlier.
+       
+       Non source-code changes
+       * Preliminary tests indicate that the server builds and runs on
+         Interix (SFU on Windows XP).
+       * EAP module configuration is now in "raddb/eap.conf", as it was
+         getting large.
+       * Updated GPL boilerplate in the source.
+       * Added new RFC's to doc/rfc/
+       * Added more "man" pages for many of the modules.  Many of the
+         'doc/rlm_*' files have been deleted, and replaced with 'man' pages.
+       * Added many new dictionaries: 3GPP, 3GPP2, Propel, Karlnet,
+         Sonicwall, Navini, Bristol University, Valemont, Mikrotik.
+       * doc/configurable_failover is now understandable by mere humans.
+       * Update scripts/rc.radiusd with examples of how to deal with
+         shared library issues.
+       * Added demo certs.
+       * Updates to configure scripts for MySQL.
+       * Updated doc/tuning_guide, with comments about SQL.
+
+       Core feature improvements
+       * Many, many minor bug fixes and feature enhancements.
+       * Added "reject" action in configurable failover for modules
+       * Added a "listen" directive, which supersedes the old
+         "bind_address" and "port" directives.  "listen" allows much
+         finer-grained control over what IP's, ports, and packets the
+         server pays attention to.
+       * The proxy code has been updated to work properly, and to
+         allocate new sockets for proxying packets when there are more
+         than 256 requests outstanding to a home server.  Many thanks
+         to Stephen Jaeger for help in debugging the new feature.
+       * Regular expression matches in brackets can now be referenced
+         as in Perl, via %{1}, %{2}, etc.
+       * added ability for mschap module to use ntlm_auth, to perform
+         MS-CHAPv1 and MS-CHAPv2 authentication against a Windows
+         Domain Controller.
+       * Check return value from registered xlat functions. If return
+         value is 0, treat the attribute as not found.  This lets things
+         like %{sql: select... :-FAILED} work.
+       * Realms can now be configured to ignore DEFAULT and NULL
+         realms.  This makes prefix/suffix realms co-exists a little
+         better.
+       * Added red-black tree implementation to src/lib.  The
+         dictionaries now use it, rather than singly linked lists.  Tests
+         indicate that the server is up to 30% faster.
+       * Updated MSCHAP module to be able to better deal with Windows
+         machines which put a username with domain into User-Name, but
+         which use only the username to create the MS-CHAP-Response.
+       * Made "hints" file more generic and flexible, without changing
+         old functionality.
+       * Enhanced configuration file variable handling.  See
+         doc/variables.txt for details.
+       * Checks for OpenSSL now enforce version number, and are common
+         across all modules, rather than being duplicated.
+       * Implement "udpfromto", which allows the server to work better in
+         LVS.  Code from Jan Berkel and Miquel van Smoorenburg.  To use
+         it, do:   ./configure --with-udpfromto=yes
+       * Re-arranged "walk over cached requests" code for clarity.
+       * The server now keeps more SNMP statistics about the packets it
+         has processed.
+       * De-coupled the queue of input requests from the pool of threads.
+         This allows "spikes" of requests to be queued, even though all
+         threads are busy.  This change significantly increases the
+         servers ability to process large numbers of requests on a
+         multi-CPU machine.
+       * Re-arranged the internal "core" request handling code, to
+         make a little more sense.
+       * Removed support for Replicate-To-Realm.  Use radrelay.
+       * Print & parse unknown attributes as Attr-%d, Vendor-%d-Attr-%d,
+         or VendorName-Attr-%d.
+       * rlm_passwd is now marked "stable", and has many bugs fixed.
+       * More flexible configuration for rlm_ldap.
+       * New implementation of parser for Ascend's data filter
+         attributes, that is now thread-safe and GPL'd.
+       * Preliminary (not entirely complete) support for IPv6 attributes,
+         including IFID.
+       * Added support for rejected packets to run an Post-Auth-Type REJECT
+         stanza instead of skipping post-auth entirely.
+       * Added support for %{*:Packet-Type} translation. (Not for %{check:})
+       * Added support for %{check:Attribute-Name} to go with
+         %{request:Attribute-Name} and the like.
+       * Add support to rlm_sql for post-authentication query execution.
+       * Add support to rlm_sql for accounting_update_query_alt
+       * Add support for supplementary groups of switched-to user
+       * Add support for xlat-ing backquoted reply values from SQL queries.
+       * Add Public Domain MD5 implementation by Colin Plumb
+       * Add Public Domain MD4 implementation by Colin Plumb and
+         Todd C. Miller
+       * Remove smbdes.c from libradius, and add to rlm_mschap and
+         rlm_eap_leap
+       * Replace GPL'd snprintf.c in libradius with LGPL'd snprintf.[ch]
+
+       EAP-module feature improvements
+       * Allow checking of EAP identity against certificate.
+       * EAP-TLS now checks Certificate Revocation List
+       * Added EAP-TTLS support in rlm_eap.  Tested with many clients,
+         and with tunneled PAP, CHAP, MS-CHAP, MSCHAPv2, EAP-MD5,
+         EAP-MSCHAPv2, and EAP-GTC.
+       * Added EAP-PEAP support, with tunneled EAP-MSCHAP-V2, and EAP-GTC.
+         Patch from Masao Nishiku.  (Many, many thanks!)
+       * Added EAP-SIM.
+       * Enabled proxying of the authentication request which is tunneled
+         inside of PEAP and TTLS.
+
+       Utility improvements
+       * Add support to checkrad.pl for mikrotik-brand NASs over SNMP
+       * Added rlm_ippool_tool, by Edwin Groothuis.
+       * Updates to radclient, so that you can specify multiple '-f'
+         options, and it will send those packets in parallel.  This
+         allows for significantly higher packet rates when load testing.
+
+       Bug fixes
+       * Fix a bug in the attr_filter module, which would throw away
+         the tag from tagged attributes.
+       * Bug fixes to thread handling from Malcolm Caldwell.
+       * Fixed a bug in libltdl which printed the wrong error message
+         when trying to link to a library.  Found by Paul Stewart.
+       * Correct error condition in rlm_krb5.  Patch from Jon Moore.
+       * Updates for 64-bit systems.
+       * Patch to make ctime_r work on non-compliant platforms.
+         Patch from Oliver Graf.
+       * Updates to rlm_ippool for stability.
+       * Catch packets which are just about 4K in size.
+          Bug found by Nils-Henner Krueger.
+       * Many fixes to the SQL module & sub-modules.
+
+FreeRADIUS 0.9.3 ; Date: 2003/11/20 20:15:48, urgency=high
+
+       * Change rlm_eap to not log an error if given a non-EAP packet
+       * Fix rlm_ippool's call to pod2man for perl versions before 5.6
+       * Fix a remote DoS and due to mis-handling of tagged attributes,
+         and Tunnel-Password attribute.
+
+FreeRADIUS 0.9.2 ; Date: 2003/10/14 19:00:09, urgency=low
+
+       * New rlm_ippool code to fix IP leaks
+       * New rlm_ippool_tool for manipulation of rlm_ippool databases
+
+       * Change radrelay to reject records without an Acct-Status-Type attribute
+       * Change rlm_counter to reject packets which predate last server reset
+       * Change version output to include GNU GPL information
+       * Change rlm_ldap to output bad search filters
+
+       * Fix compilation of various modules when not building with pthreads
+       * Fix segfault due to poorly initialised value in rlm_mschap
+       * Fix to only reject packets once
+       * Fix rlm_exec to work when wait=no
+       * Fix rlm_attr_filter to work in post-proxy (as intended)
+       * Fix rlm_sql to only try to load SQL drivers
+       * Fix to orrectly limit size of RADIUS packets
+       * Fix usage information to output to stdout when used with -h flag
+       * Fix configure to assume gethostbyname is BSD-Style on FreeBSD
+
+FreeRADIUS 0.9.1 ; Date: 2003/09/04 14:56:34, urgency=low
+
+       * Replicate-To-Realm is deprecated, and hence no longer documented
+       * Document rlm_detail support for authorize and post-auth sections
+       * Improve slightly MySQL accounting record SQL query
+       * Opaquefied CHAP-Challenge
+       * Add attributes to Nomadix dictionary
+       * Fix rlm_exec's parsing of non-attribute return values
+       * Fix for a segfault while reading config files
+       * Fix for a segfault regarding hostname lengths
+       * Fix for a segfault while reading deprecated config files
+       * Fix compilation of radiusd.c when threads are disabled
+       * Recover from inability to relay
+       * Stop complaining in error log when a system call is interrupted.
+       * Don't print binary CHAP-Passwords into the logs
+       * Successfully detect GNU dbm >= 1.8.1's dbm compatibility library
+       * Fix rlm_unix to deal with requests without a username
+       * Fix "uninmplemented function" crash in postgresql driver on -HUP
+       * Revert INTERVAL types to BIGINT in postgresql example schema
+       * Fix radrelay to notice when it's out of IDs
+       * Fix radrelay to correctly skip bad attributes
+       * Fix radrelay to not leak IDs when discarding packets
+       * Fix configure to correctly identify systems without SYSV or GNU-style
+         gethostby{addr,name}_r.
+
+FreeRADIUS 0.9.0 ; Date: 2003/07/04 21:01:29, urgency=low
+
+       * Many, many, bug fixes and feature enhancements.
+       * radrelay now updates packet 'id' on retransmissions.
+       * More checks for thread-safe functions.
+       * Fix CHAP related buffer overflow (ouch!), thanks to Masao NISHIKU.
+       * Issue warnings if deprecated configuration files are used.
+       * rlm_passwd can now add items to the reply, request, or config items.
+       * The rlm_digest, rlm_exec, and rlm_ippool modules are now marked
+         as 'stable', and included in the default build.
+       * Removed 'raduse'.  No one has used it for years.
+       * Massive fixes for Debian packaging.
+       * radclient can now send "disconnect" packets, to NASes which
+         support it.  The server, however, CANNOT send disconnect packets.
+       * Made Auth-Type, Acct-Type, etc. names consistent across
+         dictionary files and radiusd.conf.  The old (inconsistent) names
+         are still allowed for backwards compatibility.
+       * Cleaned up problems with the rlm_sql module.
+       * Updates to the rlm_ldap module.
+       * rlm_mschap no longer reads SMB password files.  See rlm_passwd,
+         instead.
+       * Changed default entry in the 'users' file to 'Auth-Type = System',
+         to allow EAP and Digest authentication to work automagically.
+       * Support for Cisco LEAP.
+       * Added many new dictionaries (Extreme, Wispr, ERX, Netscreen...)
+       * Removed support for ATTRIB_NMC.  It is now handled (better)
+         in a different manner.
+       * Dictionaries have been moved from /etc/raddb to /usr/share/freeradius
+       * Many documentation updates
+       * Ignore whitespace-only lines in the 'users' file.
+       * Patch to fix 'rlm_realm' from returning the DEFAULT entry when
+         we are looking for the NULL entry and it doesn't exist. Bug
+         noted by Nathan Miller.
+       * Disable child process spawning if we don't have threads.
+         The code doesn't work, so it's better to force the server
+         to run in single-process mode.
+       * New rlm_exec module, which allows a more generic way of
+         executing external programs.
+       * Preliminary large file support in 'configure' and in the server,
+         to support 2G+ detail files.
+       * Install documentation into /usr/local/share/doc/freeradius
+       * New/updated dictionaries for RedCreek, Bintec, Alcatel,
+         ITK, Telebit, and Cabletron.
+       * Updates to allow building on MAC OSX.
+       * Add support for Acct-Type,Session-Type and PostAuth-Type
+       * Removed builddbm.  It hasn't been used for ages.
+       * Added new post_proxy section, based on patch from Chris Brotsos.
+       * rlm_counter shouldn't reset the counters on instantiation,
+         if the reset is set to 'never'.
+       * Significant updates to the rlm_python and rlm_perl modules
+       * Fix the rlm_pap module to handle password lengths properly.
+       * Do SQL 'close' on bad sockets, to prevent descriptor leaks
+       * Case insensitivity option for rlm_radutmp
+       * New pseudo-round-robin load balancing for realms.
+       * Suppress empty SQL queries.
+       * Include strong PRNG
+       * Create 'snmp' configuration directive, so that we can disable
+         SNMP at run time, even if it's built into the server.
+       * Refresh realm as 'active' when we see a response from it,
+          Based on a patch by Angelos Karageorgiou.
+       * Don't core dump if Status-Server is received, but it's disabled.
+       * Support more variants of character fields in Oracle.
+         Patch from Stocker Gernot.
+       * Better parsing of dictionary files.
+       * Alteon web switch dictionary, from Thomas Linden
+
+FreeRADIUS 0.8 ; Date: 2002/11/18 15:37:24, urgency=low
+
+       * Added Oracle-specific queries.
+       * Updated SQL queries to match schema.
+       * PostGreSQL reconnect patch.
+       * Added documentation on how to build on MAC OSX.
+       * Allowed SQL module to ignore unknown Acct-Status-Type values.
+       * Updated PostGreSQL queries and schema.
+       * Updated the log rotation configuration files.
+       * Colubris and updated Nomadix dictionaries, from Marko Myllynen.
+       * Normalized error messages from the SQL modules, so that they're
+         more informative.
+       * Added Suse specific directory and configuration files, from
+         Peter Nixon
+       * SQL fail-over patch, so that the module returns FAIL if
+         the back-end database is down.  Based on a patch from
+         Thomas Jalsovsky.
+       * Cleaned up the internal handling of the configuration
+         information, in preparation for better handling SIGHUP.
+       * Updated rlm_krb5 configuration to better find it's libraries
+         and include files.
+       * radclient now complains if it receives a reply from a machine
+         other than the one to which it sent the request.
+       * Updated Postgresql SQL queries to get the operator, too.
+       * Added Juniper dictionary.
+       * Added Cisco VPN3000, VPN5000, and BBSM dictionaries.
+       * New platform-neutral 'rc.radiusd'
+       * Configuration files with private information get chmod'd
+         0600 after installation.
+       * Preliminary support for clean shutdowns when a SIGTERM is
+         received.
+       * SNMP timeouts for checkrad, so there will be fewer situations
+         where it hangs for 30 seconds...
+       * Added code to clean up modules and memory when asked to exit
+         via SIGTERM.
+       * Removed all need for the old-style 'naslist' and 'client' files,
+         and noted that they are deprecated.
+       * Added support for Status-Server packets, stolen shamelessly
+         from Cistron RADIUSD.  This is despite the RFC's saying such
+         things are wrong.
+       * Bug fixes to rlm_dbm.
+       * Updates for checkrad, max40xx routine, from Aleksandr Kuzminsky.
+       * Disable caching of passwords for the Unix module.  It was
+         causing too much confusion.
+       * Fix a memory leak when proxying Authentication-Request's
+       * Attributes which are not found in the dictionary are now of
+         type 'octets', instead of 'string'.
+       * Support for "round-robin" load balancing, when proxying requests
+         to multiple servers for one realm.
+       * Minor changes for better HPUX support.
+       * Updated the documentation and README's
+       * Made FreeTDS build ONLY after hand-editing, as the FreeTDS
+         libraries are in a state of flux, due to active development.
+       * Fixes to help build the server on MAC OSX
+       * Cisco VPN 3000 dictionary, as posted to the list by Chris Deramus.
+       * Fix EAP problems with retransmission, from Rainer Weikusat.
+       * Updates to the Oracle module, from Andrea Gabellini.
+       * In xlat, Unix timestamps are unsigned ints.
+       * Security fixes for the Kerberos Module.
+       * New 'post-auth' section, to do additional processing of
+         requests after they've been authenticated.
+       * doc/aaa.txt describes how the server works.
+       * More uniform encoding/decoding of passwords, so that they will
+         be seen as clear-text where possible.
+       * radwho and radzap now read 'radiusd.conf' to discover where the
+         radutmp files are located.  Patch from Andrea Gabellini.
+       * Preliminary 'expression' module, to allow you to do cool things
+         like:    Session-Timeout = `%{expr:3600 - %{sql:SELECT ...}}`
+       * Added ability to do xlat on check items, and reply items,
+         so that the value of the reply attributes can be dynamically
+         generated.
+       * Added MIBs, taken from the RFC's.  This makes SNMP queries to
+         the server a little easier to set up.
+       * Don't SEGV when we receive a packet which is larger than the
+         size claimed in the RADIUS portion.  Patch from Vaughn Skinner.
+       * SNMP patches from Harrie Hazewinkel.
+       * Added Altiga dictionary, from Calum <calum.aug02@umtstrial.co.uk>
+       * New Rewrite-Rule for rlm_attr_rewrite, to selectively choose
+         which rewrite rule is performed, and when.
+       * Minor bug fixes for radrelay.
+       * Bug fixes in SQL and sub-modules.
+       * Major updates to dialup_admin.
+       * Fixed handling of tagged string attributes, so that the server
+         doesn't go off into never-never land.
+       * Cleaned up experimental rlm_smb, so that it builds on more
+         platforms.
+       * Don't over-write request->reply->vps with the Reply-Message,
+         when doing authentication rejects with Exec-Program-Wait.
+       * Added 'instantiate' section, so that modules like 'expr',
+         with only an 'xlat' function can be registered.
+       * Allow '{' and '}' in xlat'd strings.
+       * C++ compatibility patch from Andrey Kotrekhov, for libradius.
+       * Automatically decrypt/encrypt User-Password, so that debugging
+         mode will print out the text password, and not the random
+         garbage it previously showed.
+       * Cleaned up header files and function prototypes for the SQL
+         sub-modules.
+
+FreeRADIUS 0.7 ; Date: 2002/07/26 18:01:50 , urgency=high
+
+       * Allow attributes of type 'date' to be sent in outgoing packets.
+         Bug found by Loh John Wu <ljwu@sandvine.com>
+       * Add 'Realm' attribute, even if it's a LOCAL realm.
+         Bug noted by Chris Brotsos.
+       * Added experimental SMB authentication module, which uses
+         PAP passwords to authenticate against an NT-Domain.
+         NT/LM-passwords are not currently supported.
+       * More documentation for rlm_passwd, rlm_mschap, and rlm_digest.
+       * 'configure' changes to better find sem_init and friends.
+       * Allow the use of previously installed libtool, and libltdl.
+         This appears to help a lot on FreeBSD.
+       * Fixes to work on non-threaded builds.
+         Patch from Rainer Weikusat.
+       * SQL now re-connects to the server, if the connection is lost.
+         Currently only MySQL is fixed, but other patches will follow.
+         Patch from Todd T. Fries.
+       * Added experimental use of dynamicly translated variables,
+         CallBack-Number = `%{request:Calling-Station-Id}`
+         sets the value of the CallBack-Number attribute to the value of
+         the Calling-Station-Id in the original request.
+       * Cute hack: Allow regex matching on IP addresses, by placing
+         the string representation of the IP address (1.2.3.4) into
+         the internal data structure.  This allows things like
+         NAS-IP-Address =~ "^192\.168", which may be useful.
+       * Add documentation for experimental rlm_dbm module.
+       * Added experimental Perl module.
+       * Added the relevant IETF RFC's (standards documents) to 'doc/rfc',
+         along with some simple perl scripts to convert them to cross-
+         referenced HTML.
+       * Updated the experimental Python module.
+       * Added Cisco SSG VSA's
+       * When rejecting authentication due to external Exec-Program, do
+         NOT free the reply pairs, as the server core will take care of
+         doing that.  Bug noted by Thomas Jalsovsky
+       * New experimental module: rlm_cram
+         Supports APOP, CRAM-MD5, CRAM-MD4, CRAM-SHA1 with it's own
+         VSA's. This module may be used for SMTP/POP3/IMAP4 server
+         authentication.
+       * Make Exec-Program and Exec-Program-Wait work in debugging mode.
+       * Finalize the radrelay additions, based on Cistron RADIUS
+         Patches from Simon <lists@routemeister.net>
+       * Fix issues with linking, by making libradius shared.
+       * Fix issues with MD4, MD5, SHA1, and use of OpenSSL
+       * Update rlm_x99_token module to compile.
+
+FreeRADIUS 0.6.0 ; Date: Date: 2002/07/03 14:16:33 , urgency=high
+
+       * Many bug fixes.  For explicit details, see:
+               http://www.freeradius.org/cvs-log/
+       * Change to the user/group specified in the config file in all
+         modes ( debug and daemon ).
+       * SQL sockets are rotated so that all are used, to prevent the
+         SQL server timing out and closing unused sockets.  Patch from
+         Todd T. Fries
+       * Sybase driver from mattias@nogui.se.
+       * Modules are now versioned.
+       * Delete garbage Proxy-Reply attributes sent by the home server
+         before performing our own reply.
+       * Fix race conditions when duplicate packets resulted in a request
+         being processed by two threads, at the same time.
+       * Add '-d' command-line option to radwho
+         Bug noted by Matthew Schumacher
+       * Corrected issue that when a home server never replied to a
+         proxied request, the server may die.
+       * In SQL, look in radcheck, if not found there, try radgroupcheck.
+         Patch from Thomas Jalsovsky.
+       * Set sql user name for ALIVE accounting packets, too.
+         Patch from Simon <lists@routemeister.net>.
+       * Use port-specific checking for realms, now that we can proxy to
+         different auth/acct servers for the same realms.
+         Patch from Eddie Stassen.
+       * Minor updates to encrypted tunnel passwords.
+       * Default 'run_dir' is now /var/run/radiusd, not var/run.
+         /var/run is writeable only by root, and radiusd may be run suid.
+       * Modules are now versioned, so that upgrading the server
+         ensures that the new modules are installed.
+       * Fix sql code, so that magic SQL characters don't get the
+         SQL server excited.
+       * Remove references to "UNKNOWN-NAS" in log messages.
+       * Properly handle fork() and obtaining child processes exit
+         status when using threads.  (pthread is broken w.r.t. signals)
+       * Correct code which would send erroneous reject, when the reject
+         was delayed, and a new request came in.
+       * Fix race condition where proxied requests would sometimes never
+         be re-sent.  Bug noted by Eddie Stassen.
+       * Corrected LDAP3 schema
+       * Implemented Digest authentication, as per IETF document
+         draft-sterman-aaa-sip-00.txt, to perform authentication against
+         a Cisco SIP server.
+       * If no password or group files have been specified in the config,
+         use the standard system calls to find them, rather than giving
+         up.  Patch from Steve Langasek.       
+       * Return Proxy-State attributes in a delated Access-Reject
+       * Corrected 'session zap' logic, when an old and unused session
+         is deleted from the databases.  Accounting packets with garbage
+         Client-IP-Address attributes should no longer be a problem.
+       * Bug fixed in LDAP attribute map, for MS-CHAP related attributes.
+       * Fixes to the EAP module to work better with XP.
+       * Support for MS-SQL, using the FreeTDS library,
+         from Dmitri Ageev
+       * New operators =* and !*.  See 'man 5 users' for details.
+       * Added translation for %{config:section.subsection.item}, to
+         allow run-time translation of internal configuration parameters.
+       * New rlm_sqlcounter module, to keep counters based on SQL data.
+       * Fix rlm_realm, to allow seperate proxying of accounting and
+         authentication requests.
+       * Bug fixes in PostgreSQL back-end, from Andrew Kukhta.
+       * Increase internal buffers, to allow large SQL query strings.
+       * Added debug level 3 (-xxx), where debug messages have time stamps.
+       * Fix 'radwho' to use the correct radutmp file, as found by
+         'configure' (but radwho still doesn't read radiusd.conf)
+       * Fix bugs in tunnel (tagged attribute) code, which would prevent
+         tagged attributes from being generated correctly in a packet.
+       * Build only 'stable' modules by default.  Experimental modules
+         require --with-experimental-modules to be passed to 'configure'
+       * New module rlm_ippool, to do server-side IP pooling.
+       * Fix rlm_eap module for portability, to work on non-x86 platforms.
+       * Re-connect to the LDAP server if the connection idles out
+       * Increased the visibility of the warning messages when doing
+         'make install'
+       * Fixed EAP module to use 16-bit integers, so that it will
+         work on big-endian architectures.
+
+FreeRADIUS 0.5.0 ; Date: 2002/03/14 22:18:22, urgency=medium
+
+       * Many bug fixes.  For explicit details, see:
+               http://www.freeradius.org/cvs-log/
+       * Added Foundry dictionary, from Thomas Keitel
+       * Fix a logic bug in the 'walk over request list' code, which
+         would sometimes result in a request being deleted while it
+         was still being processed.  Found by Rainer Clasen
+       * New 'tuning' guide, for optimizing the server's speed.
+       * The default ports are now 1812/1813, which is the standard.
+       * Fix a bug which would hang the server when many SQL connections
+         were open.  Found by Cvetan Ivanov <zezo@spnet.net>
+       * Updated MySQL schema, with sanity checks, based on a schema from
+         Thomas Huehn <huehn@eozaen.net>
+       * Added 'Aptis' (Nortel CVX) dictionary.
+       * Added Ipv6 attributes (as 'octets' type for now)
+       * 'xlat' capability for SQL, so other modules can do SQL queries.
+       * We don't need a shared secret for LOCAL realms.
+       * Added better description of internal variables.
+       * Configurable fail-over to DEFAULT realm.  Sometimes we don't
+         want to use the DEFAULT realm, if all configured realms are
+         marked dead.  From Rainer Clasen.
+       * new configuration items 'max_attributes' and 'reject_delay'
+         If the packet contains too many attributes, it can be rejected.
+         We can also delay sending an Access-Reject, which slows down
+         certain DoS attacks.
+       * Updates to redhat scripts and spec file, from Marko Myllynen.
+       * Python module (EXPERIMENTAL) from migs paraz <mparaz@yahoo.com>
+       * Add ability to find *best* match when comparing attributes.
+         If there is more than one attribute in a request and the first
+         one doesn't match, go check the second one, instead of failing.
+       * unixODBC support for SQL, from Dmitri Ageev <d_ageev@ortcc.ru>
+       * Use thread-safe versions of library calls.  This work is still
+         on-going.
+       * New rlm_passwd module, to allow general parsing of passwd-style
+         files.
+       * Preliminary EAP-TLS support.
+       * Updated LDAPv3 schema
+       * Correct checks for Odbc, and fix bugs in the module.
+         Andreas Kainz <aka@maxxio.at>
+       * MAN page fixes and updates
+       * Added PHP web interface 'dialup_admin'
+       * Password = "UNIX" or "PAM" backwards compatibility removed.
+       * Use the operators in the SQL schema and queries, and bug
+         fixes in the SQL module.
+         Randy Moore <ramoore@axion-it.net>
+       * fgetpwent() compatibility, for systems without it,
+         from Daniel Carroll <freeradius@defiant.mesastate.edu>
+       * Added PAP authentication module, as a step to removing
+         most authentication handlers in other modules.
+       * Send a Access-Reject after max_request_time
+       * Multiple fixes in the LDAP module.
+       * Quintum dictionary by Jeremy McNamara <jj@indie.org>
+       * Preliminary EAP Module with MD5 support
+         Contributed by Raghu <raghud@hereuare.com>
+       * Better sanity checking for bad VSA's when receiving a packet
+       * new 'xlat register' so that attribute values may be pulled
+         out of configurable databases at run-time.
+         e.g. %{ldap:ldap:///dc=company,dc=com?uid?sub?uid=%u}
+       * Minor fixes to debian package rules
+       * Attribute 'Password' deprecated in favor of 'User-Password'.
+       * MS-CHAP and MS-CHAPv2 MPPE support added.
+         Contributed by Takahiro Wagatsuma <waga@sic.shibaura-it.ac.jp>.
+       * X9.9 token enhancements (several).
+
+  --  Alan DeKok <aland@ox.org>
+
+FreeRADIUS 0.4.0 ; urgency=low
+
+       * Allow the MS-CHAP module to work, and to read /etc/smbpass
+         3APA3A <3APA3A@SECURITY.NNOV.RU>
+       * Remove the server requirement that one of User-Password
+         or CHAP-Password exist when doing authentication.  These
+         checks should be handled by the modules.  This change
+         also prepares us for EAP.
+         Patch from Raghu <raghud@hereuare.com>
+       * Make NAS-Port-ID in radwho, raduse, etc. unsigned,
+         instead of signed.
+         Patch from John Morrissey <jwm@horde.net>
+       * Allow \t and \n inside of configuration strings.
+         Frank Cusack <fcusack@fcusack.com>
+       * X9.9 Challenge-Response token card support.
+         For now, only CRYPTOCard tokens are supported.
+         Frank Cusack <fcusack@fcusack.com>
+       * Fix core dump on Solaris in radwho.c
+         Patch from Eddie Stassen <eddies@saix.net>
+       * Fix leak / core dump in Oracle module.
+       * Fix memory leak in rlm_counter
+         Kostas Kalevras <kkalev@noc.ntua.gr>
+       * "LOCAL" realms do not need to have an entry in the 'clients'
+         file.  Philippe Levan <levan@epix.net>
+
+  --  Alan DeKok <aland@ox.org>
+
+FreeRADIUS 0.3.0 ; urgency=low
+
+       * Added ability to send debug messages to the log file, when
+         running in daemon mode.
+       * Miscellaneous fixes to get Debian packaging working.
+       * When trapping a signal, don't SIGKILL children on a SIGTERM,
+         SIGTERM them, instead.  This allows Exec-Program scripts to
+         catch the signal, and finish processing, instead of dying.
+         Bug noted by Michael Chernyakhovsky <magmike@mail.ru>
+       * Increased limit on length of user name read from /etc/passwd,
+         to match the maximum allowed by RADIUS.
+         Bug noted by "Gonzalez B., Fernando" <fgonzalez@manquehue.cl>
+       * Configurable fail-over when proxying packets.  If the
+         home server doesn't respond to a repeated proxied request,
+         it's marked as 'dead', and the next one in the list is used.
+         Patch by Eddie Stassen <eddies@saix.net> and <spirn@21cn.com>
+       * Pass Access-Challenge attributes through the server, in
+         preparation for EAP.
+         Raghu <raghud@hereuare.com>
+       * More fixes for RFC compliance on the Message-Authenticator
+         Raghu <raghud@hereuare.com>
+       * Merged OSFC2/OSFSIA authentication patches from Cistron.
+         (Bug # 104)  The patches are not well tested, however.
+       * IBM DB2 UDB V7.1 SQL driver, contributed by
+         Joerg Wendland <wendland@scan-plus.de>
+       * Fix the IP + Port address assignment.
+         Bug found by "John Padula" <john_padula@aviancommunications.com>
+       * Patch to avoid smashing the contents of Ascend binary filters.
+         Michael Chernyakhovsky <magmike@mail.ru>
+       * Create and Validate Message-Authenticator attribute, in
+         preparation for EAP.
+       * Initialize variables properly in rlm_attr_filter.
+         Patch from Andriy I Pilipenko <bamby@marka.net.ua>
+       * Renamed RedHat init script from 'radiusd.init' to 'radiusd'.
+         This allows it to work properly with the RedHat rc system.
+         Patch from Christian Vogel <chris@amor.iksys.de>
+       * Fix the configure script checks for PostgreSQL, so that
+         they use the 'test' command properly.
+         Bug found by Robert Haskins <rhaskins@ziplink.net>
+       * Change instances of 'assert' to 'rad_assert', so that it
+         can log the error to the standard radius log files.
+         Patch from Vesselin Atanasov <vesselin@bgnet.bg>
+       * Patch to prevent segv when freeing results, from
+         Tomas Heredia <tomas@intermediasp.com>
+       * Added support for Exec-Program to acct.  Bug found by
+         <magmike@mail.ru>
+       * Corrected rlm_files so that raddb/acct_users works
+       * When doing synchronous proxying, update proxy next try
+         entries, so that the server doesn't eat CPU time.
+         Raghu <raghud@hereuare.com>
+       * Add primitive dictionary.nomadix <CBoyd@apogeetelecom.com>
+       * Log messages to console, if the logger hasn't been
+         initialized.  <vesselin@bgnet.bg>
+       * Log invalid user for proxy rejects, too. <help@visp.net>
+       * Fixed Expiration attribute handling.
+       * Added code to handle Ascend-Send-Secret and Ascend-Receive-Secret
+       * Removed non thread-pool code.  If we have threads, we now force
+         the use of thread pools.
+       * Update version number
+       * correct bug where proxied accounting packets would never have a
+         reply sent back to the NAS, or the reply would be sent twice.
+
+  --  Alan DeKok <aland@ox.org>
+       
+FreeRADIUS Alpha 0.2.0, July 30, 2001.
+
+       * call openlog() again when using PAM, to get the correct log
+       facility.
+       * Update child thread code, to minimize race conditions.
+       * Make thread pools the default.  Using plain child threads is NOT
+       recommended.
+       * Ignore SIGPIPE to get ride of crashes when using ldap.
+       * Update proxying code to work better.
+       * Platform independent pthread_cancel()ling
+       * Fix 'unresponsive child pid' erroneous warning messages.
+       * Many changes to get various SQL modules working.
+       Note that there may still be some issues with Oracle.
+       * Added configure options 'with-rlm-FOO-include/lib-dir', so that
+       lower-level rlm_FOO modules can be configured via the top-level
+       configuration file.  This isn't completely done yet.
+       * Fix check for shared library using libtool info, instead of
+       assuming extension being ".so".
+       * Fixes for HPUX.  We probably need more.
+       * Many additional bug fixes and changes.
index 07e36c3..1ef0238 100644 (file)
--- a/doc/DIFFS
+++ b/doc/DIFFS
@@ -68,7 +68,7 @@ SECTION 1 - CREATING AND SENDING YOUR CHANGE
    4. Select e-mail destination. 
 
       If you are on the developers mailing list, send the patch there.
-      freeradius-devel@lists.freeradius.org
+      freeradius-devel@info.cistron.nl
 
       Otherwise, send the patch to 'patches@freeradius.org'
 
index 68f4898..ac1dee2 100644 (file)
@@ -19,7 +19,7 @@ O.INTRODUCTION
 
 2.EXAMPLES
 
-  In the example below, when a request has been rejected, the 
+  In the example below, when a request has been rejected, the
   module my_ippool will not be run, only the module my_detail
   will be run.
   If the request is not rejected, the my_ippool module will be
@@ -41,4 +41,3 @@ O.INTRODUCTION
           my_sql_reject
       }
   }
-
index 809425f..a722486 100644 (file)
@@ -11,10 +11,10 @@ RADIUS-SQL.schema
  
   There isn't a generic SQL schema, but there is one for some databases:
 
-    doc/examples/mysql.sql
-    doc/examples/postgresql.sql
-    doc/examples/mssql.sql
-    doc/examples/oracle.sql
+    src/modules/rlm_sql/drivers/rlm_sql_mysql/db_mysql.sql
+    src/modules/rlm_sql/drivers/rlm_sql_postgresql/db_postgresql.sql
+    src/modules/rlm_sql/drivers/rlm_sql_freetds/db_mssql.sql
+    src/modules/rlm_sql/drivers/rlm_sql_oracle/db_oracle.sql
 
 2.MYSQL
 
@@ -25,6 +25,7 @@ RADIUS-SQL.schema
   More information about tips for configuring MySQL can be found at:
 
     http://www.mysql.com/doc/S/e/Server_parameters.html
+    http://www.mysql.com/doc/S/E/SEC456.html
     http://www.mysql.com/doc/E/X/EXPLAIN.html <-(useful)
     http://www.mysql.com/doc/T/i/Tips.html
     http://www.mysql.com/doc/M/e/Memory_use.html
@@ -32,4 +33,3 @@ RADIUS-SQL.schema
   A good page for MySQL best practices is:
 
     http://www.onlamp.com/pub/a/onlamp/2002/07/11/MySQLtips.html
-
index 4df784e..1232ad2 100644 (file)
   ----                 ----            ------
   Simultaneous-Use     integer         Max. number of concurrent logins
   Fall-Through         integer         Yes/No
+  Exec-Program         string          program to execute after authentication
+  Exec-Program-Wait    string          ditto, but wait for program to finish
+                                       before sending back auth. reply
   Login-Time           string          Defines when user may login.
   Current-Time         string          Allows you to perform time-based
                                        checks when a request is received.
 
+  Exec-Program can take arguments. You can use variables in the
+  arguments, which are automatically expanded by the server.  See
+  'doc/variables.txt' for more information.
+
+  For example, use the following entry for someone who has BSMTP (queued
+  SMTP) service. "brunq" is the program that runs the SMTP queue.
+
+  robert       Service-Type = Framed-User
+               Exec-Program = "/usr/local/sbin/brunq -h %f delta",
+               Fall-Through = 1
+
+  The output from Exec-Program-Wait is parsed by the radius server. If
+  it looks like Attribute/Value pairs, they are decoded and added to the
+  reply sent to the NAS. This way, you can for example set Session-Timeout.
+
+  If Exec-Program-Wait returns a non-zero exit status, access will be
+  denied to the user. With a zero-exit status, access is granted.
+
   Login-Time defines the time span a user may login to the system. The
   format of a so-called time string is like the format used by UUCP.
   A time string may be a list of simple time strings separated by "|" or ",".
index 90702cf..66bccd7 100644 (file)
@@ -38,7 +38,7 @@ o Enable VSA's on the Ascend/Lucent MAX:
 
 o Enable OLD attributes in FreeRADIUS
 
-  One note on this, Ciscos have an Ascend compatibility mode that
+  One note on this, cicsos have an Ascend compatability mode that
   accepts only the OLD style Ascend attributes, just to make life more
   interesting.  :)
 
index 5e5130e..313b43d 100644 (file)
@@ -62,8 +62,8 @@ server to process the second module if the first one fails.  Any
 number of modules can be listed in a "redundant" section.  The server
 will process each in turn, until one of the modules succeeds.  It willthen stop processing the "redundant" list.
 
-1. Rewriting results for single modules
-   ------------------------------------
+  Rewriting results for single modules
+  ------------------------------------
 
   Normally, when a module fails, the entire section ("authorize",
 "accounting", etc.) stops being processed.  In some cases, we may want
@@ -100,8 +100,8 @@ with priority "1".  The normal configuration is "fail = return", which
 means "if the detail module fails, stop processing the accounting
 section".
 
-2. Fail-over configuration entries
-   -------------------------------
+  Fail-over configuration entries
+  -------------------------------
 
   Modules normally return on of the following codes as their result:
 
@@ -122,10 +122,6 @@ listed, with a value.  If the code is not listed, or a configurable
 fail-over section is not defined, then values that make sense for the
 requested "group" (group, redundant, load-balance, etc) are used.
 
-  The special code "default" can be used to set all return codes to
-the specified value.  This value will be used with a lower priority
-than ones that are explicitly set.
-
   The values for each code may be one of two things:
 
        Value           Meaning
@@ -146,8 +142,8 @@ modules will be "ok", because it has higher priority than "fail".
 to fail, so long as a later module succeeds.
 
 
-3. More Complex Configurations
-   ---------------------------
+  More Complex Configurations
+  ---------------------------
 
   The "authorize" section is normally a list of module names.  We can
 create sub-lists by using the section name "group".  The "redundant"
@@ -201,120 +197,8 @@ return code found by processing the list.
 "group" section.
 
 
-4. More Complex Configuration using "if" and "else"
-   ------------------------------------------------
-
-  As of version 2.0, the server allows "if"-style checking in the
-configuration sections.  The section is still processed as a list, so
-there is no looping or "goto" support.  But by using "if", the
-administrator can have branching paths of execution, where none was
-possible before.
-
-  For example, the following configuration says "run sql, if it
-returns notfound, run ldap1, else run ldap2".
-
-  authorize {
-       ...
-       sql
-       if notfound {
-               ldap1
-       }
-       else {
-               ldap2
-       }
-
-  Note that the parser is easily confused.  The words "if" and "else"
-MUST be the first entry on the line.  Using statements like "} else {"
-is forbidden, and will prevent the server from starting.  Putting
-brackets around the condition like "if (notfound)" won't work, either.
-
-  If you want to specify multiple conditions, put them in double
-quotes, and separate the conditions by a single '|' character, as
-follows:
-
-       if "notfound | ok | fail" {
-               ...
-       }
-
-  The reason for these limitations is that the "if" conditions are
-overloading module names, and therefore have to follow a similar
-syntax.  These limitations may be removed in a future release.
-
-  The conditions that can be checked are the names listed in section
-2, above.  Any other condition is not permitted.
-
-  
-  You can also use "elsif", as follows:
-
-       if notfound {
-               ldap1
-       }
-       elsif fail {
-               ldap2
-       }
-       else {
-               ldap3
-       }
-
-  Note that the condition being checked is the return code of the last
-module or group that was executed.  This may sometimes have odd
-side-effects:
-
-       sql
-       if notfound {
-               ldap1
-       }
-       if fail {
-               ldap2
-       }
-
-  In this case, the "ldap2" module will be executed if the "sql"
-modules returns "fail", OR if the "sql" module returns "notfound", and
-the "ldap2" module returns "fail".  For this reason, you should
-probably use "elsif" whenever you have two "if" statements right after
-one another.
-
-  The "if" checks can be nested to a depth of 30 or so, which should
-be sufficient for most configurations.
-
-
-5. Virtual Modules
-   ---------------
-
-  Some configurations may require using the same list of modules, in
-the same order, in multiple sections.  For those systems, the
-configuration can be simplified through the use of "virtual" modules.
-These modules are configured as named sub-sections of the
-"instantiate" section, as follows:
-
-       instantiate {
-               ...
-
-               redundant sql1_or_2 {
-                       sql1
-                       sql2
-               }
-       }
-
-  The name "sql1_or_2" can then be used in any other section, such as
-"authorize" or "accounting".  The result will be *exactly* as if that
-section was placed at the location of the "sql1_or_2" reference.
-
-  These virtual modules are full-fledged objects in and of themselves.
-One virtual module can refer to another virtual module, and they can
-contain "if" conditions, or any other configuration permitted in a
-section.
-
-
-7. Redundancy and Load-Balancing
-   -----------------------------
-
-  See doc/load-balance.txt for information on simple redundancy
-(fail-over) and load balancing.
-
-
-6. The Gory Details
-   ----------------
+  The Gory Details
+  ----------------
 
 The fundamental object is called a MODCALLABLE, because it is something that
 can be passed a specific radius request and returns one of the RLM_MODULE_*
@@ -388,33 +272,6 @@ authorize{...} GROUP as a whole returns RLM_MODULE_NOOP, which makes sense
 because to say the user was not found at all would be a lie, since preprocess
 apparently found him, or else it would have returned RLM_MODULE_NOTFOUND too.
 
-We could use the "default" code to simplify the above example a
-little.  The following two configurations are identical:
-
-...
-  files {
-    notfound = 1
-    noop     = 2
-    ok       = 3
-    updated  = 4
-    default  = return
-  }
-...
-
-When putting the "default" first, later definitions over-ride it's
-return code:
-
-...
-  files {
-    default  = return
-    notfound = 1
-    noop     = 2
-    ok       = 3
-    updated  = 4
-  }
-...
-
-
 [Take a deep breath - the worst is over]
 
 That RESULT preference/desirability stuff is pretty complex, but my hope is
diff --git a/doc/duplicate-users b/doc/duplicate-users
new file mode 100644 (file)
index 0000000..7b9338e
--- /dev/null
@@ -0,0 +1,162 @@
+
+User Collision in FreeRadius
+----------------------------
+
+0.  INTRODUCTION
+
+    A.  What is it?
+
+        User collision is the ability to uniquely authenticate duplicate
+        usernames in radius. In addition, it provides resources to
+        correctly identify each duplicate user in the accounting logs.
+
+    B.  Who needs it and why?
+
+        Many ISPs are acquiring other ISPs in local or remote areas.  This
+        causes problems with centralizing services such as radius because
+        of the overlap in usernames between ISPs.
+
+        For example:
+
+        o  ISP A (with 10,000 users) acquires ISP B (with 1,000 users).
+        o  ISP A determines that 375 of ISP B's 1,000 usernames conflict
+           with usernames already in use at ISP A (eg 'foo' is valid
+           username on both ISPs)
+        o  ISP A, therefore, cannot merge its user files with ISP B and
+           centralize radius
+
+        Now, about now, many of you are thinking, "what about realms?"  
+        Well, realms are great, but, in general, it will require the end
+        user to add "@domain.com", which is a pain. It means ISP A has to
+        call 375 people and tell them to add that to their login name.
+
+        And now some of you are thinking, "why couldn't you add the realm
+        in the server based on some other attribute (such as NAS-IP or
+        Calling-Station)?"  The answer is, you could, but both of those
+        solutions are a pill to maintain.  For example, what if you want
+        to merge the huntgroups (and NASs) of ISP A and ISP B?  Then the
+        NAS-IP method falls apart.  And god forbid the user call from a
+        different number or change their line for Calling-Station.
+
+        So how to solve it?  Enter user collision code in radius...
+
+    C.  How does it work?
+
+        Currently, it only works when authenticating users via the
+        following methods in FreeRadius:
+
+        o  'users' file ( Auth-Types 'Local' and 'Crypt-Local' _ONLY_ )
+        o  cached password (and shadow) file users
+                               o  rlm_fastusers module (see README.rlm_fastusers)
+
+        That's it so far.  Perhaps other module authors will include it in
+        their code later, but that is for them to decide.
+
+        Btw, the reason user collision cannot be implemented (efficiently)
+        on a non-cached /etc/passwd file is because getpwnam() will always
+        return the first user it finds with a matching username.  Thus, if
+        you're going to use the /etc/passwd file, you MUST set 'cache =
+        yes' in your radiusd.conf.  Or, you could always just put
+        duplicate usernames in the 'users' files, but you should probably
+        be caching anyway if you want a speedy server :)
+
+1.  Authentication
+
+    It currently works by using the password of the user to uniquely
+    identify and auth- enticate them.
+
+    Example:
+
+    ISP A user 'foo' has password 'bar'
+    ISP B user 'foo' has password 'bleah'
+
+    If the user logs in with 'bar' as their password, their login will be
+    accepted and they will get the reply attributes associated with what
+    you've entered for the user 'foo' password 'bar' entry.
+
+    If the user logs in with 'bleah' as the password, again, they'll be
+    authenticated, but they will get the reply attributes associated with
+    user 'foo' password 'bleah'.
+
+    So, what happens if two users have the same password?  IT
+    BREAKS.  Well, ok, it doesn't "break", but every user with the
+    associated pass will get the same reply attributes, causing grief for
+    you.  THE CODE DOES NOT CHECK FOR THIS, THAT IS YOUR JOB!
+
+    NOTE:  Again, user collision authentication *depends* on the passwords
+    being distinct!
+
+    So the security minded among us are now agast.  I'm not much for this
+    method myself, but trust me, the corporate folks are gonna love it.  
+    And it's not inherently insecure as long as the passwords remain
+    different.
+
+2.  Accounting
+
+    Ok, so now, how can we tell in the accounting logs which user 'foo'
+    logged in?  Well, again, you have a little work to do.  The code
+    identifies the user via a unique value assigned to the 'Class' reply
+    attribute in the users file.
+
+    For example:
+
+    foo Auth-Type := Local, User-Password == "bar"
+    Class = 0x0001
+
+    foo Auth-Type := Local, User-Password == "bleah"
+    Class = 0x0002
+
+    Now, you'd add other attributes as well, but let's just start with
+    'Class' by itself as a reply.  When a user 'foo' logs in with password
+    'bar', the 'Class=0x0001' reply item gets sent back to the NAS they
+    dialed into.  The NAS then adds 'Class=0x0001' to the Accounting
+    'Start' packet it sends for that user, thus uniquely identifying *this*
+    'foo' in the your accounting logs.
+
+    If the user 'foo' logs in with password 'bleah', you will get
+    'Class=0x0002' in your accounting logs.
+
+    Now, again, you should note that it is *your job* to make sure the
+    'Class' values are different for each user.  If you don't, I can assure
+    you the phones will ring off the hook when bitchy users get their
+    bills.
+
+    Obviously, this method works only for users in your 'users' files.  
+
+    If you are using a cached passwd file, then the "Full name" field in
+    the passwd file you cached will be passed back to the NAS as the value
+    of 'Class'.
+
+    Example:
+
+    /etc/passwd  ->  test:x:500:500:0x1001:/dev/null:/dev/null
+
+    In this case, "0x1001" will be passed as the value for the 'Class'
+    attribute when the Auth-Accept packet gets sent back to the NAS, and
+    then you should see 'Class=0x1001' for that user in your accounting
+    logs.
+
+    Once again, it is your job to ensure that these Class values are unique
+    for each user.
+
+D.  *Does* it work?
+
+    As of 10-01-2000, it is *extremely alpha*.  If you find bugs, by all
+    means let met know at jeff@apex.net, but make sure you include
+    relavent sections of your 'users' file and debug output from the
+    server (radiusd -X).
+
+1.  USAGE
+
+               Set 'usercollide=yes' in your radiusd.conf and either restart or
+    kill -HUP radiusd.
+
+2.  CAVEATS
+
+    Currently does not work with all modules (ie, sql, ldap, etc).
+
+3.  ACKNOWLEDGEMENT
+
+    Jeff Carneal - Author
+    Alan DeKok - for telling me about the 'Class' attribute :)
+
diff --git a/doc/examples/iplanet.ldif b/doc/examples/iplanet.ldif
deleted file mode 100644 (file)
index 04773b7..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-# This is a LDAPv3 schema for RADIUS attributes.
-# Converted for use with iPlanet/Sun Directory Servers 5.x by Arne Brutschy <abrutschy@xylon.de>
-#
-# Originally Tested on OpenLDAP 2.0.7
-# Posted by Javier Fernandez-Sanguino Pena <jfernandez@sgi.es>
-# LDAP v3 version by Jochen Friedrich <jochen@scram.de>
-# Updates by Adrian Pavlykevych <pam@polynet.lviv.ua>
-##############
-dn: cn=schema
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.1 NAME 'radiusArapFeatures' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.2 NAME 'radiusArapSecurity' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.3 NAME 'radiusArapZoneAccess' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.44 NAME 'radiusAuthType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.4 NAME 'radiusCallbackId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.5 NAME 'radiusCallbackNumber' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.6 NAME 'radiusCalledStationId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.7 NAME 'radiusCallingStationId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.8 NAME 'radiusClass' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.45 NAME 'radiusClientIPAddress' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.9 NAME 'radiusFilterId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.10 NAME 'radiusFramedAppleTalkLink' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.11 NAME 'radiusFramedAppleTalkNetwork' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.12 NAME 'radiusFramedAppleTalkZone' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.13 NAME 'radiusFramedCompression' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.14 NAME 'radiusFramedIPAddress' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.15 NAME 'radiusFramedIPNetmask' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.16 NAME 'radiusFramedIPXNetwork' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.17 NAME 'radiusFramedMTU' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.18 NAME 'radiusFramedProtocol' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.19 NAME 'radiusFramedRoute' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.20 NAME 'radiusFramedRouting' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.46 NAME 'radiusGroupName' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.47 NAME 'radiusHint' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.48 NAME 'radiusHuntgroupName' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.21 NAME 'radiusIdleTimeout' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.22 NAME 'radiusLoginIPHost' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.23 NAME 'radiusLoginLATGroup' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.24 NAME 'radiusLoginLATNode' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.25 NAME 'radiusLoginLATPort' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.26 NAME 'radiusLoginLATService' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.27 NAME 'radiusLoginService' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.28 NAME 'radiusLoginTCPPort' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.29 NAME 'radiusPasswordRetry' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.30 NAME 'radiusPortLimit' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.49 NAME 'radiusProfileDn' DESC '' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.31 NAME 'radiusPrompt' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.50 NAME 'radiusProxyToRealm' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.51 NAME 'radiusReplicateToRealm' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.52 NAME 'radiusRealm' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.32 NAME 'radiusServiceType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.33 NAME 'radiusSessionTimeout' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.34 NAME 'radiusTerminationAction' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.35 NAME 'radiusTunnelAssignmentId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.36 NAME 'radiusTunnelMediumType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.37 NAME 'radiusTunnelPassword' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.38 NAME 'radiusTunnelPreference' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.39 NAME 'radiusTunnelPrivateGroupId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.40 NAME 'radiusTunnelServerEndpoint' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.41 NAME 'radiusTunnelType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.42 NAME 'radiusVSA' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.43 NAME 'radiusTunnelClientEndpoint' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-#need to change asn1.id
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.53 NAME 'radiusSimultaneousUse' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.54 NAME 'radiusLoginTime' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.55 NAME 'radiusUserCategory' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.56 NAME 'radiusStripUserName' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.57 NAME 'dialupAccess' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.58 NAME 'radiusExpiration' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.59 NAME 'radiusCheckItem' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.60 NAME 'radiusReplyItem' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-objectClasses: ( 1.3.6.1.4.1.3317.4.3.2.1 NAME 'radiusprofile' DESC '' SUP top AUXILIARY MUST ( cn ) MAY ( radiusArapFeatures $ radiusArapSecurity $ radiusArapZoneAccess $ radiusAuthType $ radiusCallbackId $ radiusCallbackNumber $ radiusCalledStationId $ radiusCallingStationId $ radiusClass $ radiusClientIPAddress $ radiusFilterId $ radiusFramedAppleTalkLink $ radiusFramedAppleTalkNetwork $ radiusFramedAppleTalkZone $ radiusFramedCompression $ radiusFramedIPAddress $ radiusFramedIPNetmask $ radiusFramedIPXNetwork $ radiusFramedMTU $ radiusFramedProtocol $ radiusCheckItem $ radiusReplyItem $ radiusFramedRoute $ radiusFramedRouting $ radiusIdleTimeout $ radiusGroupName $ radiusHint $ radiusHuntgroupName $ radiusLoginIPHost $ radiusLoginLATGroup $ radiusLoginLATNode $ radiusLoginLATPort $ radiusLoginLATService $ radiusLoginService $ radiusLoginTCPPort $ radiusLoginTime $ radiusPasswordRetry $ radiusPortLimit $ radiusPrompt $ radiusProxyToRealm $ radiusRealm $ radiusReplicateToRealm $ radiusServiceType $ radiusSessionTimeout $ radiusStripUserName $ radiusTerminationAction $ radiusTunnelClientEndpoint $ radiusProfileDn $ radiusSimultaneousUse $ radiusTunnelAssignmentId $ radiusTunnelMediumType $ radiusTunnelPassword $ radiusTunnelPreference $ radiusTunnelPrivateGroupId $ radiusTunnelServerEndpoint $ radiusTunnelType $ radiusUserCategory $ radiusVSA $ radiusExpiration $ dialupAccess ) )
diff --git a/doc/examples/iplanet.schema b/doc/examples/iplanet.schema
deleted file mode 100644 (file)
index 0f68569..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# This is a LDAPv3 schema for RADIUS attributes.
-# Tested on Sun One Directory server 5.2
-# Created by Daniel Wilson (danielwilson_2k@yahoo.com)
-##############
-dn: cn=schema
-objectClass: top
-objectClass: ldapSubentry
-objectClass: subschema
-cn: schema
-#######################
-# aci to ensure that the standard schema attributes are visible to
-# all LDAP clients (anonymous access).
-#
-aci: (target="ldap:///cn=schema")(targetattr !="aci")(version 3.0;acl "anonymous, no acis"; allow (read, search, compare) userdn = "ldap:///anyone";
-#######################
-objectClasses: ( 1.3.6.1.4.1.3317.4.3.2.1 NAME 'radiusprofile' SUP top AUXILIARY DESC 'Free Radius schema for Directory Server 5.2' MUST (cn) MAY ( radiusArapFeatures $ radiusArapSecurity $ radiusArapZoneAccess $ radiusAuthType $ radiusCallbackId $ radiusCallbackNumber $ radiusCalledStationId $ radiusCallingStationId $ radiusClass $ radiusClientIPAddress $ radiusFilterId $ radiusFramedAppleTalkLink $ radiusFramedAppleTalkNetwork $ radiusFramedAppleTalkZone $ radiusFramedCompression $ radiusFramedIPAddress $ radiusFramedIPNetmask $ radiusFramedIPXNetwork $ radiusFramedMTU $ radiusFramedProtocol $ radiusCheckItem $ radiusReplyItem $ radiusFramedRoute $ radiusFramedRouting $ radiusIdleTimeout $ radiusGroupName $ radiusHint $ radiusHuntgroupName $ radiusLoginIPHost $ radiusLoginLATGroup $ radiusLoginLATNode $ radiusLoginLATPort $ radiusLoginLATService $ radiusLoginService $ radiusLoginTCPPort $ radiusLoginTime $ radiusPasswordRetry $ radiusPortLimit $ radiusPrompt $ radiusProxyToRealm $ radiusRealm $ radiusReplicateToRealm $ radiusServiceType $ radiusSessionTimeout $ radiusStripUserName $ radiusTerminationAction $ radiusTunnelClientEndpoint $ radiusProfileDn $ radiusSimultaneousUse $ radiusTunnelAssignmentId $ radiusTunnelMediumType $ radiusTunnelPassword $ radiusTunnelPreference $ radiusTunnelPrivateGroupId $ radiusTunnelServerEndpoint $ radiusTunnelType $ radiusUserCategory $ radiusVSA $ radiusExpiration $ dialupAccess) X-ORIGIN 'user defined')
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.1 NAME 'radiusArapFeatures' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined')
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.2 NAME 'radiusArapSecurity' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined')
-attributeTypes: ( 1.3.6.1.4.1.3317.4.3.1.3 NAME 'radiusArapZoneAccess' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined')
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.44 NAME 'radiusAuthType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.4 NAME 'radiusCallbackId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.5 NAME 'radiusCallbackNumber' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.6 NAME 'radiusCalledStationId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.7 NAME 'radiusCallingStationId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.8 NAME 'radiusClass' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.45 NAME 'radiusClientIPAddress' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.9 NAME 'radiusFilterId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.10 NAME 'radiusFramedAppleTalkLink' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.11 NAME 'radiusFramedAppleTalkNetwork' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.12 NAME 'radiusFramedAppleTalkZone' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.13 NAME 'radiusFramedCompression' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.14 NAME 'radiusFramedIPAddress' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.15 NAME 'radiusFramedIPNetmask' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.16 NAME 'radiusFramedIPXNetwork' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.17 NAME 'radiusFramedMTU' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.18 NAME 'radiusFramedProtocol' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.19 NAME 'radiusFramedRoute' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.20 NAME 'radiusFramedRouting' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.46 NAME 'radiusGroupName' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.47 NAME 'radiusHint' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.48 NAME 'radiusHuntgroupName' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.21 NAME 'radiusIdleTimeout' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.22 NAME 'radiusLoginIPHost' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.23 NAME 'radiusLoginLATGroup' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.24 NAME 'radiusLoginLATNode' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.25 NAME 'radiusLoginLATPort' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.26 NAME 'radiusLoginLATService' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.27 NAME 'radiusLoginService' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.28 NAME 'radiusLoginTCPPort' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.29 NAME 'radiusPasswordRetry' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.30 NAME 'radiusPortLimit' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.49 NAME 'radiusProfileDn' DESC '' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.31 NAME 'radiusPrompt' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.50 NAME 'radiusProxyToRealm' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.51 NAME 'radiusReplicateToRealm' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.52 NAME 'radiusRealm' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.32 NAME 'radiusServiceType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.33 NAME 'radiusSessionTimeout' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.34 NAME 'radiusTerminationAction' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.35 NAME 'radiusTunnelAssignmentId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.36 NAME 'radiusTunnelMediumType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.37 NAME 'radiusTunnelPassword' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.38 NAME 'radiusTunnelPreference' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.39 NAME 'radiusTunnelPrivateGroupId' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.40 NAME 'radiusTunnelServerEndpoint' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.41 NAME 'radiusTunnelType' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.42 NAME 'radiusVSA' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.43 NAME 'radiusTunnelClientEndpoint' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.53 NAME 'radiusSimultaneousUse' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.54 NAME 'radiusLoginTime' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.55 NAME 'radiusUserCategory' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.56 NAME 'radiusStripUserName' DESC '' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.57 NAME 'dialupAccess' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.58 NAME 'radiusExpiration' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'user defined' )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.59 NAME 'radiusCheckItem' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributeTypes:  ( 1.3.6.1.4.1.3317.4.3.1.60 NAME 'radiusReplyItem' DESC '' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
index 6273410..a151025 100644 (file)
@@ -1,6 +1,4 @@
 /***************************************************************************
- * $Id$                   *
- *                                                                        *
  * db_mssql.sql                                                           *
  *                                                                         *
  * Database schema for MSSQL server                                       *
@@ -19,7 +17,6 @@ CREATE TABLE [radacct] (
        [AcctSessionId] [varchar] (32) NOT NULL ,
        [AcctUniqueId] [varchar] (32) NOT NULL ,
        [UserName] [varchar] (64) NOT NULL ,
-       [GroupName] [varchar] (64) NOT NULL ,
        [Realm] [varchar] (64) NULL ,
        [NASIPAddress] [varchar] (15) NOT NULL ,
        [NASPortId] [varchar] (15) NULL ,
@@ -84,8 +81,8 @@ CREATE TABLE [radreply] (
 ) ON [PRIMARY]
 GO
 
-/****** Object:  Table [radusergroup]    Script Date: 26.03.02 16:55:18 ******/
-CREATE TABLE [radusergroup] (
+/****** Object:  Table [usergroup]    Script Date: 26.03.02 16:55:18 ******/
+CREATE TABLE [usergroup] (
        [id] [int] IDENTITY (1, 1) NOT NULL ,
        [UserName] [varchar] (64) NOT NULL ,
        [GroupName] [varchar] (64) NULL
@@ -167,10 +164,10 @@ ALTER TABLE [radreply] WITH NOCHECK ADD
        )  ON [PRIMARY]
 GO
 
-ALTER TABLE [radusergroup] WITH NOCHECK ADD
-       CONSTRAINT [DF_radusergroup_UserName] DEFAULT ('') FOR [UserName],
-       CONSTRAINT [DF_radusergroup_GroupName] DEFAULT ('') FOR [GroupName],
-       CONSTRAINT [PK_radusergroup] PRIMARY KEY  NONCLUSTERED
+ALTER TABLE [usergroup] WITH NOCHECK ADD
+       CONSTRAINT [DF_usergroup_UserName] DEFAULT ('') FOR [UserName],
+       CONSTRAINT [DF_usergroup_GroupName] DEFAULT ('') FOR [GroupName],
+       CONSTRAINT [PK_usergroup] PRIMARY KEY  NONCLUSTERED
        (
                [id]
        )  ON [PRIMARY]
@@ -209,5 +206,5 @@ GO
  CREATE  INDEX [UserName] ON [radreply]([UserName]) ON [PRIMARY]
 GO
 
- CREATE  INDEX [UserName] ON [radusergroup]([UserName]) ON [PRIMARY]
+ CREATE  INDEX [UserName] ON [usergroup]([UserName]) ON [PRIMARY]
 GO
index d798e85..0c630a0 100644 (file)
@@ -1,6 +1,4 @@
 ###########################################################################
-# $Id$                 #
-#                                                                         #
 #  db_mysql.sql                     rlm_sql - FreeRADIUS SQL Module       #
 #                                                                         #
 #     Database schema for MySQL rlm_sql module                            #
@@ -19,7 +17,6 @@ CREATE TABLE radacct (
   AcctSessionId varchar(32) NOT NULL default '',
   AcctUniqueId varchar(32) NOT NULL default '',
   UserName varchar(64) NOT NULL default '',
-  GroupName varchar(64) NOT NULL default '',
   Realm varchar(64) default '',
   NASIPAddress varchar(15) NOT NULL default '',
   NASPortId varchar(15) default NULL,
@@ -108,10 +105,10 @@ CREATE TABLE radreply (
 
 
 #
-# Table structure for table 'radusergroup'
+# Table structure for table 'usergroup'
 #
 
-CREATE TABLE radusergroup (
+CREATE TABLE usergroup (
   UserName varchar(64) NOT NULL default '',
   GroupName varchar(64) NOT NULL default '',
   priority int(11) NOT NULL default '1',
diff --git a/doc/examples/openldap.schema b/doc/examples/openldap.schema
deleted file mode 100644 (file)
index 55d34f3..0000000
+++ /dev/null
@@ -1,587 +0,0 @@
-# This is a LDAPv3 schema for RADIUS attributes.
-# Tested on OpenLDAP 2.0.7
-# Posted by Javier Fernandez-Sanguino Pena <jfernandez@sgi.es>
-# LDAP v3 version by Jochen Friedrich <jochen@scram.de>
-# Updates by Adrian Pavlykevych <pam@polynet.lviv.ua>
-##############
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.1
-      NAME 'radiusArapFeatures'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.2
-      NAME 'radiusArapSecurity'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.3
-      NAME 'radiusArapZoneAccess'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.44
-     NAME 'radiusAuthType'
-     DESC ''
-     EQUALITY caseIgnoreIA5Match
-     SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-     SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.4
-      NAME 'radiusCallbackId'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.5
-      NAME 'radiusCallbackNumber'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.6
-      NAME 'radiusCalledStationId'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.7
-      NAME 'radiusCallingStationId'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.8
-      NAME 'radiusClass'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.45
-     NAME 'radiusClientIPAddress'
-     DESC ''
-     EQUALITY caseIgnoreIA5Match
-     SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-     SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.9
-      NAME 'radiusFilterId'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.10
-      NAME 'radiusFramedAppleTalkLink'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.11
-      NAME 'radiusFramedAppleTalkNetwork'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.12
-      NAME 'radiusFramedAppleTalkZone'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.13
-      NAME 'radiusFramedCompression'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.14
-      NAME 'radiusFramedIPAddress'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.15
-      NAME 'radiusFramedIPNetmask'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.16
-      NAME 'radiusFramedIPXNetwork'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.17
-      NAME 'radiusFramedMTU'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.18
-      NAME 'radiusFramedProtocol'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.19
-      NAME 'radiusFramedRoute'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.20
-      NAME 'radiusFramedRouting'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.46
-      NAME 'radiusGroupName'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.47
-      NAME 'radiusHint'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.48
-      NAME 'radiusHuntgroupName'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.21
-      NAME 'radiusIdleTimeout'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.22
-      NAME 'radiusLoginIPHost'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.23
-      NAME 'radiusLoginLATGroup'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.24
-      NAME 'radiusLoginLATNode'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.25
-      NAME 'radiusLoginLATPort'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.26
-      NAME 'radiusLoginLATService'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.27
-      NAME 'radiusLoginService'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.28
-      NAME 'radiusLoginTCPPort'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.29
-      NAME 'radiusPasswordRetry'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.30
-      NAME 'radiusPortLimit'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.49
-      NAME 'radiusProfileDn'
-      DESC ''
-      EQUALITY distinguishedNameMatch
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.31
-      NAME 'radiusPrompt'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.50
-      NAME 'radiusProxyToRealm'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.51
-      NAME 'radiusReplicateToRealm'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.52
-      NAME 'radiusRealm'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.32
-      NAME 'radiusServiceType'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.33
-      NAME 'radiusSessionTimeout'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.34
-      NAME 'radiusTerminationAction'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.35
-      NAME 'radiusTunnelAssignmentId'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.36
-      NAME 'radiusTunnelMediumType'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.37
-      NAME 'radiusTunnelPassword'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.38
-      NAME 'radiusTunnelPreference'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.39
-      NAME 'radiusTunnelPrivateGroupId'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.40
-      NAME 'radiusTunnelServerEndpoint'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.41
-      NAME 'radiusTunnelType'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.42
-      NAME 'radiusVSA'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.43
-      NAME 'radiusTunnelClientEndpoint'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-
-#need to change asn1.id
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.53
-      NAME 'radiusSimultaneousUse'
-      DESC ''
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.54
-      NAME 'radiusLoginTime'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.55
-      NAME 'radiusUserCategory'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.56
-      NAME 'radiusStripUserName'
-      DESC ''
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.57
-      NAME 'dialupAccess'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.58
-      NAME 'radiusExpiration'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.59
-      NAME 'radiusCheckItem'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.60
-      NAME 'radiusReplyItem'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.61
-      NAME 'radiusNASIpAddress'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-      SINGLE-VALUE
-   )
-
-attributetype
-   ( 1.3.6.1.4.1.3317.4.3.1.62
-      NAME 'radiusReplyMessage'
-      DESC ''
-      EQUALITY caseIgnoreIA5Match
-      SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-   )
-
-
-objectclass
-   ( 1.3.6.1.4.1.3317.4.3.2.1
-      NAME 'radiusprofile'
-      SUP top AUXILIARY
-      DESC ''
-      MUST cn
-      MAY ( radiusArapFeatures $ radiusArapSecurity $ radiusArapZoneAccess $
-            radiusAuthType $ radiusCallbackId $ radiusCallbackNumber $
-            radiusCalledStationId $ radiusCallingStationId $ radiusClass $
-            radiusClientIPAddress $ radiusFilterId $ radiusFramedAppleTalkLink $
-            radiusFramedAppleTalkNetwork $ radiusFramedAppleTalkZone $
-            radiusFramedCompression $ radiusFramedIPAddress $
-            radiusFramedIPNetmask $ radiusFramedIPXNetwork $
-            radiusFramedMTU $ radiusFramedProtocol $
-           radiusCheckItem $ radiusReplyItem $
-            radiusFramedRoute $ radiusFramedRouting $ radiusIdleTimeout $
-            radiusGroupName $ radiusHint $ radiusHuntgroupName $
-            radiusLoginIPHost $ radiusLoginLATGroup $ radiusLoginLATNode $
-            radiusLoginLATPort $ radiusLoginLATService $ radiusLoginService $
-            radiusLoginTCPPort $ radiusLoginTime $ radiusPasswordRetry $
-            radiusPortLimit $ radiusPrompt $ radiusProxyToRealm $
-            radiusRealm $ radiusReplicateToRealm $ radiusServiceType $
-            radiusSessionTimeout $ radiusStripUserName $
-            radiusTerminationAction $ radiusTunnelClientEndpoint $ radiusProfileDn $
-            radiusSimultaneousUse $ radiusTunnelAssignmentId $
-            radiusTunnelMediumType $ radiusTunnelPassword $ radiusTunnelPreference $
-            radiusTunnelPrivateGroupId $ radiusTunnelServerEndpoint $
-            radiusTunnelType $ radiusUserCategory $ radiusVSA $
-            radiusExpiration $ dialupAccess $ radiusNASIpAddress $
-            radiusReplyMessage )
-   )
-
-objectclass
-  ( 1.3.6.1.4.1.3317.4.3.2.2
-       NAME 'radiusObjectProfile'
-       SUP top STRUCTURAL
-       DESC 'A Container Objectclass to be used for creating radius profile object'
-       MUST cn
-       MAY ( uid $ userPassword $ description )
-  )
index 3910a83..3d5082c 100644 (file)
@@ -43,8 +43,7 @@ CREATE TABLE radacct (
        radacctid               INT PRIMARY KEY,
        acctsessionid           VARCHAR(32) NOT NULL,
        acctuniqueid            VARCHAR(32),
-       username                VARCHAR(64) NOT NULL,
-       groupname               VARCHAR(32) NOT NULL,
+       username                VARCHAR(32) NOT NULL,
        realm                   VARCHAR(30),
        nasipaddress            VARCHAR(15) NOT NULL,
        nasportid               VARCHAR(15),
@@ -155,22 +154,22 @@ CREATE OR REPLACE TRIGGER radreply_serialnumber
 /
 
 /*
- * Table structure for table 'radusergroup'
+ * Table structure for table 'usergroup'
  */
-CREATE TABLE radusergroup (
+CREATE TABLE usergroup (
        id              INT PRIMARY KEY,
        UserName        VARCHAR(30) UNIQUE NOT NULL,
        GroupName       VARCHAR(30)
 );
-CREATE SEQUENCE radusergroup_seq START WITH 1 INCREMENT BY 1;
+CREATE SEQUENCE usergroup_seq START WITH 1 INCREMENT BY 1;
 
 /* Trigger to emulate a serial # on the primary key */
-CREATE OR REPLACE TRIGGER radusergroup_serialnumber
-       BEFORE INSERT OR UPDATE OF id ON radusergroup
+CREATE OR REPLACE TRIGGER usergroup_serialnumber
+       BEFORE INSERT OR UPDATE OF id ON usergroup
        FOR EACH ROW
        BEGIN
                if ( :new.id = 0 or :new.id is null ) then
-                       SELECT radusergroup_seq.nextval into :new.id from dual;
+                       SELECT usergroup_seq.nextval into :new.id from dual;
                end if;
        END;
 /
index 49c6f7b..4cf1133 100644 (file)
@@ -18,7 +18,6 @@ CREATE TABLE radacct (
        AcctSessionId           VARCHAR(32) NOT NULL,
        AcctUniqueId            VARCHAR(32) NOT NULL,
        UserName                VARCHAR(253),
-       GroupName               VARCHAR(253),
        Realm                   VARCHAR(64),
        NASIPAddress            INET NOT NULL,
        NASPortId               VARCHAR(15),
@@ -35,11 +34,11 @@ CREATE TABLE radacct (
        CallingStationId        VARCHAR(50),
        AcctTerminateCause      VARCHAR(32),
        ServiceType             VARCHAR(32),
-       XAscendSessionSvrKey    VARCHAR(10),
        FramedProtocol          VARCHAR(32),
        FramedIPAddress         INET,
        AcctStartDelay          BIGINT,
-       AcctStopDelay           BIGINT
+       AcctStopDelay           BIGINT,
+       XAscendSessionSvrKey    VARCHAR(10)
 );
 -- This index may be usefull..
 -- CREATE UNIQUE INDEX radacct_whoson on radacct (AcctStartTime, nasipaddress);
@@ -129,18 +128,18 @@ create index radreply_UserName on radreply (UserName,Attribute);
 -- create index radreply_UserName_lower on radreply (lower(UserName),Attribute);
 
 /*
- * Table structure for table 'radusergroup'
+ * Table structure for table 'usergroup'
  */
-CREATE TABLE radusergroup (
+CREATE TABLE usergroup (
        UserName        VARCHAR(64) NOT NULL DEFAULT '',
        GroupName       VARCHAR(64) NOT NULL DEFAULT '',
        priority        INTEGER NOT NULL DEFAULT 0
 );
-create index radusergroup_UserName on radusergroup (UserName);
+create index usergroup_UserName on usergroup (UserName);
 /*
  * Use this index if you use case insensitive queries
  */
--- create index radusergroup_UserName_lower on radusergroup (lower(UserName));
+-- create index usergroup_UserName_lower on usergroup (lower(UserName));
 
 /*
  * Table structure for table 'realmgroup'
@@ -185,14 +184,12 @@ create index nas_nasname on nas (nasname);
 --
 
 CREATE TABLE radpostauth (
-       id                      BIGSERIAL PRIMARY KEY,
-       username                VARCHAR(253) NOT NULL,
-       pass                    VARCHAR(128),
-       reply                   VARCHAR(32),
-       CalledStationId         VARCHAR(50),
-       CallingStationId        VARCHAR(50),
-       authdate                TIMESTAMP with time zone NOT NULL default 'now'
-);
+       id              BIGSERIAL PRIMARY KEY,
+       username        VARCHAR(253) NOT NULL,
+       pass            VARCHAR(128),
+       reply           VARCHAR(32),
+       authdate        TIMESTAMP with time zone NOT NULL default 'now'
+) ;
 
 --
 -- Table structure for table 'radippool'
@@ -200,21 +197,16 @@ CREATE TABLE radpostauth (
 
 CREATE TABLE radippool (
        id                      BIGSERIAL PRIMARY KEY,
-       pool_name               varchar(64) NOT NULL,
-       FramedIPAddress         INET NOT NULL,
-       NASIPAddress            VARCHAR(16) NOT NULL default '',
-       pool_key                VARCHAR(64) NOT NULL default 0,
+       pool_name               text NOT NULL,
+       FramedIPAddress         INET,
+       NASIPAddress            text NOT NULL,
        CalledStationId         VARCHAR(64),
-       CallingStationId        text NOT NULL default ''::text,
-       expiry_time             TIMESTAMP(0) without time zone NOT NULL default 'now'::timestamp(0),
-       username                text DEFAULT ''::text
+       CallingStationId        text NOT NULL DEFAULT ''::text,
+       expiry_time             TIMESTAMP(0) without time zone NOT NULL,
+       username                text DEFAULT ''::text,
+       pool_key                VARCHAR(30) NOT NULL
 );
 
-CREATE INDEX radippool_poolname_ipaadr ON radippool USING btree (pool_name, framedipaddress);
-CREATE INDEX radippool_poolname_expire ON radippool USING btree (pool_name, expiry_time);
-CREATE INDEX radippool_nasipaddr_poolkey ON radippool USING btree (nasipaddress, pool_key);
-CREATE INDEX radippool_nasipaddr_calling ON radippool USING btree (nasipaddress, callingstationid);
-
 --
 -- Table structure for table 'dictionary'
 -- This is not currently used by FreeRADIUS
diff --git a/doc/examples/postgresql_update_radacct_group_trigger.sql b/doc/examples/postgresql_update_radacct_group_trigger.sql
deleted file mode 100644 (file)
index ca01d60..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * $Id$
- *
- * OPTIONAL Postgresql trigger for FreeRADIUS
- *
- * This trigger updates fills in the groupname field (which doesnt come in Accounting packets)
- * by querying the radusergroup table.
- * This makes it easier to do group summary reports, however note that it does add some extra
- * database load to 50% of your SQL accounting queries. If you dont care about group summary
- * reports then you dont need to install this.
- *
- */
-
-
-CREATE OR REPLACE FUNCTION upd_radgroups() RETURNS trigger AS'
-
-DECLARE
-        v_groupname varchar;
-
-BEGIN
-        SELECT INTO v_groupname groupname FROM radusergroup WHERE calledstationid = NEW.calledstationid AND username = NEW.username;
-        IF FOUND THEN
-                UPDATE radacct SET groupname = v_groupname WHERE radacctid = NEW.radacctid;
-        END IF;
-
-        RETURN NEW;
-END
-
-'LANGUAGE plpgsql;
-
-
-DROP TRIGGER upd_radgroups ON radacct;
-
-CREATE TRIGGER upd_radgroups AFTER INSERT ON radacct
-    FOR EACH ROW EXECUTE PROCEDURE upd_radgroups();
-
-
index 4a92671..5496707 100644 (file)
@@ -3,7 +3,7 @@ Dusty Doris
 dusty at doris dot cc
 01-09-2003
 
-This document describes how to setup Freeradius on a Freebsd machine
+This document decribes how to setup Freeradius on a Freebsd machine
 using LDAP as a backend.  This is by no means complete and your
 mileage may vary.  If you are having any problems with the setup of
 your freeradius installation, please read the documentation that comes
@@ -1075,7 +1075,7 @@ The next module is files, which is commonly know as the users file.  The users
 file will start with either a username to determine how to authorize a specific 
 user, or a DEFAULT setting.  In each line it will define what items must be 
 present for there to be a match in the form of attribute == value.  If all the 
-required attributes are matched, then attributes specified with attribute := 
+required attributes are matched, then attributes specified with attribte := 
 value will be set for that user.  If no match is found the users file will 
 continue to be processed until there is a match.  The last DEFAULT setting will 
 be set as a catch-all, in case there is no previous match.  If a match is made, 
index 72906aa..0151258 100644 (file)
@@ -81,7 +81,7 @@ then log to the detail file"
        ==========================
 
   If you want to do redundancy and load-balancing among three
-modules, the configuration is quite complex:
+modules, the configuration is complex:
 
 ...
   load-balance {
@@ -147,58 +147,5 @@ one picked for load-balancing is down, load-balance among the
 remaining two.  If that one is down, pick the one remaining 'live'
 server".
 
-  The "redundant-load-balance" section can contain any number of
-modules.
-
-
-  Interaction with "if" and "else"
-  --------------------------------
-
-  It's best to have "if" and "else" blocks contain "load-balance" or
-"redundant-load-balance" sections, rather than the other way around.
-The "else" and "elsif" sections cannot appear inside of a
-"load-balance" or "redundant-load-balance" section, because the "else"
-condition would be chose as one of the modules for load-balancing,
-which is not what you want.
-
-  It's OK to have a plain "if" block inside of a "load-balance" or
-"redundant-load-balance" section.  In that case, the "if" condition
-checks the return code of the module or group that executed just
-before the "load-balance" section.  It does *not* check the return
-code of the previous module in the section.
-
-  The following table illustrates which sections can be sub-sections
-of others.  If an entry for a row/column is empty, then that
-combination is not allowed.
-
-           x = allowed
-           i = allowed if immediately after an 'if or 'elsif'
-
-
-   Allowed:    group   redundant  l-b  r-l-b   if    else  elsif
-
-Container:
-
-  group          x        x        x      x     x     i     i
-
-  if             x        x        x      x     x     i     i
-
-  else           i        i        i      i     i     i     i
-
-  elsif          i        i        i      i     i     i     i
-
-  l-b            x        x        x      x     x
-
-  r-l-b          x        x        x      x     x
-
-  redundant      x        x        x      x
-
-
-  e.g. "redundant" can contain "load-balance", but not "if", "else",
-or "eslif".  "if" can contain any other section, but if it contains
-"else" or "elsif", they have to have be listed after a second "if"
-section, inside of the first "if".
-
-
 ----------------------------------------------------------------------
 $Id$
diff --git a/doc/radrelay b/doc/radrelay
new file mode 100644 (file)
index 0000000..1df1963
--- /dev/null
@@ -0,0 +1,136 @@
+
+             Accounting replication with radrelay.
+
+
+0. INTRODUCTION
+
+   Often people run multiple radius servers; at least one primary and
+   one backup server. When the primary goes down, most NASes detect that
+   and switch to the backup server.
+
+   That will cause your accounting packets to go the the backup
+   server - and some NASes don't even switch back to the primary
+   server when it comes back up.
+
+   That means you miss accounting records or must jump through hoops
+   to combine the different detail files from multiple servers. It
+   also means that the session database ("radutmp", used for radwho
+   and simultaneous use detection) gets out of sync.
+
+1. REPLICATION
+
+   Radrelay is a program that does the equivalent of tail(1) on a
+   accounting detail file. Each time the server writes a packet
+   to this file, radrelay reads it and sends it to a remote radius
+   server. If all works well, radrelay gets replies from the remote
+   server as it should. When it reaches end-of-file, it locks the
+   file, renames it to <filename>.work, and waits for all it's
+   accounting requests to get answered. As soon as they are
+   answered, <filename.work> is deleted.
+
+   When radrelay starts up it first checks for <filename.work>
+   before it starts processing the standard detail file. This
+   ensures that no packets get lost.
+
+   Even if the primary server is down for a day, or if the secondary
+   server crashes and reboots, radrelay will buffer the accounting
+   packets and send them to the remote accounting server.
+
+   Radrelay checks the "Client-IP-Address" attribute in each record,
+   and if it's the same as the remote server it will not replicate
+   that record to prevent loops. That means you can point radrelay
+   to the primary server on the backup host, and to the backup server
+   on the primary host, to have complete records on both.
+
+2. USAGE
+
+   First, you should make radiusd log to an extra, single detail file.
+   This is probably done easiest by adding an extra instance of the
+   detail module to your radiusd.conf.
+
+   For example:
+
+   detail detail1 {
+       detailfile = %A/%{Client-IP-Address}/detail-%Y%m
+       detailperm = 0600
+       dirperm = 0755
+   }
+   detail detail2 {
+       detailfile = ${radacctdir}/detail-combined
+       detailperm = 0600
+       dirperm = 0755
+       locking = yes
+   }
+
+   [...]
+
+   accounting {
+        [...]
+       detail1
+        detail2
+        [...]
+   }
+
+   In the above example, the instance detail1 of the detail module
+   represents your original detail logging. detail2 will create a
+   detail file dedicated only to radrelay. Note the use of "locking = yes",
+   this is _very very_ important when using the detail module in combination
+   with radrelay. It's used to keep both the detail module and radrelay
+   playing nice with each other.
+
+   Next, you need to fire up radrelay.
+
+   For example:
+
+   radrelay -S secret_file <server> detail-combined
+
+   The use of -S is recommended over -s due to the fact that your secret
+   won't show up with ps. You should also make sure your secret file is not
+   world readable.
+
+   If the server you are relaying to is included in your 'clients.conf' file
+   using the '-n [shortname]' commandline option is probably easiest. This
+   means you won't have to give the remote server address or the shared
+   secret when you start radrelay.
+
+   You should never logrotate your detail file, radrelay will take care of
+   this for you.
+
+3. REPLICATION AND PROXYING
+
+   If you have a primary and a backup server with identical configs
+   that both proxy for certain realms to other radius servers, the
+   remote server might end up with duplicate accounting info - the
+   accounting packet is received by the backup server, proxied to
+   the remote server and replicated to the primary server, then the
+   primary server proxies the same packet to the remote radius server
+   again because it doesn't know that that was already done.
+
+   To prevent this scenario, FreeRADIUS writes an extra attribute
+   to the detail file if it has proxied the accounting packet, the
+   vendor-specific attribute 'Freeradius-Proxied-To'. It contains the
+   address of the remote radius server. Radrelay replicates this
+   attribute just like any other to the primary server. If the
+   primary server wants to proxy an accounting packet to a remote
+   radius server, it first checks the packet to see if the
+   'Freeradius-Proxied-To' attribute is present. If it is, and it
+   contains the IP address of the remote radius server, it knows
+   that it doesn't need to proxy this packet to the remote server
+   once more. Problem solved!
+
+4. NOTES
+
+   Only attributes that are defined in the dictionary are replicated.
+   Unknown attributes are simply ignored.
+
+   Radrelay doesn't re-read its config files on a SIGHUP. It uses
+   two config files - the dictionary (which can consist of multiple
+   files ofcourse if you use $INCLUDE) and possibly the secret file.
+   If you modify one of those files you need to restart radrelay.
+
+5. CREDITS
+   Original   - Miquel van Smoorenburg <miquels@cistron.nl>
+               Written for the Cistron radius project.
+   2002-06-09 - Simon Ekstrand <simon@routemeister.net>
+               Ported to the FreeRADIUS project.
+
index 4d8fd43..c659d30 100644 (file)
@@ -7,26 +7,19 @@
 include ../../Make.inc
 
 RFC    = rfc2548.txt rfc2865.txt rfc2866.txt rfc2867.txt rfc2868.txt \
-         rfc2869.txt rfc3162.txt rfc3576.txt rfc3579.txt rfc3580.txt \
-         rfc4590.txt
+         rfc2869.txt rfc3162.txt
 
 all:
 
 html: refs
        ./rewrite.pl $(RFC)
-       ./per-rfc.pl $(RFC)
        @touch .rewrite
 
-index.html: html
-       ./update.sh
-
 refs: $(RFC)
        ./genref.pl $(RFC) > refs
-       @echo 'rfc2865 Class' >> refs
-       @echo 'rfc2865 State' >> refs
 
 clean:
-       rm -f refs *rfc*.html *~ .rewrite index.html
+       rm -f refs rfc*.html *~ .rewrite index.html
 
 install:
        $(INSTALL) -d -m 755 $(R)$(docdir)/rfc
index 8f15be2..7852a2f 100644 (file)
@@ -2,15 +2,16 @@
 <HTML>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Perl">
-   <title>rfc4590.html</title>
+   <title>RADIUS Attribute List</title>
 </head>
-<body>
+<body bgcolor="#ffffff" >
 
-<H2>RADIUS Attribute List</H2>
+<H1>RADIUS Attribute List</H1>
 
-<H3>A</H3>
+This is a list of RADIUS attributes, automatically generated from the
+relevant RFC's.  Any errors or omissions are unintentional.
 
+<H2>A</H2>
 <UL>
 <A HREF="rfc2869.html#ARAP-Challenge-Response">ARAP-Challenge-Response</A><BR>
 <A HREF="rfc2869.html#ARAP-Features">ARAP-Features</A><BR>
@@ -43,8 +44,9 @@
 <A HREF="rfc2867.html#Acct-Tunnel-Packets-Lost">Acct-Tunnel-Packets-Lost</A><BR>
 </UL>
 
-<H3>C</H3>
+<H2>B</H2>
 
+<H2>C</H2>
 <UL>
 <A HREF="rfc2865.html#CHAP-Challenge">CHAP-Challenge</A><BR>
 <A HREF="rfc2865.html#CHAP-Password">CHAP-Password</A><BR>
 <A HREF="rfc2865.html#Callback-Number">Callback-Number</A><BR>
 <A HREF="rfc2865.html#Called-Station-Id">Called-Station-Id</A><BR>
 <A HREF="rfc2865.html#Calling-Station-Id">Calling-Station-Id</A><BR>
-<A HREF="rfc3576.html#Change-of-Authorization">Change-of-Authorization</A><BR>
 <A HREF="rfc2865.html#Class">Class</A><BR>
 <A HREF="rfc2869.html#Configuration-Token">Configuration-Token</A><BR>
 <A HREF="rfc2869.html#Connect-Info">Connect-Info</A><BR>
 </UL>
 
-<H3>D</H3>
-
-<UL>
-<A HREF="rfc4590.html#Digest-AKA-Auts">Digest-AKA-Auts</A><BR>
-<A HREF="rfc4590.html#Digest-Algorithm">Digest-Algorithm</A><BR>
-<A HREF="rfc4590.html#Digest-Auth-Param">Digest-Auth-Param</A><BR>
-<A HREF="rfc4590.html#Digest-CNonce">Digest-CNonce</A><BR>
-<A HREF="rfc4590.html#Digest-Domain">Digest-Domain</A><BR>
-<A HREF="rfc4590.html#Digest-Entity-Body-Hash">Digest-Entity-Body-Hash</A><BR>
-<A HREF="rfc4590.html#Digest-HA1">Digest-HA1</A><BR>
-<A HREF="rfc4590.html#Digest-Method">Digest-Method</A><BR>
-<A HREF="rfc4590.html#Digest-Nextnonce">Digest-Nextnonce</A><BR>
-<A HREF="rfc4590.html#Digest-Nonce">Digest-Nonce</A><BR>
-<A HREF="rfc4590.html#Digest-Nonce-Count">Digest-Nonce-Count</A><BR>
-<A HREF="rfc4590.html#Digest-Opaque">Digest-Opaque</A><BR>
-<A HREF="rfc4590.html#Digest-Qop">Digest-Qop</A><BR>
-<A HREF="rfc4590.html#Digest-Realm">Digest-Realm</A><BR>
-<A HREF="rfc4590.html#Digest-Response">Digest-Response</A><BR>
-<A HREF="rfc4590.html#Digest-Response-Auth">Digest-Response-Auth</A><BR>
-<A HREF="rfc4590.html#Digest-Stale">Digest-Stale</A><BR>
-<A HREF="rfc4590.html#Digest-URI">Digest-URI</A><BR>
-<A HREF="rfc4590.html#Digest-Username">Digest-Username</A><BR>
-</UL>
-
-<H3>E</H3>
+<H2>D</H2>
 
+<H2>E</H2>
 <UL>
 <A HREF="rfc2869.html#EAP-Message">EAP-Message</A><BR>
-<A HREF="rfc3576.html#Error-Cause">Error-Cause</A><BR>
 <A HREF="rfc2869.html#Event-Timestamp">Event-Timestamp</A><BR>
 </UL>
 
-<H3>F</H3>
-
+<H2>F</H2>
 <UL>
-<A HREF="rfc3580.html#Filter-ID">Filter-ID</A><BR>
 <A HREF="rfc2865.html#Filter-Id">Filter-Id</A><BR>
 <A HREF="rfc2865.html#Framed-AppleTalk-Link">Framed-AppleTalk-Link</A><BR>
 <A HREF="rfc2865.html#Framed-AppleTalk-Network">Framed-AppleTalk-Network</A><BR>
 <A HREF="rfc2865.html#Framed-Compression">Framed-Compression</A><BR>
 <A HREF="rfc2865.html#Framed-IP-Address">Framed-IP-Address</A><BR>
 <A HREF="rfc2865.html#Framed-IP-Netmask">Framed-IP-Netmask</A><BR>
-<A HREF="rfc2865.html#Framed-IPX-Network">Framed-IPX-Network</A><BR>
 <A HREF="rfc3162.html#Framed-IPv6-Pool">Framed-IPv6-Pool</A><BR>
 <A HREF="rfc3162.html#Framed-IPv6-Prefix">Framed-IPv6-Prefix</A><BR>
 <A HREF="rfc3162.html#Framed-IPv6-Route">Framed-IPv6-Route</A><BR>
 <A HREF="rfc3162.html#Framed-Interface-Id">Framed-Interface-Id</A><BR>
+<A HREF="rfc2865.html#Framed-IPX-Network">Framed-IPX-Network</A><BR>
 <A HREF="rfc2865.html#Framed-MTU">Framed-MTU</A><BR>
 <A HREF="rfc2869.html#Framed-Pool">Framed-Pool</A><BR>
 <A HREF="rfc2865.html#Framed-Protocol">Framed-Protocol</A><BR>
 <A HREF="rfc2865.html#Framed-Routing">Framed-Routing</A><BR>
 </UL>
 
-<H3>I</H3>
+<H2>G</H2>
+
+<H2>H</H2>
 
+<H2>I</H2>
 <UL>
 <A HREF="rfc2865.html#Idle-Timeout">Idle-Timeout</A><BR>
 </UL>
 
-<H3>K</H3>
+<H2>J</H2>
 
+<H2>K</H2>
 <UL>
 <A HREF="rfc2865.html#Keep-Alives">Keep-Alives</A><BR>
 </UL>
 
-<H3>L</H3>
-
+<H2>L</H2>
 <UL>
 <A HREF="rfc2865.html#Login-IP-Host">Login-IP-Host</A><BR>
 <A HREF="rfc3162.html#Login-IPv6-Host">Login-IPv6-Host</A><BR>
 <A HREF="rfc2865.html#Login-TCP-Port">Login-TCP-Port</A><BR>
 </UL>
 
-<H3>M</H3>
-
+<H2>M</H2>
 <UL>
 <A HREF="rfc2548.html#MS-ARAP-Challenge">MS-ARAP-Challenge</A><BR>
 <A HREF="rfc2548.html#MS-ARAP-Password-Change-Reason">MS-ARAP-Password-Change-Reason</A><BR>
 <A HREF="rfc2548.html#MS-Secondary-DNS-Server">MS-Secondary-DNS-Server</A><BR>
 <A HREF="rfc2548.html#MS-Secondary-NBNS-Server">MS-Secondary-NBNS-Server</A><BR>
 <A HREF="rfc2869.html#Message-Authenticator">Message-Authenticator</A><BR>
+<A HREF="rfc2869.html#Message-Authenticator">Message-Authenticator</A><BR>
 </UL>
 
-<H3>N</H3>
-
+<H2>N</H2>
 <UL>
 <A HREF="rfc2865.html#NAS-IP-Address">NAS-IP-Address</A><BR>
 <A HREF="rfc3162.html#NAS-IPv6-Address">NAS-IPv6-Address</A><BR>
 <A HREF="rfc2865.html#NAS-Port-Type">NAS-Port-Type</A><BR>
 </UL>
 
-<H3>P</H3>
+<H2>O</H2>
 
+<H2>P</H2>
 <UL>
 <A HREF="rfc2869.html#Password-Retry">Password-Retry</A><BR>
 <A HREF="rfc2865.html#Port-Limit">Port-Limit</A><BR>
+<A HREF="rfc2869.html#Prompt">Prompt</A><BR>
 <A HREF="rfc2865.html#Proxy-State">Proxy-State</A><BR>
 </UL>
 
-<H3>R</H3>
+<H2>Q</H2>
 
+<H2>R</H2>
 <UL>
 <A HREF="rfc2865.html#Reply-Message">Reply-Message</A><BR>
 </UL>
 
-<H3>S</H3>
-
+<H2>S</H2>
 <UL>
-<A HREF="rfc4590.html#SIP-AOR">SIP-AOR</A><BR>
 <A HREF="rfc2865.html#Service-Type">Service-Type</A><BR>
 <A HREF="rfc2865.html#Session-Timeout">Session-Timeout</A><BR>
 <A HREF="rfc2865.html#State">State</A><BR>
 </UL>
 
-<H3>T</H3>
-
+<H2>T</H2>
 <UL>
+<A HREF="rfc2809.html#Telephone-number">Telephone-number</A><BR>
 <A HREF="rfc2865.html#Termination-Action">Termination-Action</A><BR>
 <A HREF="rfc2868.html#Tunnel-Assignment-ID">Tunnel-Assignment-ID</A><BR>
 <A HREF="rfc2868.html#Tunnel-Client-Auth-ID">Tunnel-Client-Auth-ID</A><BR>
 <A HREF="rfc2867.html#Tunnel-Link-Start">Tunnel-Link-Start</A><BR>
 <A HREF="rfc2867.html#Tunnel-Link-Stop">Tunnel-Link-Stop</A><BR>
 <A HREF="rfc2868.html#Tunnel-Medium-Type">Tunnel-Medium-Type</A><BR>
+<A HREF="rfc2868.html#Tunnel-Medium-Type">Tunnel-Medium-Type</A><BR>
 <A HREF="rfc2868.html#Tunnel-Password">Tunnel-Password</A><BR>
 <A HREF="rfc2868.html#Tunnel-Preference">Tunnel-Preference</A><BR>
 <A HREF="rfc2868.html#Tunnel-Private-Group-ID">Tunnel-Private-Group-ID</A><BR>
 <A HREF="rfc2868.html#Tunnel-Type">Tunnel-Type</A><BR>
 </UL>
 
-<H3>U</H3>
-
+<H2>U</H2>
 <UL>
 <A HREF="rfc2865.html#User-Name">User-Name</A><BR>
 <A HREF="rfc2865.html#User-Password">User-Password</A><BR>
 </UL>
 
-<H3>V</H3>
-
+<H2>V</H2>
 <UL>
 <A HREF="rfc2865.html#Vendor-Specific">Vendor-Specific</A><BR>
 </UL>
-</BODY>
+
+<H2>W</H2>
+<H2>X</H2>
+<H2>Y</H2>
+<H2>Z</H2>
+
+</body>
+</html>
index 61486ee..6ab0ab1 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
 foreach $file (@ARGV) {
     open FILE, "<$file" || die "Error opening $file: $!\n";
 
@@ -10,14 +10,7 @@ foreach $file (@ARGV) {
 
        chop;
        split;
-
-       next if ($_[1] =~ /,/);
-
-       next if (defined($file{$_[1]}));
-
        print $ref, "\t", $_[1], "\n";
-
-       $file{$_[1]} = $ref;
     }
 
     close FILE;
diff --git a/doc/rfc/per-rfc.pl b/doc/rfc/per-rfc.pl
deleted file mode 100755 (executable)
index 7705afd..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env perl
-
-#
-#   Read in the references, and put into an associative array
-#
-open FILE, "<refs" || die "Error opening refs: $!\n";
-while (<FILE>) {
-    chop;
-    split;
-    
-    $refs{$_[1]} = $_[0];
-    $defs{$_[0]}{$_[1]}++;
-}
-close FILE;
-
-#
-#  now loop over the input RFC's.
-#
-foreach $file (@ARGV) {
-    $def=$file;
-    $def =~ s/\.txt//;
-
-    $attribute = "zzzzz";
-
-    # get the current reference
-    $ref = $file;
-    $ref =~ s/\..*//g;
-    $rfc = $ref;
-    $ref = "attributes-$ref";
-
-    open OUTPUT, ">$ref.html" || die "Error creating $ref.html: $!\n";
-
-    #
-    #  Print out the HTML header
-    #
-    print OUTPUT <<EOF;
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<HTML>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Perl">
-   <title>$rfc Index of Attributes</title>
-</head>
-<body>
-<h1>$rfc Attribute List</h1>
-EOF
-
-  $letter = "@";
-
-  foreach $key (sort keys %{$defs{$def}}) {
-    if (substr($key,0,1) ne $letter) {
-      print OUTPUT "</UL>\n" if ($letter ne "@");
-      $letter = substr($key,0,1);
-      print OUTPUT "\n<H3>$letter</H3>\n\n";
-      print OUTPUT "<UL>\n";
-    }
-    
-    print OUTPUT "<A HREF=\"$refs{$key}.html#$key\">$key</A><BR />\n";
-
-  }
-
-  print OUTPUT "</UL>\n";
-  print OUTPUT "</BODY>\n";
-  close OUTPUT;
-}
index 73039c7..78d7be1 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
 
 #
 #   Read in the references, and put into an associative array
@@ -64,13 +64,13 @@ EOF
        #
        #  Attribute name header.
        #
-       if (/^\d+\./ && !/\d$/) {
+       if (/^\d+\./) {
            split;
 
            if ($refs{$_[1]} ne "") {
                $attribute = $_[1];
                
-               print OUTPUT "<A NAME=\"$attribute\"><H2>$_</H2></a>\n";
+               print OUTPUT "<A NAME=\"$attribute\"><H2>$_[0] $attribute</H2></a>\n";
                
            } else {
                print OUTPUT "<H2>$_</H2>\n";
@@ -122,7 +122,7 @@ EOF
 #
 #  And finally, create the index.
 #
-open OUTPUT, ">attributes.html" || die "Error creating attributes.html: $!\n";
+open OUTPUT, ">index.html" || die "Error creating index.html: $!\n";
 
 #
 #  Print out the HTML header
@@ -144,16 +144,12 @@ $letter = "@";
 
 foreach $key (sort keys %refs) {
     if (substr($key,0,1) ne $letter) {
-       print OUTPUT "</UL>\n" if ($letter ne "@");
        $letter = substr($key,0,1);
        print OUTPUT "\n<H3>$letter</H3>\n\n";
-        print OUTPUT "<UL>\n";
     }
     
     print OUTPUT "<A HREF=\"$refs{$key}.html#$key\">$key</A><BR>\n";
 }
 
-print OUTPUT "</UL>\n";
-
 print OUTPUT "</BODY>\n";
 close OUTPUT;
diff --git a/doc/rfc/rfc2607.txt b/doc/rfc/rfc2607.txt
deleted file mode 100644 (file)
index 2d34c5b..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                           B. Aboba
-Request for Comments: 2607                         Microsoft Corporation
-Category: Informational                                    J. Vollbrecht
-                                                    Merit Networks, Inc.
-                                                               June 1999
-
-
-          Proxy Chaining and Policy Implementation in Roaming
-
-Status of this Memo
-
-   This memo provides information for the Internet community.  It does
-   not specify an Internet standard of any kind.  Distribution of this
-   memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (1999).  All Rights Reserved.
-
-1.  Abstract
-
-   This document describes how proxy chaining and policy implementation
-   can be supported in roaming systems. The mechanisms described in this
-   document are in current use.
-
-   However, as noted in the security considerations section, the
-   techniques outlined in this document are vulnerable to attack from
-   external parties as well as susceptible to fraud perpetrated by the
-   roaming partners themselves. As a result, such methods are not
-   suitable for wide-scale deployment on the Internet.
-
-2.  Terminology
-
-   This document frequently uses the following terms:
-
-   Network Access Server
-      The Network Access Server (NAS) is the device that clients contact
-      in order to get access to the network.
-
-   RADIUS server
-      This is a server which provides for authentication/authorization
-      via the protocol described in [3], and for accounting as described
-      in [4].
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 1]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-   RADIUS proxy
-      In order to provide for the routing of RADIUS authentication and
-      accounting requests, a RADIUS proxy can be employed. To the NAS,
-      the RADIUS proxy appears to act as a RADIUS server, and to the
-      RADIUS server, the proxy appears to act as a RADIUS client.
-
-   Network Access Identifier
-      In order to provide for the routing of RADIUS authentication and
-      accounting requests, the userID field used in PPP (known as the
-      Network Access Identifier or NAI) and in the subsequent RADIUS
-      authentication and accounting requests, can contain structure.
-      This structure provides a means by which the RADIUS proxy will
-      locate the RADIUS server that is to receive the request. The NAI
-      is defined in [6].
-
-   Roaming relationships
-      Roaming relationships include relationships between companies and
-      ISPs, relationships among peer ISPs within a roaming association,
-      and relationships between an ISP and a roaming consortia.
-      Together, the set of relationships forming a path between a local
-      ISP's authentication proxy and the home authentication server is
-      known as the roaming relationship path.
-
-3.  Requirements language
-
-   In this document, the key words "MAY", "MUST, "MUST NOT", "optional",
-   "recommended", "SHOULD", and "SHOULD NOT", are to be interpreted as
-   described in [5].
-
-4.  Introduction
-
-   Today, as described in [1], proxy chaining is widely deployed for the
-   purposes of providing roaming services. In such systems,
-   authentication/authorization and accounting packets are routed
-   between a NAS device and a home server through a series of proxies.
-   Consultation of the home server is required for password-based
-   authentication, since the home server maintains the password database
-   and thus it is necessary for the NAS to communicate with the home
-   authentication server in order to verify the user's identity.
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 2]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-4.1.  Advantages of proxy chaining
-
-   Proxies serve a number of functions in roaming, including:
-
-   Scalability improvement
-   Authentication forwarding
-   Capabilities adjustment
-   Policy implementation
-   Accounting reliability improvement
-   Atomic operation
-
-   Scalability improvement
-      In large scale roaming systems, it is necessary to provide for
-      scalable management of keys used for integrity protection and
-      authentication.
-
-      Proxy chaining enables implementation of hierarchical
-      forwarding within roaming systems, which improves scalability
-      in roaming consortia based on authentication protocols without
-      automated key management.  Since RADIUS as described in [3]
-      requires a shared secret for each client-server pair, a
-      consortium of 100 roaming partners would require 4950 shared
-      secrets if each partner were to contact each other directly,
-      one for each partner pair.  However, were the partners to
-      route authentication requests through a central proxy, only
-      100 shared secrets would be needed, one for each partner. The
-      reduction in the number of partner pairs also brings with it
-      other benefits, such as a reduction in the number of bilateral
-      agreements and accounting and auditing overhead.  Thus,
-      hierarchical routing might be desirable even if an
-      authentiation protocol supporting automated key exchange were
-      available.
-
-   Capabilities adjustment
-      As part of the authentication exchange with the home server,
-      the NAS receives authorization parameters describing the
-      service to be provided to the roaming user.  Since RADIUS,
-      described in [3], does not support capabilities negotiation,
-      it is possible that the authorization parameters sent by the
-      home server will not match those required by the NAS. For
-      example, a static IP address could be specified that would not
-      be routable by the NAS. As a result, capbilities adjustment is
-      performed by proxies in order to enable communication between
-      NASes and home servers with very different feature sets.
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 3]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-      As part of capabilities adjustment, proxies can edit
-      attributes within the Access-Accept in order to ensure
-      compatibility with the NAS.  Such editing may include
-      addition, deletion, or modification of attributes. In
-      addition, in some cases it may be desirable for a proxy to
-      edit attributes within an Access-Request in order to clean up
-      or even hide information destined for the home server.  Note
-      that if the proxy edits attributes within the Access-Accept,
-      then it is possible that the service provided to the user may
-      not be the same as that requested by the home server. This
-      creates the possibility of disputes arising from inappropriate
-      capabilities adjustment.
-
-      Note that were roaming to be implemented based on an
-      authentication/authorization protocol with built-in capability
-      negotiation, proxy-based capabilities adjustment would
-      probably not be necessary.
-
-   Authentication forwarding
-      Since roaming associations frequently implement hierarchical
-      forwarding in order to improve scalability, in order for a NAS
-      and home server to communicate, authentication and accounting
-      packets are forwarded by one or more proxies. The path
-      travelled by these packets, known as the roaming relationship
-      path, is determined from the Network Access Identifier (NAI),
-      described in [6]. Since most NAS devices do not implement
-      forwarding logic, a proxy is needed to enable forwarding of
-      authentication and accounting packets. For reasons that are
-      described in the security section, in proxy systems it is
-      desirable for accounting and authentication packets to follow
-      the same path.
-
-      Note: The way a proxy learns the mapping between NAI and the
-      home server is  beyond  the  scope  of this document. This
-      mapping can be accomplished by static configuration in the
-      proxy, or by some currently undefined protocol that provides
-      for dynamic mapping. For the purposes of this document, it is
-      assumed that such a mapping capability exists in the proxy.
-
-   Policy implementation
-      In roaming systems it is often desirable to be able to
-      implement policy. For example, a given partner may only be
-      entitled to use of a given NAS during certain times of the
-      day. In order to implement such policies, proxies may be
-      implemented at the interface between administrative domains
-      and programmed to modify authentication/authorization packets
-      forwarded between the NAS and the home server. As a result,
-      from a security point of view, a proxy implementing policy
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 4]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-      operates as a "man in the middle."
-
-   Accounting reliability improvement
-      In roaming systems based on proxy chaining, it is necessary
-      for accounting information to be forwarded between the NAS and
-      the home server. Thus roaming is inherently an interdomain
-      application.
-
-      This represents a problem since the RADIUS accounting
-      protocol, described in [4] is not designed for use on an
-      Internet scale.  Given that in roaming accounting packets
-      travel between administrative domains, packets will often pass
-      through network access points (NAPs) where packet loss may be
-      substantial. This can result in unacceptable rates of
-      accounting data loss.
-
-      For example, in a proxy chaining system involving four
-      systems, a one percent failure rate on each hop can result in
-      loss of 3.9 percent of all accounting transactions. Placement
-      of an accounting proxy near the NAS may improve reliability by
-      enabling enabling persistent storage of accounting records and
-      long duration retry.
-
-   Atomic operation
-      In order to ensure consistency among all parties required to
-      process accounting data, it can be desirable to assure that
-      transmission of accounting data is handled as an atomic
-      operation. This implies that all parties on the roaming
-      relationship path will receive and acknowledge the receipt of
-      the accounting data for the operation to complete. Proxies can
-      be used to ensure atomic delivery of accounting data by
-      arranging for delivery of the accounting data in a serial
-      fashion, as discussed in section 5.2.
-
-5.  Proxy chaining
-
-   An example of a proxy chaining system is shown below.
-
-         (request)          (request)          (request)
-     NAS ----------> Proxy1 ----------> Proxy2 ----------> Home
-         (reply)            (reply)            (reply)     Server
-         <---------         <---------         <---------
-
-   In the above diagram, the NAS generates a request and sends it to
-   Proxy1.  Proxy1 forwards the request to Proxy2 and Proxy2 forwards
-   the request to the Home Server.  The Home Server generates a reply
-   and sends it to Proxy2.  Proxy2 receives the reply, matches it with
-   the request it had sent, and forwards a reply to Proxy1. Proxy1
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 5]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-   matches the reply with the request it sent earlier and forwards a
-   reply to the NAS.  This model applies to all requests, including
-   Access Requests and Accounting Requests.
-
-   Except for the two cases described below, a proxy server such as
-   Proxy2 in the diagram above SHOULD NOT send a Reply packet to Proxy1
-   without first having received a Reply packet initiated by the Home
-   Server.  The two exceptions are when the proxy is enforcing policy as
-   described in section 5.1 and when the proxy is acting as an
-   accounting store (as in store and forward), as described in section
-   5.2.
-
-   The RADIUS protocol described in [3] does not provide for end-to-end
-   security services, including integrity or replay protection,
-   authentication or confidentiality. As noted in the security
-   considerations section, this omission results in several security
-   problems within proxy chaining systems.
-
-5.1.  Policy implementation
-
-   Proxies are frequently used to implement policy in roaming
-   situations.  Proxies implementing policy MAY reply directly to
-   Access-Requests without forwarding the request. When replying
-   directly to an Access-Request, the proxy MUST reply either with an
-   Access-Reject or an Access-Challenge packet. A proxy MUST NOT reply
-   directly with an Access-Accept.  An example of this would be when the
-   proxy refuses all connections from a particular realm during prime
-   time. In this case the home server will never receive th Access-
-   Request.  This situation is shown below:
-
-         (request)          (request)
-     NAS ----------> Proxy1 ----------> Proxy2             Home
-         (reply)            (reply)                        Server
-         <---------         <---------
-
-   A proxy MAY also decide to Reject a Request that has been accepted by
-   the home server.  This could be based on the set of attributes
-   returned by the home server.  In this case the Proxy SHOULD send an
-   Access-Reject to the NAS and an Accounting-Request with Acct-Status-
-   Type=Proxy-Stop (6) to the home server.  This lets the home server
-   know that the session it approved has been denied downstream by the
-   proxy.  However, a proxy MUST NOT send an Access-Accept after
-   receiving an Access-Reject from a proxy or from the home server.
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 6]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-         (Access-Req)       (Access-Req)       (Access-Req)
-     NAS ----------> Proxy1 ----------> Proxy2 ---------->     Home
-         (Access-Reject)    (Access-Accept)    (Access-Accept) Server
-         <---------         <---------         <---------
-                            (AcctPxStop)       (AcctPxStop)
-                            ---------->        ---------->
-
-5.2.  Accounting behavior
-
-   As described above, a proxy MUST NOT reply directly with an Access-
-   Accept, and MUST NOT reply with an Access-Accept when it has received
-   an Access-Reject from another proxy or Home Server. As a result, in
-   all cases where an accounting record is to be generated (accepted
-   sessions), no direct replies have occurred, and the Access-Request
-   and Access-Accept have passed through the same set of systems.
-
-   In order to allow proxies to match incoming Accounting-Requests with
-   previously handled Access-Requests and Access-Accepts, a proxy SHOULD
-   route the Accounting-Request along the same realm path travelled in
-   authentication/authorization.  Note that this does not imply that
-   accounting packets will necessarily travel the identical path,
-   machine by machine, as did authentication/authorization packets.
-   This is because it is conceivable that a proxy may have gone down,
-   and as a result the Accounting-request may need to be forwarded to an
-   alternate server. It is also conceivable that
-   authentication/authorization and accounting may be handled by
-   different servers within a realm.
-
-   The Class attribute can be used to match Accounting Requests with
-   prior Access Requests.  It can also be used to match session log
-   records between the home Server, proxies, and NAS. This matching can
-   be accomplished either in real-time (in the case that authentication
-   and accounting packets follow the same path, machine by machine), or
-   after the fact.
-
-   Home servers SHOULD insert a unique session identifier in the Class
-   attribute in an Access-Accept and Access-Challenge.  Proxies and
-   NASes MUST forward the unmodified Class attribute.  The NAS MUST
-   include the Class attribute in subsequent requests, in particular for
-   Accounting-Requests. The sequence of events is shown below:
-
-
-
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 7]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-                      Authentication/Authorization
-
-      -------->         -------->          --------->
- NAS            Proxy1              Proxy2             Home (add class)
-     <-class--          <-class-           <-class--
-
-
-                               Accounting
-
-     (Accounting-req)   (Accounting-req)  (Accounting-req)
-         w/class           w/class            w/class
-  NAS ----------> Proxy1 ----------> Proxy2 ---------->       Home
-      (Accounting-reply) (Accounting-reply)(Accounting-reply) Server
-      <---------         <---------         <---------
-
-   Since there is no need to implement policy in accounting, a proxy
-   MUST forward all Accounting Requests to the next server on the path.
-   The proxy MUST guarantee that the Accounting Request is received by
-   the End Server and all intermediate servers.  The proxy may do this
-   either by: 1) forwarding the Accounting Request and not sending a
-   Reply until it receives the matching Reply from the upstream server,
-   or 2) acting as a store point which takes responsibility for
-   reforwarding the Accounting Request until it receives a Reply.
-
-   Note that when the proxy does not send a reply until it receives a
-   matching reply, this ensures that Accounting Start and Stop messages
-   are received and can be logged by all servers along the roaming
-   relationship path. If one of the servers is not available, then the
-   operation will fail. As a result the entire accounting transaction
-   will either succeed or fail as a unit, and thus can be said to be
-   atomic.
-
-   Where store and forward is implemented, it is possible that one or
-   more servers along the roaming relationship path will not receive the
-   accounting data while others will. The accounting operation will not
-   succeed or fail as a unit, and is therefore not atomic.  As a result,
-   it may not be possible for the roaming partners to reconcile their
-   audit logs, opening new opportunities for fraud.  Where store and
-   forward is implemented, forwarding of Accounting Requests SHOULD be
-   done as they are received so the downstream servers will receive them
-   in a timely way.
-
-   Note that there are cases where a proxy will need to forward an
-   Accounting packet to more than one system. For example, in order to
-   allow for proper accounting in the case of a NAS that is shutting
-   down, the proxy can send an Accounting-Request with Acct-Status-
-   Type=Accounting-Off (8) to all realms that it forwards to.  In turn,
-   these proxies will also flood the packet to their connected realms.
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 8]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-6.  References
-
-   [1]  Aboba, B., Lu J., Alsop J., Ding J. and W. Wang, "Review of
-        Roaming Implementations", RFC 2194, September 1997.
-
-   [2]  Aboba, B. and G. Zorn, "Criteria for Evaluating Roaming
-        Protocols", RFC 2477, January 1999.
-
-   [3]  Rigney, C., Rubens, A., Simpson, W. and S. Willens, "Remote
-        Authentication Dial In User Service (RADIUS)", RFC 2138, April
-        1997.
-
-   [4]  Rigney, C., "RADIUS  Accounting", RFC 2139, April 1997.
-
-   [5]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
-        Levels", BCP 14, RFC 2119, March 1997.
-
-   [6]  Aboba, B. and M. Beadles, "The Network Access Identifier", RFC
-        2486, January 1999.
-
-7.  Security Considerations
-
-   The RADIUS protocol described in [3] was designed for intra-domain
-   use, where the NAS, proxy, and home server exist within a single
-   administrative domain, and proxies may be considered a trusted
-   component. However, in roaming the NAS, proxies, and home server will
-   typically be managed by different administrative entities. As a
-   result, roaming is inherently an inter-domain application, and
-   proxies cannot necessarily be trusted.  This results in a number of
-   security threats, including:
-
-      Message editing
-      Attribute editing
-      Theft of passwords
-      Theft and modification of accounting data
-      Replay attacks
-      Connection hijacking
-      Fraudulent accounting
-
-7.1.  Message editing
-
-   Through the use of shared secrets it is possible for proxies
-   operating in different domains to establish a trust relationship.
-   However, if only hop-by-hop security is available then untrusted
-   proxies are capable of perpetrating a number of man-in-the-middle
-   attacks.  These include modification of messages.
-
-
-
-
-
-Aboba & Vollbrecht           Informational                      [Page 9]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-   For example, an Access-Accept could be substituted for an Access-
-   Reject, and without end-to-end integrity protection, there is no way
-   for the NAS to detect this. On the home server, this will result in
-   an accounting log entry for a session that was not authorized.
-   However, if the proxy does not forward accounting packets or session
-   records to the home server, then the home server will not be able to
-   detect the discrepancy until a bill is received and audited.
-
-   Note that a proxy can also send an Access-Reject to the NAS after
-   receiving an Access-Accept from the home server. This will result in
-   an authentication log entry without a corresponding accounting log
-   entry.  Without the proxy sending an Accounting-Request with Acct-
-   Status-Type=Proxy-Stop (6) to the home server, then there will be no
-   way for the home server to determine whether the discrepancy is due
-   to policy implementation or loss of accounting packets.  Thus the use
-   of Acct-Status-Type=Proxy-Stop can be of value in debugging roaming
-   systems.
-
-   It should be noted that even if end-to-end security were to be
-   available, a number of sticky questions would remain. While the end-
-   points would be able to detect that the message from the home server
-   had been modified by an intermediary, the question arises as to what
-   action should be taken. While the modified packet could be silently
-   discarded, this could affect the ability of the home server to .
-   accept an Acct-Status-Type=Proxy-Stop message from an intermediate
-   proxy. Since this message would not be signed by the NAS, it may need
-   to be dropped by the home server.
-
-   This is similar to the problem that IPSEC-capable systems face in
-   making use of ICMP messages from systems with whom they do not have a
-   security association. The problem is more difficult here, since in
-   RADIUS retransmission is driven by the NAS.  Therefore the home
-   server does not receive acknowledgement for Access-Accepts and thus
-   would have no way of knowing that its response has not been honored.
-
-7.2.  Attribute editing
-
-   RADIUS as defined in [3] does not provide for end-to-end security or
-   capabilities negotiation. As a result there is no way for a home
-   server to securely negotiate a mutually acceptable configuration with
-   the NAS or proxies. As a result, a number of attribute editing
-   attacks are possible.
-
-   For example, EAP attributes might be removed or modified so as to
-   cause a client to authenticate with EAP MD5 or PAP, instead of a
-   stronger authentication method. Alternatively, tunnel attributes
-   might be removed or modified so as to remove encryption, redirect the
-   tunnel to a rogue tunnel server, or otherwise lessen the security
-
-
-
-Aboba & Vollbrecht           Informational                     [Page 10]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-   provided to the client.  The mismatch between requested and received
-   services may only be detectable after the fact by comparing the
-   Access-Accept attributes against the attributes included in the
-   Accounting-Request. However, without end-to-end security services, it
-   is possible for a rogue proxy to cover its tracks.
-
-   Due to the complexity of proxy configuration, such attacks need not
-   involve malice, but can occur due to mis-configuration or
-   implementation deficiencies.  Today several proxy implementations
-   remove attributes that they do not understand, or can be set up to
-   replace attribute sets sent in the Access-Accept with sets of
-   attributes appropriate for a particular NAS.
-
-   In practice, it is not possible to define a set of guidelines for
-   attribute editing, since the requirements are very often
-   implementation-specific. At the same time, protection against
-   inappropriate attribute editing is necessary to guard against attacks
-   and provide assurance that users are provisioned as directed by the
-   home server.
-
-   Since it is not possible to determine beforehand whether a given
-   attribute is editable or not, a mechanism needs to be provided to
-   allow senders to indicate which attributes are editable and which are
-   not, and for the receivers to detect modifications of "non-editable"
-   attributes.  Through implementation of end-to-end security it may be
-   possible to detect unauthorized addition, deletion, or modification
-   of integrity-protected attributes. However, it would still possible
-   for a rogue proxy to add, delete or modify attributes that are not
-   integrity-protected. If such attributes influence subsequent charges,
-   then the possibility of fraud would remain.
-
-7.3.  Theft of passwords
-
-   RADIUS as defined in [3] does not provide for end-to-end
-   confidentiality. As a result, where clients authenticate using PAP,
-   each proxy along the path between the local NAS and the home server
-   will have access to the cleartext password. In many circumstances,
-   this represents an unacceptable security risk.
-
-7.4.  Theft and modification of accounting data
-
-   Typically in roaming systems, accounting packets are provided to all
-   the participants along the roaming relationship path, in order to
-   allow them to audit subsequent invoices. RADIUS as described in [3]
-   does not provide for end-to-end security services, including
-   integrity protection or confidentiality. Without end-to-end integrity
-   protection, it is possible for proxies to modify accounting packets
-   or session records.  Without end-to-end confidentiality, accounting
-
-
-
-Aboba & Vollbrecht           Informational                     [Page 11]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-   data will be accessible to proxies.  However, if the objective is
-   merely to prevent snooping of accounting data on the wire, then IPSEC
-   ESP can be used.
-
-7.5.  Replay attacks
-
-   In this attack, a man in the middle or rogue proxy collects CHAP-
-   Challenge and CHAP-Response attributes, and later replays them. If
-   this attack is performed in collaboration with an unscrupulous ISP,
-   it can be used to subsequently submit fraudulent accounting records
-   for payment.  The system performing the replay need not necessarily
-   be the one that initially captured the CHAP Challenge/Response pair.
-
-   While RADIUS as described in [3] is vulnerable to replay attacks,
-   without roaming the threat is restricted to proxies operating in the
-   home server's domain. With roaming, such an attack can be mounted by
-   any proxy capable of reaching the home server.
-
-7.6.  Connection hijacking
-
-   In this form of attack, the attacker attempts to inject packets into
-   the conversation between the NAS and the home server. RADIUS as
-   described in [3] is vulnerable to such attacks since only Access-
-   Reply and Access-Challenge packets are authenticated.
-
-7.7.  Fraudulent accounting
-
-   In this form of attack, a local proxy transmits fraudulent accounting
-   packets or session records in an effort to collect fees to which they
-   are not entitled. This includes submission of packets or session
-   records for non-existent sessions. Since in RADIUS as described in
-   [3], there is no end-to-end security, a rogue proxy may insert or
-   edit packets without fear of detection.
-
-   In order to detect submissions of accounting packets or session
-   records for non-existent sessions, parties receiving accounting
-   packets or session records would be prudent to reconcile them with
-   the authentication logs. Such reconciliation is only typically
-   possible when the party acts as an authentication proxy for all
-   sessions for which an accounting record will subsequently be
-   submitted.
-
-   In order to make reconciliation easier, home servers involved in
-   roaming include a Class attribute in the Access-Accept.  The Class
-   attribute uniquely identifies a session, so as to allow an
-   authentication log entry to be matched with a corresponding
-   accounting packet or session record.
-
-
-
-
-Aboba & Vollbrecht           Informational                     [Page 12]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-   If reconciliation is put in place and all accounting log entries
-   without a corresponding authentication are rejected, then the
-   attacker will need to have obtained a valid user password prior to
-   submitting accounting packets or session records on non-existent
-   sessions. While use of end-to-end security can defeat unauthorized
-   injection or editing of accounting or authentication packets by
-   intermediate proxies, other attacks remain feasible. For example,
-   unless replay protection is put in place, it is still feasible for an
-   intermediate proxy to resubmit authentication or accounting packets
-   or session records. In addition, end-to-end security does not provide
-   protection against attacks by the local proxy, since this is
-   typically where end-to-end security will be initiated. To detect such
-   attacks, other measures need to be put in place, such as systems for
-   detecting unusual activity of ISP or user accounts, or for
-   determining whether a user or ISP account is within their credit
-   limit.
-
-   Note that implementation of the store and forward approach to proxy
-   accounting makes it possible for some systems in the roaming
-   relationship path to receive accounting records that other systems do
-   not get. This can result in audit discrepancies. About the best that
-   is achievable in such cases is to verify that the accounting data is
-   missing by checking against the authentication logs.
-
-8.  Acknowledgments
-
-   Thanks to Pat Calhoun of Sun Microsystems, Mark Beadles of
-   CompuServe, Aydin Edguer of Morningstar, Bill Bulley of Merit, and
-   Steven P. Crain of Shore.Net for useful discussions of this problem
-   space.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                     [Page 13]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-9.  Authors' Addresses
-
-   Bernard Aboba
-   Microsoft Corporation
-   One Microsoft Way
-   Redmond, WA 98052
-
-   Phone: 425-936-6605
-   EMail: bernarda@microsoft.com
-
-
-   John R. Vollbrecht
-   Merit Network, Inc.
-   4251 Plymouth Rd.
-   Ann Arbor, MI 48105-2785
-
-   Phone: 313-763-1206
-   EMail: jrv@merit.edu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                     [Page 14]
-\f
-RFC 2607          Proxy Chaining and Policy in Roaming         June 1999
-
-
-10.  Full Copyright Statement
-
-   Copyright (C) The Internet Society (1999).  All Rights Reserved.
-
-   This document and translations of it may be copied and furnished to
-   others, and derivative works that comment on or otherwise explain it
-   or assist in its implementation may be prepared, copied, published
-   and distributed, in whole or in part, without restriction of any
-   kind, provided that the above copyright notice and this paragraph are
-   included on all such copies and derivative works.  However, this
-   document itself may not be modified in any way, such as by removing
-   the copyright notice or references to the Internet Society or other
-   Internet organizations, except as needed for the purpose of
-   developing Internet standards in which case the procedures for
-   copyrights defined in the Internet Standards process must be
-   followed, or as required to translate it into languages other than
-   English.
-
-   The limited permissions granted above are perpetual and will not be
-   revoked by the Internet Society or its successors or assigns.
-
-   This document and the information contained herein is provided on an
-   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
-   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
-   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
-   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is currently provided by the
-   Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba & Vollbrecht           Informational                     [Page 15]
-\f
diff --git a/doc/rfc/rfc3748.txt b/doc/rfc/rfc3748.txt
deleted file mode 100644 (file)
index 75600c1..0000000
+++ /dev/null
@@ -1,3755 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                           B. Aboba
-Request for Comments: 3748                                     Microsoft
-Obsoletes: 2284                                                 L. Blunk
-Category: Standards Track                             Merit Network, Inc
-                                                           J. Vollbrecht
-                                               Vollbrecht Consulting LLC
-                                                              J. Carlson
-                                                                     Sun
-                                                       H. Levkowetz, Ed.
-                                                             ipUnplugged
-                                                               June 2004
-
-
-                Extensible Authentication Protocol (EAP)
-
-Status of this Memo
-
-   This document specifies an Internet standards track protocol for the
-   Internet community, and requests discussion and suggestions for
-   improvements.  Please refer to the current edition of the "Internet
-   Official Protocol Standards" (STD 1) for the standardization state
-   and status of this protocol.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (2004).
-
-Abstract
-
-   This document defines the Extensible Authentication Protocol (EAP),
-   an authentication framework which supports multiple authentication
-   methods.  EAP typically runs directly over data link layers such as
-   Point-to-Point Protocol (PPP) or IEEE 802, without requiring IP.  EAP
-   provides its own support for duplicate elimination and
-   retransmission, but is reliant on lower layer ordering guarantees.
-   Fragmentation is not supported within EAP itself; however, individual
-   EAP methods may support this.
-
-   This document obsoletes RFC 2284.  A summary of the changes between
-   this document and RFC 2284 is available in Appendix A.
-
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 1]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-Table of Contents
-
-   1.   Introduction. . . . . . . . . . . . . . . . . . . . . . . . .  3
-        1.1.  Specification of Requirements . . . . . . . . . . . . .  4
-        1.2.  Terminology . . . . . . . . . . . . . . . . . . . . . .  4
-        1.3.  Applicability . . . . . . . . . . . . . . . . . . . . .  6
-   2.   Extensible Authentication Protocol (EAP). . . . . . . . . . .  7
-        2.1.  Support for Sequences . . . . . . . . . . . . . . . . .  9
-        2.2.  EAP Multiplexing Model. . . . . . . . . . . . . . . . . 10
-        2.3.  Pass-Through Behavior . . . . . . . . . . . . . . . . . 12
-        2.4.  Peer-to-Peer Operation. . . . . . . . . . . . . . . . . 14
-   3.   Lower Layer Behavior. . . . . . . . . . . . . . . . . . . . . 15
-        3.1.  Lower Layer Requirements. . . . . . . . . . . . . . . . 15
-        3.2.  EAP Usage Within PPP. . . . . . . . . . . . . . . . . . 18
-              3.2.1. PPP Configuration Option Format. . . . . . . . . 18
-        3.3.  EAP Usage Within IEEE 802 . . . . . . . . . . . . . . . 19
-        3.4.  Lower Layer Indications . . . . . . . . . . . . . . . . 19
-   4.   EAP Packet Format . . . . . . . . . . . . . . . . . . . . . . 20
-        4.1.  Request and Response. . . . . . . . . . . . . . . . . . 21
-        4.2.  Success and Failure . . . . . . . . . . . . . . . . . . 23
-        4.3.  Retransmission Behavior . . . . . . . . . . . . . . . . 26
-   5.   Initial EAP Request/Response Types. . . . . . . . . . . . . . 27
-        5.1.  Identity. . . . . . . . . . . . . . . . . . . . . . . . 28
-        5.2.  Notification. . . . . . . . . . . . . . . . . . . . . . 29
-        5.3.  Nak . . . . . . . . . . . . . . . . . . . . . . . . . . 31
-              5.3.1. Legacy Nak . . . . . . . . . . . . . . . . . . . 31
-              5.3.2. Expanded Nak . . . . . . . . . . . . . . . . . . 32
-        5.4.  MD5-Challenge . . . . . . . . . . . . . . . . . . . . . 35
-        5.5.  One-Time Password (OTP) . . . . . . . . . . . . . . . . 36
-        5.6.  Generic Token Card (GTC). . . . . . . . . . . . . . . . 37
-        5.7.  Expanded Types. . . . . . . . . . . . . . . . . . . . . 38
-        5.8.  Experimental. . . . . . . . . . . . . . . . . . . . . . 40
-   6.   IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40
-        6.1.  Packet Codes. . . . . . . . . . . . . . . . . . . . . . 41
-        6.2.  Method Types. . . . . . . . . . . . . . . . . . . . . . 41
-   7.   Security Considerations . . . . . . . . . . . . . . . . . . . 42
-        7.1.  Threat Model. . . . . . . . . . . . . . . . . . . . . . 42
-        7.2.  Security Claims . . . . . . . . . . . . . . . . . . . . 43
-              7.2.1. Security Claims Terminology for EAP Methods. . . 44
-        7.3.  Identity Protection . . . . . . . . . . . . . . . . . . 46
-        7.4.  Man-in-the-Middle Attacks . . . . . . . . . . . . . . . 47
-        7.5.  Packet Modification Attacks . . . . . . . . . . . . . . 48
-        7.6.  Dictionary Attacks. . . . . . . . . . . . . . . . . . . 49
-        7.7.  Connection to an Untrusted Network. . . . . . . . . . . 49
-        7.8.  Negotiation Attacks . . . . . . . . . . . . . . . . . . 50
-        7.9.  Implementation Idiosyncrasies . . . . . . . . . . . . . 50
-        7.10. Key Derivation. . . . . . . . . . . . . . . . . . . . . 51
-        7.11. Weak Ciphersuites . . . . . . . . . . . . . . . . . . . 53
-
-
-
-Aboba, et al.               Standards Track                     [Page 2]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-        7.12. Link Layer. . . . . . . . . . . . . . . . . . . . . . . 53
-        7.13. Separation of Authenticator and Backend Authentication
-              Server. . . . . . . . . . . . . . . . . . . . . . . . . 54
-        7.14. Cleartext Passwords . . . . . . . . . . . . . . . . . . 55
-        7.15. Channel Binding . . . . . . . . . . . . . . . . . . . . 55
-        7.16. Protected Result Indications. . . . . . . . . . . . . . 56
-   8.   Acknowledgements. . . . . . . . . . . . . . . . . . . . . . . 58
-   9.   References. . . . . . . . . . . . . . . . . . . . . . . . . . 59
-        9.1.  Normative References. . . . . . . . . . . . . . . . . . 59
-        9.2.  Informative References. . . . . . . . . . . . . . . . . 60
-   Appendix A. Changes from RFC 2284. . . . . . . . . . . . . . . . . 64
-   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 66
-   Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 67
-
-1.  Introduction
-
-   This document defines the Extensible Authentication Protocol (EAP),
-   an authentication framework which supports multiple authentication
-   methods.  EAP typically runs directly over data link layers such as
-   Point-to-Point Protocol (PPP) or IEEE 802, without requiring IP.  EAP
-   provides its own support for duplicate elimination and
-   retransmission, but is reliant on lower layer ordering guarantees.
-   Fragmentation is not supported within EAP itself; however, individual
-   EAP methods may support this.
-
-   EAP may be used on dedicated links, as well as switched circuits, and
-   wired as well as wireless links.  To date, EAP has been implemented
-   with hosts and routers that connect via switched circuits or dial-up
-   lines using PPP [RFC1661].  It has also been implemented with
-   switches and access points using IEEE 802 [IEEE-802].  EAP
-   encapsulation on IEEE 802 wired media is described in [IEEE-802.1X],
-   and encapsulation on IEEE wireless LANs in [IEEE-802.11i].
-
-   One of the advantages of the EAP architecture is its flexibility.
-   EAP is used to select a specific authentication mechanism, typically
-   after the authenticator requests more information in order to
-   determine the specific authentication method to be used.  Rather than
-   requiring the authenticator to be updated to support each new
-   authentication method, EAP permits the use of a backend
-   authentication server, which may implement some or all authentication
-   methods, with the authenticator acting as a pass-through for some or
-   all methods and peers.
-
-   Within this document, authenticator requirements apply regardless of
-   whether the authenticator is operating as a pass-through or not.
-   Where the requirement is meant to apply to either the authenticator
-   or backend authentication server, depending on where the EAP
-   authentication is terminated, the term "EAP server" will be used.
-
-
-
-Aboba, et al.               Standards Track                     [Page 3]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-1.1.  Specification of Requirements
-
-   In this document, several words are used to signify the requirements
-   of the specification.  The key words "MUST", "MUST NOT", "REQUIRED",
-   "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
-   and "OPTIONAL" in this document are to be interpreted as described in
-   [RFC2119].
-
-1.2.  Terminology
-
-   This document frequently uses the following terms:
-
-   authenticator
-      The end of the link initiating EAP authentication.  The term
-      authenticator is used in [IEEE-802.1X], and has the same meaning
-      in this document.
-
-   peer
-      The end of the link that responds to the authenticator.  In
-      [IEEE-802.1X], this end is known as the Supplicant.
-
-   Supplicant
-      The end of the link that responds to the authenticator in [IEEE-
-      802.1X].  In this document, this end of the link is called the
-      peer.
-
-   backend authentication server
-      A backend authentication server is an entity that provides an
-      authentication service to an authenticator.  When used, this
-      server typically executes EAP methods for the authenticator.  This
-      terminology is also used in [IEEE-802.1X].
-
-   AAA
-      Authentication, Authorization, and Accounting.  AAA protocols with
-      EAP support include RADIUS [RFC3579] and Diameter [DIAM-EAP].  In
-      this document, the terms "AAA server" and "backend authentication
-      server" are used interchangeably.
-
-   Displayable Message
-      This is interpreted to be a human readable string of characters.
-      The message encoding MUST follow the UTF-8 transformation format
-      [RFC2279].
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 4]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   EAP server
-      The entity that terminates the EAP authentication method with the
-      peer.  In the case where no backend authentication server is used,
-      the EAP server is part of the authenticator.  In the case where
-      the authenticator operates in pass-through mode, the EAP server is
-      located on the backend authentication server.
-
-   Silently Discard
-      This means the implementation discards the packet without further
-      processing.  The implementation SHOULD provide the capability of
-      logging the event, including the contents of the silently
-      discarded packet, and SHOULD record the event in a statistics
-      counter.
-
-   Successful Authentication
-      In the context of this document, "successful authentication" is an
-      exchange of EAP messages, as a result of which the authenticator
-      decides to allow access by the peer, and the peer decides to use
-      this access.  The authenticator's decision typically involves both
-      authentication and authorization aspects; the peer may
-      successfully authenticate to the authenticator, but access may be
-      denied by the authenticator due to policy reasons.
-
-   Message Integrity Check (MIC)
-      A keyed hash function used for authentication and integrity
-      protection of data.  This is usually called a Message
-      Authentication Code (MAC), but IEEE 802 specifications (and this
-      document) use the acronym MIC to avoid confusion with Medium
-      Access Control.
-
-   Cryptographic Separation
-      Two keys (x and y) are "cryptographically separate" if an
-      adversary that knows all messages exchanged in the protocol cannot
-      compute x from y or y from x without "breaking" some cryptographic
-      assumption.  In particular, this definition allows that the
-      adversary has the knowledge of all nonces sent in cleartext, as
-      well as all predictable counter values used in the protocol.
-      Breaking a cryptographic assumption would typically require
-      inverting a one-way function or predicting the outcome of a
-      cryptographic pseudo-random number generator without knowledge of
-      the secret state.  In other words, if the keys are
-      cryptographically separate, there is no shortcut to compute x from
-      y or y from x, but the work an adversary must do to perform this
-      computation is equivalent to performing an exhaustive search for
-      the secret state value.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 5]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Master Session Key (MSK)
-      Keying material that is derived between the EAP peer and server
-      and exported by the EAP method.  The MSK is at least 64 octets in
-      length.  In existing implementations, a AAA server acting as an
-      EAP server transports the MSK to the authenticator.
-
-   Extended Master Session Key (EMSK)
-      Additional keying material derived between the EAP client and
-      server that is exported by the EAP method.  The EMSK is at least
-      64 octets in length.  The EMSK is not shared with the
-      authenticator or any other third party.  The EMSK is reserved for
-      future uses that are not defined yet.
-
-   Result indications
-      A method provides result indications if after the method's last
-      message is sent and received:
-
-      1) The peer is aware of whether it has authenticated the server,
-         as well as whether the server has authenticated it.
-
-      2) The server is aware of whether it has authenticated the peer,
-         as well as whether the peer has authenticated it.
-
-   In the case where successful authentication is sufficient to
-   authorize access, then the peer and authenticator will also know if
-   the other party is willing to provide or accept access.  This may not
-   always be the case.  An authenticated peer may be denied access due
-   to lack of authorization (e.g., session limit) or other reasons.
-   Since the EAP exchange is run between the peer and the server, other
-   nodes (such as AAA proxies) may also affect the authorization
-   decision.  This is discussed in more detail in Section 7.16.
-
-1.3.  Applicability
-
-   EAP was designed for use in network access authentication, where IP
-   layer connectivity may not be available.  Use of EAP for other
-   purposes, such as bulk data transport, is NOT RECOMMENDED.
-
-   Since EAP does not require IP connectivity, it provides just enough
-   support for the reliable transport of authentication protocols, and
-   no more.
-
-   EAP is a lock-step protocol which only supports a single packet in
-   flight.  As a result, EAP cannot efficiently transport bulk data,
-   unlike transport protocols such as TCP [RFC793] or SCTP [RFC2960].
-
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 6]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   While EAP provides support for retransmission, it assumes ordering
-   guarantees provided by the lower layer, so out of order reception is
-   not supported.
-
-   Since EAP does not support fragmentation and reassembly, EAP
-   authentication methods generating payloads larger than the minimum
-   EAP MTU need to provide fragmentation support.
-
-   While authentication methods such as EAP-TLS [RFC2716] provide
-   support for fragmentation and reassembly, the EAP methods defined in
-   this document do not.  As a result, if the EAP packet size exceeds
-   the EAP MTU of the link, these methods will encounter difficulties.
-
-   EAP authentication is initiated by the server (authenticator),
-   whereas many authentication protocols are initiated by the client
-   (peer).  As a result, it may be necessary for an authentication
-   algorithm to add one or two additional messages (at most one
-   roundtrip) in order to run over EAP.
-
-   Where certificate-based authentication is supported, the number of
-   additional roundtrips may be much larger due to fragmentation of
-   certificate chains.  In general, a fragmented EAP packet will require
-   as many round-trips to send as there are fragments.  For example, a
-   certificate chain 14960 octets in size would require ten round-trips
-   to send with a 1496 octet EAP MTU.
-
-   Where EAP runs over a lower layer in which significant packet loss is
-   experienced, or where the connection between the authenticator and
-   authentication server experiences significant packet loss, EAP
-   methods requiring many round-trips can experience difficulties.  In
-   these situations, use of EAP methods with fewer roundtrips is
-   advisable.
-
-2.  Extensible Authentication Protocol (EAP)
-
-   The EAP authentication exchange proceeds as follows:
-
-   [1] The authenticator sends a Request to authenticate the peer.  The
-       Request has a Type field to indicate what is being requested.
-       Examples of Request Types include Identity, MD5-challenge, etc.
-       The MD5-challenge Type corresponds closely to the CHAP
-       authentication protocol [RFC1994].  Typically, the authenticator
-       will send an initial Identity Request; however, an initial
-       Identity Request is not required, and MAY be bypassed.  For
-       example, the identity may not be required where it is determined
-       by the port to which the peer has connected (leased lines,
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 7]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-       dedicated switch or dial-up ports), or where the identity is
-       obtained in another fashion (via calling station identity or MAC
-       address, in the Name field of the MD5-Challenge Response, etc.).
-
-   [2] The peer sends a Response packet in reply to a valid Request.  As
-       with the Request packet, the Response packet contains a Type
-       field, which corresponds to the Type field of the Request.
-
-   [3] The authenticator sends an additional Request packet, and the
-       peer replies with a Response.  The sequence of Requests and
-       Responses continues as long as needed.  EAP is a 'lock step'
-       protocol, so that other than the initial Request, a new Request
-       cannot be sent prior to receiving a valid Response.  The
-       authenticator is responsible for retransmitting requests as
-       described in Section 4.1.  After a suitable number of
-       retransmissions, the authenticator SHOULD end the EAP
-       conversation.  The authenticator MUST NOT send a Success or
-       Failure packet when retransmitting or when it fails to get a
-       response from the peer.
-
-   [4] The conversation continues until the authenticator cannot
-       authenticate the peer (unacceptable Responses to one or more
-       Requests), in which case the authenticator implementation MUST
-       transmit an EAP Failure (Code 4).  Alternatively, the
-       authentication conversation can continue until the authenticator
-       determines that successful authentication has occurred, in which
-       case the authenticator MUST transmit an EAP Success (Code 3).
-
-   Advantages:
-
-   o  The EAP protocol can support multiple authentication mechanisms
-      without having to pre-negotiate a particular one.
-
-   o  Network Access Server (NAS) devices (e.g., a switch or access
-      point) do not have to understand each authentication method and
-      MAY act as a pass-through agent for a backend authentication
-      server.  Support for pass-through is optional.  An authenticator
-      MAY authenticate local peers, while at the same time acting as a
-      pass-through for non-local peers and authentication methods it
-      does not implement locally.
-
-   o  Separation of the authenticator from the backend authentication
-      server simplifies credentials management and policy decision
-      making.
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 8]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Disadvantages:
-
-   o  For use in PPP, EAP requires the addition of a new authentication
-      Type to PPP LCP and thus PPP implementations will need to be
-      modified to use it.  It also strays from the previous PPP
-      authentication model of negotiating a specific authentication
-      mechanism during LCP.  Similarly, switch or access point
-      implementations need to support [IEEE-802.1X] in order to use EAP.
-
-   o  Where the authenticator is separate from the backend
-      authentication server, this complicates the security analysis and,
-      if needed, key distribution.
-
-2.1.  Support for Sequences
-
-   An EAP conversation MAY utilize a sequence of methods.  A common
-   example of this is an Identity request followed by a single EAP
-   authentication method such as an MD5-Challenge.  However, the peer
-   and authenticator MUST utilize only one authentication method (Type 4
-   or greater) within an EAP conversation, after which the authenticator
-   MUST send a Success or Failure packet.
-
-   Once a peer has sent a Response of the same Type as the initial
-   Request, an authenticator MUST NOT send a Request of a different Type
-   prior to completion of the final round of a given method (with the
-   exception of a Notification-Request) and MUST NOT send a Request for
-   an additional method of any Type after completion of the initial
-   authentication method; a peer receiving such Requests MUST treat them
-   as invalid, and silently discard them.  As a result, Identity Requery
-   is not supported.
-
-   A peer MUST NOT send a Nak (legacy or expanded) in reply to a Request
-   after an initial non-Nak Response has been sent.  Since spoofed EAP
-   Request packets may be sent by an attacker, an authenticator
-   receiving an unexpected Nak SHOULD discard it and log the event.
-
-   Multiple authentication methods within an EAP conversation are not
-   supported due to their vulnerability to man-in-the-middle attacks
-   (see Section 7.4) and incompatibility with existing implementations.
-
-   Where a single EAP authentication method is utilized, but other
-   methods are run within it (a "tunneled" method), the prohibition
-   against multiple authentication methods does not apply.  Such
-   "tunneled" methods appear as a single authentication method to EAP.
-   Backward compatibility can be provided, since a peer not supporting a
-   "tunneled" method can reply to the initial EAP-Request with a Nak
-
-
-
-
-
-Aboba, et al.               Standards Track                     [Page 9]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   (legacy or expanded).  To address security vulnerabilities,
-   "tunneled" methods MUST support protection against man-in-the-middle
-   attacks.
-
-2.2.  EAP Multiplexing Model
-
-   Conceptually, EAP implementations consist of the following
-   components:
-
-   [a] Lower layer.  The lower layer is responsible for transmitting and
-       receiving EAP frames between the peer and authenticator.  EAP has
-       been run over a variety of lower layers including PPP, wired IEEE
-       802 LANs [IEEE-802.1X], IEEE 802.11 wireless LANs [IEEE-802.11],
-       UDP (L2TP [RFC2661] and IKEv2 [IKEv2]), and TCP [PIC].  Lower
-       layer behavior is discussed in Section 3.
-
-   [b] EAP layer.  The EAP layer receives and transmits EAP packets via
-       the lower layer, implements duplicate detection and
-       retransmission, and delivers and receives EAP messages to and
-       from the EAP peer and authenticator layers.
-
-   [c] EAP peer and authenticator layers.  Based on the Code field, the
-       EAP layer demultiplexes incoming EAP packets to the EAP peer and
-       authenticator layers.  Typically, an EAP implementation on a
-       given host will support either peer or authenticator
-       functionality, but it is possible for a host to act as both an
-       EAP peer and authenticator.  In such an implementation both EAP
-       peer and authenticator layers will be present.
-
-   [d] EAP method layers.  EAP methods implement the authentication
-       algorithms and receive and transmit EAP messages via the EAP peer
-       and authenticator layers.  Since fragmentation support is not
-       provided by EAP itself, this is the responsibility of EAP
-       methods, which are discussed in Section 5.
-
-   The EAP multiplexing model is illustrated in Figure 1 below.  Note
-   that there is no requirement that an implementation conform to this
-   model, as long as the on-the-wire behavior is consistent with it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 10]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-         +-+-+-+-+-+-+-+-+-+-+-+-+  +-+-+-+-+-+-+-+-+-+-+-+-+
-         |           |           |  |           |           |
-         | EAP method| EAP method|  | EAP method| EAP method|
-         | Type = X  | Type = Y  |  | Type = X  | Type = Y  |
-         |       V   |           |  |       ^   |           |
-         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
-         |       !               |  |       !               |
-         |  EAP  ! Peer layer    |  |  EAP  ! Auth. layer   |
-         |       !               |  |       !               |
-         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
-         |       !               |  |       !               |
-         |  EAP  ! layer         |  |  EAP  ! layer         |
-         |       !               |  |       !               |
-         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
-         |       !               |  |       !               |
-         | Lower ! layer         |  | Lower ! layer         |
-         |       !               |  |       !               |
-         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
-                 !                          !
-                 !   Peer                   ! Authenticator
-                 +------------>-------------+
-
-                     Figure 1: EAP Multiplexing Model
-
-   Within EAP, the Code field functions much like a protocol number in
-   IP.  It is assumed that the EAP layer demultiplexes incoming EAP
-   packets according to the Code field.  Received EAP packets with
-   Code=1 (Request), 3 (Success), and 4 (Failure) are delivered by the
-   EAP layer to the EAP peer layer, if implemented.  EAP packets with
-   Code=2 (Response) are delivered to the EAP authenticator layer, if
-   implemented.
-
-   Within EAP, the Type field functions much like a port number in UDP
-   or TCP.  It is assumed that the EAP peer and authenticator layers
-   demultiplex incoming EAP packets according to their Type, and deliver
-   them only to the EAP method corresponding to that Type.  An EAP
-   method implementation on a host may register to receive packets from
-   the peer or authenticator layers, or both, depending on which role(s)
-   it supports.
-
-   Since EAP authentication methods may wish to access the Identity,
-   implementations SHOULD make the Identity Request and Response
-   accessible to authentication methods (Types 4 or greater), in
-   addition to the Identity method.  The Identity Type is discussed in
-   Section 5.1.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 11]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   A Notification Response is only used as confirmation that the peer
-   received the Notification Request, not that it has processed it, or
-   displayed the message to the user.  It cannot be assumed that the
-   contents of the Notification Request or Response are available to
-   another method.  The Notification Type is discussed in Section 5.2.
-
-   Nak (Type 3) or Expanded Nak (Type 254) are utilized for the purposes
-   of method negotiation.  Peers respond to an initial EAP Request for
-   an unacceptable Type with a Nak Response (Type 3) or Expanded Nak
-   Response (Type 254).  It cannot be assumed that the contents of the
-   Nak Response(s) are available to another method.  The Nak Type(s) are
-   discussed in Section 5.3.
-
-   EAP packets with Codes of Success or Failure do not include a Type
-   field, and are not delivered to an EAP method.  Success and Failure
-   are discussed in Section 4.2.
-
-   Given these considerations, the Success, Failure, Nak Response(s),
-   and Notification Request/Response messages MUST NOT be used to carry
-   data destined for delivery to other EAP methods.
-
-2.3.  Pass-Through Behavior
-
-   When operating as a "pass-through authenticator", an authenticator
-   performs checks on the Code, Identifier, and Length fields as
-   described in Section 4.1.  It forwards EAP packets received from the
-   peer and destined to its authenticator layer to the backend
-   authentication server; packets received from the backend
-   authentication server destined to the peer are forwarded to it.
-
-   A host receiving an EAP packet may only do one of three things with
-   it: act on it, drop it, or forward it.  The forwarding decision is
-   typically based only on examination of the Code, Identifier, and
-   Length fields.  A pass-through authenticator implementation MUST be
-   capable of forwarding EAP packets received from the peer with Code=2
-   (Response) to the backend authentication server. It also MUST be
-   capable of receiving EAP packets from the backend authentication
-   server and forwarding EAP packets of Code=1 (Request), Code=3
-   (Success), and Code=4 (Failure) to the peer.
-
-   Unless the authenticator implements one or more authentication
-   methods locally which support the authenticator role, the EAP method
-   layer header fields (Type, Type-Data) are not examined as part of the
-   forwarding decision.  Where the authenticator supports local
-   authentication methods, it MAY examine the Type field to determine
-   whether to act on the packet itself or forward it.  Compliant pass-
-   through authenticator implementations MUST by default forward EAP
-   packets of any Type.
-
-
-
-Aboba, et al.               Standards Track                    [Page 12]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   EAP packets received with Code=1 (Request), Code=3 (Success), and
-   Code=4 (Failure) are demultiplexed by the EAP layer and delivered to
-   the peer layer.  Therefore, unless a host implements an EAP peer
-   layer, these packets will be silently discarded.  Similarly, EAP
-   packets received with Code=2 (Response) are demultiplexed by the EAP
-   layer and delivered to the authenticator layer.  Therefore, unless a
-   host implements an EAP authenticator layer, these packets will be
-   silently discarded.  The behavior of a "pass-through peer" is
-   undefined within this specification, and is unsupported by AAA
-   protocols such as RADIUS [RFC3579] and Diameter [DIAM-EAP].
-
-   The forwarding model is illustrated in Figure 2.
-
-        Peer         Pass-through Authenticator   Authentication
-                                                      Server
-
-   +-+-+-+-+-+-+                                   +-+-+-+-+-+-+
-   |           |                                   |           |
-   |EAP method |                                   |EAP method |
-   |     V     |                                   |     ^     |
-   +-+-+-!-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-!-+-+-+
-   |     !     |   |EAP  |  EAP  |             |   |     !     |
-   |     !     |   |Peer |  Auth.| EAP Auth.   |   |     !     |
-   |EAP  ! peer|   |     | +-----------+       |   |EAP  !Auth.|
-   |     !     |   |     | !     |     !       |   |     !     |
-   +-+-+-!-+-+-+   +-+-+-+-!-+-+-+-+-+-!-+-+-+-+   +-+-+-!-+-+-+
-   |     !     |   |       !     |     !       |   |     !     |
-   |EAP  !layer|   |   EAP !layer| EAP !layer  |   |EAP  !layer|
-   |     !     |   |       !     |     !       |   |     !     |
-   +-+-+-!-+-+-+   +-+-+-+-!-+-+-+-+-+-!-+-+-+-+   +-+-+-!-+-+-+
-   |     !     |   |       !     |     !       |   |     !     |
-   |Lower!layer|   |  Lower!layer| AAA ! /IP   |   | AAA ! /IP |
-   |     !     |   |       !     |     !       |   |     !     |
-   +-+-+-!-+-+-+   +-+-+-+-!-+-+-+-+-+-!-+-+-+-+   +-+-+-!-+-+-+
-         !                 !           !                 !
-         !                 !           !                 !
-         +-------->--------+           +--------->-------+
-
-
-                   Figure 2: Pass-through Authenticator
-
-   For sessions in which the authenticator acts as a pass-through, it
-   MUST determine the outcome of the authentication solely based on the
-   Accept/Reject indication sent by the backend authentication server;
-   the outcome MUST NOT be determined by the contents of an EAP packet
-   sent along with the Accept/Reject indication, or the absence of such
-   an encapsulated EAP packet.
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 13]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-2.4.  Peer-to-Peer Operation
-
-   Since EAP is a peer-to-peer protocol, an independent and simultaneous
-   authentication may take place in the reverse direction (depending on
-   the capabilities of the lower layer).  Both ends of the link may act
-   as authenticators and peers at the same time.  In this case, it is
-   necessary for both ends to implement EAP authenticator and peer
-   layers.  In addition, the EAP method implementations on both peers
-   must support both authenticator and peer functionality.
-
-   Although EAP supports peer-to-peer operation, some EAP
-   implementations, methods, AAA protocols, and link layers may not
-   support this.  Some EAP methods may support asymmetric
-   authentication, with one type of credential being required for the
-   peer and another type for the authenticator.  Hosts supporting peer-
-   to-peer operation with such a method would need to be provisioned
-   with both types of credentials.
-
-   For example, EAP-TLS [RFC2716] is a client-server protocol in which
-   distinct certificate profiles are typically utilized for the client
-   and server.  This implies that a host supporting peer-to-peer
-   authentication with EAP-TLS would need to implement both the EAP peer
-   and authenticator layers, support both peer and authenticator roles
-   in the EAP-TLS implementation, and provision certificates appropriate
-   for each role.
-
-   AAA protocols such as RADIUS/EAP [RFC3579] and Diameter EAP [DIAM-
-   EAP] only support "pass-through authenticator" operation.  As noted
-   in [RFC3579] Section 2.6.2, a RADIUS server responds to an Access-
-   Request encapsulating an EAP-Request, Success, or Failure packet with
-   an Access-Reject.  There is therefore no support for "pass-through
-   peer" operation.
-
-   Even where a method is used which supports mutual authentication and
-   result indications, several considerations may dictate that two EAP
-   authentications (one in each direction) are required.  These include:
-
-   [1] Support for bi-directional session key derivation in the lower
-       layer.  Lower layers such as IEEE 802.11 may only support uni-
-       directional derivation and transport of transient session keys.
-       For example, the group-key handshake defined in [IEEE-802.11i] is
-       uni-directional, since in IEEE 802.11 infrastructure mode, only
-       the Access Point (AP) sends multicast/broadcast traffic.  In IEEE
-       802.11 ad hoc mode, where either peer may send
-       multicast/broadcast traffic, two uni-directional group-key
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 14]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-       exchanges are required.  Due to limitations of the design, this
-       also implies the need for unicast key derivations and EAP method
-       exchanges to occur in each direction.
-
-   [2] Support for tie-breaking in the lower layer.  Lower layers such
-       as IEEE 802.11 ad hoc do not support "tie breaking" wherein two
-       hosts initiating authentication with each other will only go
-       forward with a single authentication.  This implies that even if
-       802.11 were to support a bi-directional group-key handshake, then
-       two authentications, one in each direction, might still occur.
-
-   [3] Peer policy satisfaction.  EAP methods may support result
-       indications, enabling the peer to indicate to the EAP server
-       within the method that it successfully authenticated the EAP
-       server, as well as for the server to indicate that it has
-       authenticated the peer.  However, a pass-through authenticator
-       will not be aware that the peer has accepted the credentials
-       offered by the EAP server, unless this information is provided to
-       the authenticator via the AAA protocol.  The authenticator SHOULD
-       interpret the receipt of a key attribute within an Accept packet
-       as an indication that the peer has successfully authenticated the
-       server.
-
-   However, it is possible that the EAP peer's access policy was not
-   satisfied during the initial EAP exchange, even though mutual
-   authentication occurred.  For example, the EAP authenticator may not
-   have demonstrated authorization to act in both peer and authenticator
-   roles.  As a result, the peer may require an additional
-   authentication in the reverse direction, even if the peer provided an
-   indication that the EAP server had successfully authenticated to it.
-
-3.  Lower Layer Behavior
-
-3.1.  Lower Layer Requirements
-
-   EAP makes the following assumptions about lower layers:
-
-   [1] Unreliable transport.  In EAP, the authenticator retransmits
-       Requests that have not yet received Responses so that EAP does
-       not assume that lower layers are reliable.  Since EAP defines its
-       own retransmission behavior, it is possible (though undesirable)
-       for retransmission to occur both in the lower layer and the EAP
-       layer when EAP is run over a reliable lower layer.
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 15]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Note that EAP Success and Failure packets are not retransmitted.
-   Without a reliable lower layer, and with a non-negligible error rate,
-   these packets can be lost, resulting in timeouts.  It is therefore
-   desirable for implementations to improve their resilience to loss of
-   EAP Success or Failure packets, as described in Section 4.2.
-
-   [2] Lower layer error detection.  While EAP does not assume that the
-       lower layer is reliable, it does rely on lower layer error
-       detection (e.g., CRC, Checksum, MIC, etc.).  EAP methods may not
-       include a MIC, or if they do, it may not be computed over all the
-       fields in the EAP packet, such as the Code, Identifier, Length,
-       or Type fields.  As a result, without lower layer error
-       detection, undetected errors could creep into the EAP layer or
-       EAP method layer header fields, resulting in authentication
-       failures.
-
-       For example, EAP TLS [RFC2716], which computes its MIC over the
-       Type-Data field only, regards MIC validation failures as a fatal
-       error.  Without lower layer error detection, this method, and
-       others like it, will not perform reliably.
-
-   [3] Lower layer security.  EAP does not require lower layers to
-       provide security services such as per-packet confidentiality,
-       authentication, integrity, and replay protection.  However, where
-       these security services are available, EAP methods supporting Key
-       Derivation (see Section 7.2.1) can be used to provide dynamic
-       keying material.  This makes it possible to bind the EAP
-       authentication to subsequent data and protect against data
-       modification, spoofing, or replay.  See Section 7.1 for details.
-
-   [4] Minimum MTU.  EAP is capable of functioning on lower layers that
-       provide an EAP MTU size of 1020 octets or greater.
-
-       EAP does not support path MTU discovery, and fragmentation and
-       reassembly is not supported by EAP, nor by the methods defined in
-       this specification: Identity (1), Notification (2), Nak Response
-       (3), MD5-Challenge (4), One Time Password (5), Generic Token Card
-       (6), and expanded Nak Response (254) Types.
-
-       Typically, the EAP peer obtains information on the EAP MTU from
-       the lower layers and sets the EAP frame size to an appropriate
-       value.  Where the authenticator operates in pass-through mode,
-       the authentication server does not have a direct way of
-       determining the EAP MTU, and therefore relies on the
-       authenticator to provide it with this information, such as via
-       the Framed-MTU attribute, as described in [RFC3579], Section 2.4.
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 16]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-       While methods such as EAP-TLS [RFC2716] support fragmentation and
-       reassembly, EAP methods originally designed for use within PPP
-       where a 1500 octet MTU is guaranteed for control frames (see
-       [RFC1661], Section 6.1) may lack fragmentation and reassembly
-       features.
-
-       EAP methods can assume a minimum EAP MTU of 1020 octets in the
-       absence of other information.  EAP methods SHOULD include support
-       for fragmentation and reassembly if their payloads can be larger
-       than this minimum EAP MTU.
-
-       EAP is a lock-step protocol, which implies a certain inefficiency
-       when handling fragmentation and reassembly.  Therefore, if the
-       lower layer supports fragmentation and reassembly (such as where
-       EAP is transported over IP), it may be preferable for
-       fragmentation and reassembly to occur in the lower layer rather
-       than in EAP.  This can be accomplished by providing an
-       artificially large EAP MTU to EAP, causing fragmentation and
-       reassembly to be handled within the lower layer.
-
-   [5] Possible duplication.  Where the lower layer is reliable, it will
-       provide the EAP layer with a non-duplicated stream of packets.
-       However,  while it is desirable that lower layers provide for
-       non-duplication, this is not a requirement.  The Identifier field
-       provides both the peer and authenticator with the ability to
-       detect duplicates.
-
-   [6] Ordering guarantees.  EAP does not require the Identifier to be
-       monotonically increasing, and so is reliant on lower layer
-       ordering guarantees for correct operation.  EAP was originally
-       defined to run on PPP, and [RFC1661] Section 1 has an ordering
-       requirement:
-
-           "The Point-to-Point Protocol is designed for simple links
-           which transport packets between two peers.  These links
-           provide full-duplex simultaneous bi-directional operation,
-           and are assumed to deliver packets in order."
-
-       Lower layer transports for EAP MUST preserve ordering between a
-       source and destination at a given priority level (the ordering
-       guarantee provided by [IEEE-802]).
-
-       Reordering, if it occurs, will typically result in an EAP
-       authentication failure, causing EAP authentication to be re-run.
-       In an environment in which reordering is likely, it is therefore
-       expected that EAP authentication failures will be common.  It is
-       RECOMMENDED that EAP only be run over lower layers that provide
-       ordering guarantees; running EAP over raw IP or UDP transport is
-
-
-
-Aboba, et al.               Standards Track                    [Page 17]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-       NOT RECOMMENDED.  Encapsulation of EAP within RADIUS [RFC3579]
-       satisfies ordering requirements, since RADIUS is a "lockstep"
-       protocol that delivers packets in order.
-
-3.2.  EAP Usage Within PPP
-
-   In order to establish communications over a point-to-point link, each
-   end of the PPP link first sends LCP packets to configure the data
-   link during the Link Establishment phase.  After the link has been
-   established, PPP provides for an optional Authentication phase before
-   proceeding to the Network-Layer Protocol phase.
-
-   By default, authentication is not mandatory.  If authentication of
-   the link is desired, an implementation MUST specify the
-   Authentication Protocol Configuration Option during the Link
-   Establishment phase.
-
-   If the identity of the peer has been established in the
-   Authentication phase, the server can use that identity in the
-   selection of options for the following network layer negotiations.
-
-   When implemented within PPP, EAP does not select a specific
-   authentication mechanism at the PPP Link Control Phase, but rather
-   postpones this until the Authentication Phase.  This allows the
-   authenticator to request more information before determining the
-   specific authentication mechanism.  This also permits the use of a
-   "backend" server which actually implements the various mechanisms
-   while the PPP authenticator merely passes through the authentication
-   exchange.  The PPP Link Establishment and Authentication phases, and
-   the Authentication Protocol Configuration Option, are defined in The
-   Point-to-Point Protocol (PPP) [RFC1661].
-
-3.2.1.  PPP Configuration Option Format
-
-   A summary of the PPP Authentication Protocol Configuration Option
-   format to negotiate EAP follows.  The fields are transmitted from
-   left to right.
-
-   Exactly one EAP packet is encapsulated in the Information field of a
-   PPP Data Link Layer frame where the protocol field indicates type hex
-   C227 (PPP EAP).
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 18]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Type      |    Length     |     Authentication Protocol   |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      3
-
-   Length
-
-      4
-
-   Authentication Protocol
-
-      C227 (Hex) for Extensible Authentication Protocol (EAP)
-
-3.3.  EAP Usage Within IEEE 802
-
-   The encapsulation of EAP over IEEE 802 is defined in [IEEE-802.1X].
-   The IEEE 802 encapsulation of EAP does not involve PPP, and IEEE
-   802.1X does not include support for link or network layer
-   negotiations.  As a result, within IEEE 802.1X, it is not possible to
-   negotiate non-EAP authentication mechanisms, such as PAP or CHAP
-   [RFC1994].
-
-3.4.  Lower Layer Indications
-
-   The reliability and security of lower layer indications is dependent
-   on the lower layer.  Since EAP is media independent, the presence or
-   absence of lower layer security is not taken into account in the
-   processing of EAP messages.
-
-   To improve reliability, if a peer receives a lower layer success
-   indication as defined in Section 7.2, it MAY conclude that a Success
-   packet has been lost, and behave as if it had actually received a
-   Success packet.  This includes choosing to ignore the Success in some
-   circumstances as described in Section 4.2.
-
-   A discussion of some reliability and security issues with lower layer
-   indications in PPP, IEEE 802 wired networks, and IEEE 802.11 wireless
-   LANs can be found in the Security Considerations, Section 7.12.
-
-   After EAP authentication is complete, the peer will typically
-   transmit and receive data via the authenticator.  It is desirable to
-   provide assurance that the entities transmitting data are the same
-   ones that successfully completed EAP authentication.  To accomplish
-
-
-
-Aboba, et al.               Standards Track                    [Page 19]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   this, it is necessary for the lower layer to provide per-packet
-   integrity, authentication and replay protection, and to bind these
-   per-packet services to the keys derived during EAP authentication.
-   Otherwise, it is possible for subsequent data traffic to be modified,
-   spoofed, or replayed.
-
-   Where keying material for the lower layer ciphersuite is itself
-   provided by EAP, ciphersuite negotiation and key activation are
-   controlled by the lower layer.  In PPP, ciphersuites are negotiated
-   within ECP so that it is not possible to use keys derived from EAP
-   authentication until the completion of ECP.  Therefore, an initial
-   EAP exchange cannot be protected by a PPP ciphersuite, although EAP
-   re-authentication can be protected.
-
-   In IEEE 802 media, initial key activation also typically occurs after
-   completion of EAP authentication.  Therefore an initial EAP exchange
-   typically cannot be protected by the lower layer ciphersuite,
-   although an EAP re-authentication or pre-authentication exchange can
-   be protected.
-
-4.  EAP Packet Format
-
-   A summary of the EAP packet format is shown below.  The fields are
-   transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Code      |  Identifier   |            Length             |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |    Data ...
-   +-+-+-+-+
-
-   Code
-
-      The Code field is one octet and identifies the Type of EAP packet.
-      EAP Codes are assigned as follows:
-
-         1       Request
-         2       Response
-         3       Success
-         4       Failure
-
-      Since EAP only defines Codes 1-4, EAP packets with other codes
-      MUST be silently discarded by both authenticators and peers.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 20]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Identifier
-
-      The Identifier field is one octet and aids in matching Responses
-      with Requests.
-
-   Length
-
-      The Length field is two octets and indicates the length, in
-      octets, of the EAP packet including the Code, Identifier, Length,
-      and Data fields.  Octets outside the range of the Length field
-      should be treated as Data Link Layer padding and MUST be ignored
-      upon reception.  A message with the Length field set to a value
-      larger than the number of received octets MUST be silently
-      discarded.
-
-   Data
-
-      The Data field is zero or more octets.  The format of the Data
-      field is determined by the Code field.
-
-4.1.  Request and Response
-
-   Description
-
-      The Request packet (Code field set to 1) is sent by the
-      authenticator to the peer.  Each Request has a Type field which
-      serves to indicate what is being requested.  Additional Request
-      packets MUST be sent until a valid Response packet is received, an
-      optional retry counter expires, or a lower layer failure
-      indication is received.
-
-      Retransmitted Requests MUST be sent with the same Identifier value
-      in order to distinguish them from new Requests.  The content of
-      the data field is dependent on the Request Type.  The peer MUST
-      send a Response packet in reply to a valid Request packet.
-      Responses MUST only be sent in reply to a valid Request and never
-      be retransmitted on a timer.
-
-      If a peer receives a valid duplicate Request for which it has
-      already sent a Response, it MUST resend its original Response
-      without reprocessing the Request.  Requests MUST be processed in
-      the order that they are received, and MUST be processed to their
-      completion before inspecting the next Request.
-
-   A summary of the Request and Response packet format follows.  The
-   fields are transmitted from left to right.
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 21]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Code      |  Identifier   |            Length             |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Type      |  Type-Data ...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
-
-   Code
-
-      1 for Request
-      2 for Response
-
-   Identifier
-
-      The Identifier field is one octet.  The Identifier field MUST be
-      the same if a Request packet is retransmitted due to a timeout
-      while waiting for a Response.  Any new (non-retransmission)
-      Requests MUST modify the Identifier field.
-
-      The Identifier field of the Response MUST match that of the
-      currently outstanding Request.  An authenticator receiving a
-      Response whose Identifier value does not match that of the
-      currently outstanding Request MUST silently discard the Response.
-
-      In order to avoid confusion between new Requests and
-      retransmissions, the Identifier value chosen for each new Request
-      need only be different from the previous Request, but need not be
-      unique within the conversation.  One way to achieve this is to
-      start the Identifier at an initial value and increment it for each
-      new Request.  Initializing the first Identifier with a random
-      number rather than starting from zero is recommended, since it
-      makes sequence attacks somewhat more difficult.
-
-      Since the Identifier space is unique to each session,
-      authenticators are not restricted to only 256 simultaneous
-      authentication conversations.  Similarly, with re-authentication,
-      an EAP conversation might continue over a long period of time, and
-      is not limited to only 256 roundtrips.
-
-   Implementation Note: The authenticator is responsible for
-   retransmitting Request messages.  If the Request message is obtained
-   from elsewhere (such as from a backend authentication server), then
-   the authenticator will need to save a copy of the Request in order to
-   accomplish this.  The peer is responsible for detecting and handling
-   duplicate Request messages before processing them in any way,
-   including passing them on to an outside party.  The authenticator is
-   also responsible for discarding Response messages with a non-matching
-
-
-
-Aboba, et al.               Standards Track                    [Page 22]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Identifier value before acting on them in any way, including passing
-   them on to the backend authentication server for verification.  Since
-   the authenticator can retransmit before receiving a Response from the
-   peer, the authenticator can receive multiple Responses, each with a
-   matching Identifier.  Until a new Request is received by the
-   authenticator, the Identifier value is not updated, so that the
-   authenticator forwards Responses to the backend authentication
-   server, one at a time.
-
-   Length
-
-      The Length field is two octets and indicates the length of the EAP
-      packet including the Code, Identifier, Length, Type, and Type-Data
-      fields.  Octets outside the range of the Length field should be
-      treated as Data Link Layer padding and MUST be ignored upon
-      reception.  A message with the Length field set to a value larger
-      than the number of received octets MUST be silently discarded.
-
-   Type
-
-      The Type field is one octet.  This field indicates the Type of
-      Request or Response.  A single Type MUST be specified for each EAP
-      Request or Response.  An initial specification of Types follows in
-      Section 5 of this document.
-
-      The Type field of a Response MUST either match that of the
-      Request, or correspond to a legacy or Expanded Nak (see Section
-      5.3) indicating that a Request Type is unacceptable to the peer.
-      A peer MUST NOT send a Nak (legacy or expanded) in response to a
-      Request, after an initial non-Nak Response has been sent.  An EAP
-      server receiving a Response not meeting these requirements MUST
-      silently discard it.
-
-   Type-Data
-
-      The Type-Data field varies with the Type of Request and the
-      associated Response.
-
-4.2.  Success and Failure
-
-   The Success packet is sent by the authenticator to the peer after
-   completion of an EAP authentication method (Type 4 or greater) to
-   indicate that the peer has authenticated successfully to the
-   authenticator.  The authenticator MUST transmit an EAP packet with
-   the Code field set to 3 (Success).  If the authenticator cannot
-   authenticate the peer (unacceptable Responses to one or more
-   Requests), then after unsuccessful completion of the EAP method in
-   progress, the implementation MUST transmit an EAP packet with the
-
-
-
-Aboba, et al.               Standards Track                    [Page 23]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Code field set to 4 (Failure).  An authenticator MAY wish to issue
-   multiple Requests before sending a Failure response in order to allow
-   for human typing mistakes.  Success and Failure packets MUST NOT
-   contain additional data.
-
-   Success and Failure packets MUST NOT be sent by an EAP authenticator
-   if the specification of the given method does not explicitly permit
-   the method to finish at that point.  A peer EAP implementation
-   receiving a Success or Failure packet where sending one is not
-   explicitly permitted MUST silently discard it.  By default, an EAP
-   peer MUST silently discard a "canned" Success packet (a Success
-   packet sent immediately upon connection).  This ensures that a rogue
-   authenticator will not be able to bypass mutual authentication by
-   sending a Success packet prior to conclusion of the EAP method
-   conversation.
-
-   Implementation Note: Because the Success and Failure packets are not
-   acknowledged, they are not retransmitted by the authenticator, and
-   may be potentially lost.  A peer MUST allow for this circumstance as
-   described in this note.  See also Section 3.4 for guidance on the
-   processing of lower layer success and failure indications.
-
-   As described in Section 2.1, only a single EAP authentication method
-   is allowed within an EAP conversation.  EAP methods may implement
-   result indications.  After the authenticator sends a failure result
-   indication to the peer, regardless of the response from the peer, it
-   MUST subsequently send a Failure packet.  After the authenticator
-   sends a success result indication to the peer and receives a success
-   result indication from the peer, it MUST subsequently send a Success
-   packet.
-
-   On the peer, once the method completes unsuccessfully (that is,
-   either the authenticator sends a failure result indication, or the
-   peer decides that it does not want to continue the conversation,
-   possibly after sending a failure result indication), the peer MUST
-   terminate the conversation and indicate failure to the lower layer.
-   The peer MUST silently discard Success packets and MAY silently
-   discard Failure packets.  As a result, loss of a Failure packet need
-   not result in a timeout.
-
-   On the peer, after success result indications have been exchanged by
-   both sides, a Failure packet MUST be silently discarded.  The peer
-   MAY, in the event that an EAP Success is not received, conclude that
-   the EAP Success packet was lost and that authentication concluded
-   successfully.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 24]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   If the authenticator has not sent a result indication, and the peer
-   is willing to continue the conversation, the peer waits for a Success
-   or Failure packet once the method completes, and MUST NOT silently
-   discard either of them.  In the event that neither a Success nor
-   Failure packet is received, the peer SHOULD terminate the
-   conversation to avoid lengthy timeouts in case the lost packet was an
-   EAP Failure.
-
-   If the peer attempts to authenticate to the authenticator and fails
-   to do so, the authenticator MUST send a Failure packet and MUST NOT
-   grant access by sending a Success packet.  However, an authenticator
-   MAY omit having the peer authenticate to it in situations where
-   limited access is offered (e.g., guest access).  In this case, the
-   authenticator MUST send a Success packet.
-
-   Where the peer authenticates successfully to the authenticator, but
-   the authenticator does not send a result indication, the
-   authenticator MAY deny access by sending a Failure packet where the
-   peer is not currently authorized for network access.
-
-   A summary of the Success and Failure packet format is shown below.
-   The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Code      |  Identifier   |            Length             |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Code
-
-      3 for Success
-      4 for Failure
-
-   Identifier
-
-      The Identifier field is one octet and aids in matching replies to
-      Responses.  The Identifier field MUST match the Identifier field
-      of the Response packet that it is sent in response to.
-
-   Length
-
-      4
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 25]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-4.3.  Retransmission Behavior
-
-   Because the authentication process will often involve user input,
-   some care must be taken when deciding upon retransmission strategies
-   and authentication timeouts.  By default, where EAP is run over an
-   unreliable lower layer, the EAP retransmission timer SHOULD be
-   dynamically estimated.  A maximum of 3-5 retransmissions is
-   suggested.
-
-   When run over a reliable lower layer (e.g., EAP over ISAKMP/TCP, as
-   within [PIC]), the authenticator retransmission timer SHOULD be set
-   to an infinite value, so that retransmissions do not occur at the EAP
-   layer.  The peer may still maintain a timeout value so as to avoid
-   waiting indefinitely for a Request.
-
-   Where the authentication process requires user input, the measured
-   round trip times may be determined by user responsiveness rather than
-   network characteristics, so that dynamic RTO estimation may not be
-   helpful.  Instead, the retransmission timer SHOULD be set so as to
-   provide sufficient time for the user to respond, with longer timeouts
-   required in certain cases, such as where Token Cards (see Section
-   5.6) are involved.
-
-   In order to provide the EAP authenticator with guidance as to the
-   appropriate timeout value, a hint can be communicated to the
-   authenticator by the backend authentication server (such as via the
-   RADIUS Session-Timeout attribute).
-
-   In order to dynamically estimate the EAP retransmission timer, the
-   algorithms for the estimation of SRTT, RTTVAR, and RTO described in
-   [RFC2988] are RECOMMENDED, including use of Karn's algorithm, with
-   the following potential modifications:
-
-   [a] In order to avoid synchronization behaviors that can occur with
-       fixed timers among distributed systems, the retransmission timer
-       is calculated with a jitter by using the RTO value and randomly
-       adding a value drawn between -RTOmin/2 and RTOmin/2.  Alternative
-       calculations to create jitter MAY be used.  These MUST be
-       pseudo-random.  For a discussion of pseudo-random number
-       generation, see [RFC1750].
-
-   [b] When EAP is transported over a single link (as opposed to over
-       the Internet), smaller values of RTOinitial, RTOmin, and RTOmax
-       MAY be used.  Recommended values are RTOinitial=1 second,
-       RTOmin=200ms, and RTOmax=20 seconds.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 26]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [c] When EAP is transported over a single link (as opposed to over
-       the Internet), estimates MAY be done on a per-authenticator
-       basis, rather than a per-session basis.  This enables the
-       retransmission estimate to make the most use of information on
-       link-layer behavior.
-
-   [d] An EAP implementation MAY clear SRTT and RTTVAR after backing off
-       the timer multiple times, as it is likely that the current SRTT
-       and RTTVAR are bogus in this situation.  Once SRTT and RTTVAR are
-       cleared, they should be initialized with the next RTT sample
-       taken as described in [RFC2988] equation 2.2.
-
-5.  Initial EAP Request/Response Types
-
-   This section defines the initial set of EAP Types used in Request/
-   Response exchanges.  More Types may be defined in future documents.
-   The Type field is one octet and identifies the structure of an EAP
-   Request or Response packet.  The first 3 Types are considered special
-   case Types.
-
-   The remaining Types define authentication exchanges.  Nak (Type 3) or
-   Expanded Nak (Type 254) are valid only for Response packets, they
-   MUST NOT be sent in a Request.
-
-   All EAP implementations MUST support Types 1-4, which are defined in
-   this document, and SHOULD support Type 254.  Implementations MAY
-   support other Types defined here or in future RFCs.
-
-             1       Identity
-             2       Notification
-             3       Nak (Response only)
-             4       MD5-Challenge
-             5       One Time Password (OTP)
-             6       Generic Token Card (GTC)
-           254       Expanded Types
-           255       Experimental use
-
-   EAP methods MAY support authentication based on shared secrets.  If
-   the shared secret is a passphrase entered by the user,
-   implementations MAY support entering passphrases with non-ASCII
-   characters.  In this case, the input should be processed using an
-   appropriate stringprep [RFC3454] profile, and encoded in octets using
-   UTF-8 encoding [RFC2279].  A preliminary version of a possible
-   stringprep profile is described in [SASLPREP].
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 27]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-5.1.  Identity
-
-   Description
-
-      The Identity Type is used to query the identity of the peer.
-      Generally, the authenticator will issue this as the initial
-      Request.  An optional displayable message MAY be included to
-      prompt the peer in the case where there is an expectation of
-      interaction with a user.  A Response of Type 1 (Identity) SHOULD
-      be sent in Response to a Request with a Type of 1 (Identity).
-
-      Some EAP implementations piggy-back various options into the
-      Identity Request after a NUL-character.  By default, an EAP
-      implementation SHOULD NOT assume that an Identity Request or
-      Response can be larger than 1020 octets.
-
-      It is RECOMMENDED that the Identity Response be used primarily for
-      routing purposes and selecting which EAP method to use.  EAP
-      Methods SHOULD include a method-specific mechanism for obtaining
-      the identity, so that they do not have to rely on the Identity
-      Response.  Identity Requests and Responses are sent in cleartext,
-      so an attacker may snoop on the identity, or even modify or spoof
-      identity exchanges.  To address these threats, it is preferable
-      for an EAP method to include an identity exchange that supports
-      per-packet authentication, integrity and replay protection, and
-      confidentiality.  The Identity Response may not be the appropriate
-      identity for the method; it may have been truncated or obfuscated
-      so as to provide privacy, or it may have been decorated for
-      routing purposes.  Where the peer is configured to only accept
-      authentication methods supporting protected identity exchanges,
-      the peer MAY provide an abbreviated Identity Response (such as
-      omitting the peer-name portion of the NAI [RFC2486]).  For further
-      discussion of identity protection, see Section 7.3.
-
-   Implementation Note: The peer MAY obtain the Identity via user input.
-   It is suggested that the authenticator retry the Identity Request in
-   the case of an invalid Identity or authentication failure to allow
-   for potential typos on the part of the user.  It is suggested that
-   the Identity Request be retried a minimum of 3 times before
-   terminating the authentication.  The Notification Request MAY be used
-   to indicate an invalid authentication attempt prior to transmitting a
-   new Identity Request (optionally, the failure MAY be indicated within
-   the message of the new Identity Request itself).
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 28]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Type
-
-      1
-
-   Type-Data
-
-      This field MAY contain a displayable message in the Request,
-      containing UTF-8 encoded ISO 10646 characters [RFC2279].  Where
-      the Request contains a null, only the portion of the field prior
-      to the null is displayed.  If the Identity is unknown, the
-      Identity Response field should be zero bytes in length.  The
-      Identity Response field MUST NOT be null terminated.  In all
-      cases, the length of the Type-Data field is derived from the
-      Length field of the Request/Response packet.
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           None
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         No
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   N/A
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-5.2.  Notification
-
-   Description
-
-      The Notification Type is optionally used to convey a displayable
-      message from the authenticator to the peer.  An authenticator MAY
-      send a Notification Request to the peer at any time when there is
-      no outstanding Request, prior to completion of an EAP
-      authentication method.  The peer MUST respond to a Notification
-      Request with a Notification Response unless the EAP authentication
-      method specification prohibits the use of Notification messages.
-      In any case, a Nak Response MUST NOT be sent in response to a
-      Notification Request.  Note that the default maximum length of a
-      Notification Request is 1020 octets.  By default, this leaves at
-      most 1015 octets for the human readable message.
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 29]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-      An EAP method MAY indicate within its specification that
-      Notification messages must not be sent during that method.  In
-      this case, the peer MUST silently discard Notification Requests
-      from the point where an initial Request for that Type is answered
-      with a Response of the same Type.
-
-      The peer SHOULD display this message to the user or log it if it
-      cannot be displayed.  The Notification Type is intended to provide
-      an acknowledged notification of some imperative nature, but it is
-      not an error indication, and therefore does not change the state
-      of the peer.  Examples include a password with an expiration time
-      that is about to expire, an OTP sequence integer which is nearing
-      0, an authentication failure warning, etc.  In most circumstances,
-      Notification should not be required.
-
-   Type
-
-      2
-
-   Type-Data
-
-      The Type-Data field in the Request contains a displayable message
-      greater than zero octets in length, containing UTF-8 encoded ISO
-      10646 characters [RFC2279].  The length of the message is
-      determined by the Length field of the Request packet.  The message
-      MUST NOT be null terminated.  A Response MUST be sent in reply to
-      the Request with a Type field of 2 (Notification).  The Type-Data
-      field of the Response is zero octets in length.  The Response
-      should be sent immediately (independent of how the message is
-      displayed or logged).
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           None
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         No
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   N/A
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 30]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-5.3.  Nak
-
-5.3.1.  Legacy Nak
-
-   Description
-
-      The legacy Nak Type is valid only in Response messages.  It is
-      sent in reply to a Request where the desired authentication Type
-      is unacceptable.  Authentication Types are numbered 4 and above.
-      The Response contains one or more authentication Types desired by
-      the Peer.  Type zero (0) is used to indicate that the sender has
-      no viable alternatives, and therefore the authenticator SHOULD NOT
-      send another Request after receiving a Nak Response containing a
-      zero value.
-
-      Since the legacy Nak Type is valid only in Responses and has very
-      limited functionality, it MUST NOT be used as a general purpose
-      error indication, such as for communication of error messages, or
-      negotiation of parameters specific to a particular EAP method.
-
-   Code
-
-      2 for Response.
-
-   Identifier
-
-      The Identifier field is one octet and aids in matching Responses
-      with Requests.  The Identifier field of a legacy Nak Response MUST
-      match the Identifier field of the Request packet that it is sent
-      in response to.
-
-   Length
-
-      >=6
-
-   Type
-
-      3
-
-   Type-Data
-
-      Where a peer receives a Request for an unacceptable authentication
-      Type (4-253,255), or a peer lacking support for Expanded Types
-      receives a Request for Type 254, a Nak Response (Type 3) MUST be
-      sent.  The Type-Data field of the Nak Response (Type 3) MUST
-      contain one or more octets indicating the desired authentication
-      Type(s), one octet per Type, or the value zero (0) to indicate no
-      proposed alternative.  A peer supporting Expanded Types that
-
-
-
-Aboba, et al.               Standards Track                    [Page 31]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-      receives a Request for an unacceptable authentication Type (4-253,
-      255) MAY include the value 254 in the Nak Response (Type 3) to
-      indicate the desire for an Expanded authentication Type. If the
-      authenticator can accommodate this preference, it will respond
-      with an Expanded Type Request (Type 254).
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           None
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         No
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   N/A
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-
-5.3.2.  Expanded Nak
-
-   Description
-
-      The Expanded Nak Type is valid only in Response messages.  It MUST
-      be sent only in reply to a Request of Type 254 (Expanded Type)
-      where the authentication Type is unacceptable.  The Expanded Nak
-      Type uses the Expanded Type format itself, and the Response
-      contains one or more authentication Types desired by the peer, all
-      in Expanded Type format.  Type zero (0) is used to indicate that
-      the sender has no viable alternatives.  The general format of the
-      Expanded Type is described in Section 5.7.
-
-      Since the Expanded Nak Type is valid only in Responses and has
-      very limited functionality, it MUST NOT be used as a general
-      purpose error indication, such as for communication of error
-      messages, or negotiation of parameters specific to a particular
-      EAP method.
-
-   Code
-
-      2 for Response.
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 32]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Identifier
-
-      The Identifier field is one octet and aids in matching Responses
-      with Requests.  The Identifier field of an Expanded Nak Response
-      MUST match the Identifier field of the Request packet that it is
-      sent in response to.
-
-   Length
-
-      >=20
-
-   Type
-
-      254
-
-   Vendor-Id
-
-      0 (IETF)
-
-   Vendor-Type
-
-      3 (Nak)
-
-   Vendor-Data
-
-      The Expanded Nak Type is only sent when the Request contains an
-      Expanded Type (254) as defined in Section 5.7.  The Vendor-Data
-      field of the Nak Response MUST contain one or more authentication
-      Types (4 or greater), all in expanded format, 8 octets per Type,
-      or the value zero (0), also in Expanded Type format, to indicate
-      no proposed alternative.  The desired authentication Types may
-      include a mixture of Vendor-Specific and IETF Types.  For example,
-      an Expanded Nak Response indicating a preference for OTP (Type 5),
-      and an MIT (Vendor-Id=20) Expanded Type of 6 would appear as
-      follows:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 33]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     2         |  Identifier   |           Length=28           |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |   Type=254    |                0 (IETF)                       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |                                3 (Nak)                        |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |   Type=254    |                0 (IETF)                       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |                                5 (OTP)                        |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |   Type=254    |                20 (MIT)                       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |                                6                              |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   An Expanded Nak Response indicating a no desired alternative would
-   appear as follows:
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     2         |  Identifier   |           Length=20           |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |   Type=254    |                0 (IETF)                       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |                                3 (Nak)                        |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |   Type=254    |                0 (IETF)                       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |                                0 (No alternative)             |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           None
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         No
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   N/A
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-
-
-
-Aboba, et al.               Standards Track                    [Page 34]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-
-5.4.  MD5-Challenge
-
-   Description
-
-      The MD5-Challenge Type is analogous to the PPP CHAP protocol
-      [RFC1994] (with MD5 as the specified algorithm).  The Request
-      contains a "challenge" message to the peer.  A Response MUST be
-      sent in reply to the Request.  The Response MAY be either of Type
-      4 (MD5-Challenge), Nak (Type 3), or Expanded Nak (Type 254).  The
-      Nak reply indicates the peer's desired authentication Type(s).
-      EAP peer and EAP server implementations MUST support the MD5-
-      Challenge mechanism.  An authenticator that supports only pass-
-      through MUST allow communication with a backend authentication
-      server that is capable of supporting MD5-Challenge, although the
-      EAP authenticator implementation need not support MD5-Challenge
-      itself.  However, if the EAP authenticator can be configured to
-      authenticate peers locally (e.g., not operate in pass-through),
-      then the requirement for support of the MD5-Challenge mechanism
-      applies.
-
-      Note that the use of the Identifier field in the MD5-Challenge
-      Type is different from that described in [RFC1994].  EAP allows
-      for retransmission of MD5-Challenge Request packets, while
-      [RFC1994] states that both the Identifier and Challenge fields
-      MUST change each time a Challenge (the CHAP equivalent of the
-      MD5-Challenge Request packet) is sent.
-
-      Note: [RFC1994] treats the shared secret as an octet string, and
-      does not specify how it is entered into the system (or if it is
-      handled by the user at all).  EAP MD5-Challenge implementations
-      MAY support entering passphrases with non-ASCII characters.  See
-      Section 5 for instructions how the input should be processed and
-      encoded into octets.
-
-   Type
-
-      4
-
-   Type-Data
-
-      The contents of the Type-Data field is summarized below.  For
-      reference on the use of these fields, see the PPP Challenge
-      Handshake Authentication Protocol [RFC1994].
-
-
-
-Aboba, et al.               Standards Track                    [Page 35]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Value-Size   |  Value ...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Name ...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           Password or pre-shared key.
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         No
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   No
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-5.5.  One-Time Password (OTP)
-
-   Description
-
-      The One-Time Password system is defined in "A One-Time Password
-      System" [RFC2289] and "OTP Extended Responses" [RFC2243].  The
-      Request contains an OTP challenge in the format described in
-      [RFC2289].  A Response MUST be sent in reply to the Request.  The
-      Response MUST be of Type 5 (OTP), Nak (Type 3), or Expanded Nak
-      (Type 254).  The Nak Response indicates the peer's desired
-      authentication Type(s).  The EAP OTP method is intended for use
-      with the One-Time Password system only, and MUST NOT be used to
-      provide support for cleartext passwords.
-
-   Type
-
-      5
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 36]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Type-Data
-
-      The Type-Data field contains the OTP "challenge" as a displayable
-      message in the Request.  In the Response, this field is used for
-      the 6 words from the OTP dictionary [RFC2289].  The messages MUST
-      NOT be null terminated.  The length of the field is derived from
-      the Length field of the Request/Reply packet.
-
-      Note: [RFC2289] does not specify how the secret pass-phrase is
-      entered by the user, or how the pass-phrase is converted into
-      octets.  EAP OTP implementations MAY support entering passphrases
-      with non-ASCII characters.  See Section 5 for instructions on how
-      the input should be processed and encoded into octets.
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           One-Time Password
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         Yes
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   No
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-
-5.6.  Generic Token Card (GTC)
-
-   Description
-
-      The Generic Token Card Type is defined for use with various Token
-      Card implementations which require user input.  The Request
-      contains a displayable message and the Response contains the Token
-      Card information necessary for authentication.  Typically, this
-      would be information read by a user from the Token card device and
-      entered as ASCII text.  A Response MUST be sent in reply to the
-      Request.  The Response MUST be of Type 6 (GTC), Nak (Type 3), or
-      Expanded Nak (Type 254).  The Nak Response indicates the peer's
-      desired authentication Type(s).  The EAP GTC method is intended
-      for use with the Token Cards supporting challenge/response
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 37]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-      authentication and MUST NOT be used to provide support for
-      cleartext passwords in the absence of a protected tunnel with
-      server authentication.
-
-   Type
-
-      6
-
-   Type-Data
-
-      The Type-Data field in the Request contains a displayable message
-      greater than zero octets in length.  The length of the message is
-      determined by the Length field of the Request packet.  The message
-      MUST NOT be null terminated.  A Response MUST be sent in reply to
-      the Request with a Type field of 6 (Generic Token Card).  The
-      Response contains data from the Token Card required for
-      authentication.  The length of the data is determined by the
-      Length field of the Response packet.
-
-      EAP GTC implementations MAY support entering a response with non-
-      ASCII characters.  See Section 5 for instructions how the input
-      should be processed and encoded into octets.
-
-   Security Claims (see Section 7.2):
-
-      Auth. mechanism:           Hardware token.
-      Ciphersuite negotiation:   No
-      Mutual authentication:     No
-      Integrity protection:      No
-      Replay protection:         No
-      Confidentiality:           No
-      Key derivation:            No
-      Key strength:              N/A
-      Dictionary attack prot.:   No
-      Fast reconnect:            No
-      Crypt. binding:            N/A
-      Session independence:      N/A
-      Fragmentation:             No
-      Channel binding:           No
-
-
-5.7.  Expanded Types
-
-   Description
-
-      Since many of the existing uses of EAP are vendor-specific, the
-      Expanded method Type is available to allow vendors to support
-      their own Expanded Types not suitable for general usage.
-
-
-
-Aboba, et al.               Standards Track                    [Page 38]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-      The Expanded Type is also used to expand the global Method Type
-      space beyond the original 255 values.  A Vendor-Id of 0 maps the
-      original 255 possible Types onto a space of 2^32-1 possible Types.
-      (Type 0 is only used in a Nak Response to indicate no acceptable
-      alternative).
-
-      An implementation that supports the Expanded attribute MUST treat
-      EAP Types that are less than 256 equivalently, whether they appear
-      as a single octet or as the 32-bit Vendor-Type within an Expanded
-      Type where Vendor-Id is 0.  Peers not equipped to interpret the
-      Expanded Type MUST send a Nak as described in Section 5.3.1, and
-      negotiate a more suitable authentication method.
-
-      A summary of the Expanded Type format is shown below.  The fields
-      are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Type      |               Vendor-Id                       |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |                          Vendor-Type                          |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |              Vendor data...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      254 for Expanded Type
-
-   Vendor-Id
-
-      The Vendor-Id is 3 octets and represents the SMI Network
-      Management Private Enterprise Code of the Vendor in network byte
-      order, as allocated by IANA.  A Vendor-Id of zero is reserved for
-      use by the IETF in providing an expanded global EAP Type space.
-
-   Vendor-Type
-
-      The Vendor-Type field is four octets and represents the vendor-
-      specific method Type.
-
-      If the Vendor-Id is zero, the Vendor-Type field is an extension
-      and superset of the existing namespace for EAP Types.  The first
-      256 Types are reserved for compatibility with single-octet EAP
-      Types that have already been assigned or may be assigned in the
-      future.  Thus, EAP Types from 0 through 255 are semantically
-      identical, whether they appear as single octet EAP Types or as
-
-
-
-Aboba, et al.               Standards Track                    [Page 39]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-      Vendor-Types when Vendor-Id is zero.  There is one exception to
-      this rule: Expanded Nak and Legacy Nak packets share the same
-      Type, but must be treated differently because they have a
-      different format.
-
-   Vendor-Data
-
-      The Vendor-Data field is defined by the vendor.  Where a Vendor-Id
-      of zero is present, the Vendor-Data field will be used for
-      transporting the contents of EAP methods of Types defined by the
-      IETF.
-
-5.8.  Experimental
-
-   Description
-
-      The Experimental Type has no fixed format or content.  It is
-      intended for use when experimenting with new EAP Types.  This Type
-      is intended for experimental and testing purposes.  No guarantee
-      is made for interoperability between peers using this Type, as
-      outlined in [RFC3692].
-
-   Type
-
-      255
-
-   Type-Data
-
-      Undefined
-
-6.  IANA Considerations
-
-   This section provides guidance to the Internet Assigned Numbers
-   Authority (IANA) regarding registration of values related to the EAP
-   protocol, in accordance with BCP 26, [RFC2434].
-
-   There are two name spaces in EAP that require registration: Packet
-   Codes and method Types.
-
-   EAP is not intended as a general-purpose protocol, and allocations
-   SHOULD NOT be made for purposes unrelated to authentication.
-
-   The following terms are used here with the meanings defined in BCP
-   26: "name space", "assigned value", "registration".
-
-   The following policies are used here with the meanings defined in BCP
-   26: "Private Use", "First Come First Served", "Expert Review",
-   "Specification Required", "IETF Consensus", "Standards Action".
-
-
-
-Aboba, et al.               Standards Track                    [Page 40]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   For registration requests where a Designated Expert should be
-   consulted, the responsible IESG area director should appoint the
-   Designated Expert.  The intention is that any allocation will be
-   accompanied by a published RFC.  But in order to allow for the
-   allocation of values prior to the RFC being approved for publication,
-   the Designated Expert can approve allocations once it seems clear
-   that an RFC will be published.  The Designated expert will post a
-   request to the EAP WG mailing list (or a successor designated by the
-   Area Director) for comment and review, including an Internet-Draft.
-   Before a period of 30 days has passed, the Designated Expert will
-   either approve or deny the registration request and publish a notice
-   of the decision to the EAP WG mailing list or its successor, as well
-   as informing IANA.  A denial notice must be justified by an
-   explanation, and in the cases where it is possible, concrete
-   suggestions on how the request can be modified so as to become
-   acceptable should be provided.
-
-6.1.  Packet Codes
-
-   Packet Codes have a range from 1 to 255, of which 1-4 have been
-   allocated.  Because a new Packet Code has considerable impact on
-   interoperability, a new Packet Code requires Standards Action, and
-   should be allocated starting at 5.
-
-6.2.  Method Types
-
-   The original EAP method Type space has a range from 1 to 255, and is
-   the scarcest resource in EAP, and thus must be allocated with care.
-   Method Types 1-45 have been allocated, with 20 available for re-use.
-   Method Types 20 and 46-191 may be allocated on the advice of a
-   Designated Expert, with Specification Required.
-
-   Allocation of blocks of method Types (more than one for a given
-   purpose) should require IETF Consensus.  EAP Type Values 192-253 are
-   reserved and allocation requires Standards Action.
-
-   Method Type 254 is allocated for the Expanded Type.  Where the
-   Vendor-Id field is non-zero, the Expanded Type is used for functions
-   specific only to one vendor's implementation of EAP, where no
-   interoperability is deemed useful.  When used with a Vendor-Id of
-   zero, method Type 254 can also be used to provide for an expanded
-   IETF method Type space.  Method Type values 256-4294967295 may be
-   allocated after Type values 1-191 have been allocated, on the advice
-   of a Designated Expert, with Specification Required.
-
-   Method Type 255 is allocated for Experimental use, such as testing of
-   new EAP methods before a permanent Type is allocated.
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 41]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-7.  Security Considerations
-
-   This section defines a generic threat model as well as the EAP method
-   security claims mitigating those threats.
-
-   It is expected that the generic threat model and corresponding
-   security claims will used to define EAP method requirements for use
-   in specific environments.  An example of such a requirements analysis
-   is provided in [IEEE-802.11i-req].  A security claims section is
-   required in EAP method specifications, so that EAP methods can be
-   evaluated against the requirements.
-
-7.1.  Threat Model
-
-   EAP was developed for use with PPP [RFC1661] and was later adapted
-   for use in wired IEEE 802 networks [IEEE-802] in [IEEE-802.1X].
-   Subsequently, EAP has been proposed for use on wireless LAN networks
-   and over the Internet.  In all these situations, it is possible for
-   an attacker to gain access to links over which EAP packets are
-   transmitted.  For example, attacks on telephone infrastructure are
-   documented in [DECEPTION].
-
-   An attacker with access to the link may carry out a number of
-   attacks, including:
-
-   [1]  An attacker may try to discover user identities by snooping
-        authentication traffic.
-
-   [2]  An attacker may try to modify or spoof EAP packets.
-
-   [3]  An attacker may launch denial of service attacks by spoofing
-        lower layer indications or Success/Failure packets, by replaying
-        EAP packets, or by generating packets with overlapping
-        Identifiers.
-
-   [4]  An attacker may attempt to recover the pass-phrase by mounting
-        an offline dictionary attack.
-
-   [5]  An attacker may attempt to convince the peer to connect to an
-        untrusted network by mounting a man-in-the-middle attack.
-
-   [6]  An attacker may attempt to disrupt the EAP negotiation in order
-        cause a weak authentication method to be selected.
-
-   [7]  An attacker may attempt to recover keys by taking advantage of
-        weak key derivation techniques used within EAP methods.
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 42]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [8]  An attacker may attempt to take advantage of weak ciphersuites
-        subsequently used after the EAP conversation is complete.
-
-   [9]  An attacker may attempt to perform downgrading attacks on lower
-        layer ciphersuite negotiation in order to ensure that a weaker
-        ciphersuite is used subsequently to EAP authentication.
-
-   [10] An attacker acting as an authenticator may provide incorrect
-        information to the EAP peer and/or server via out-of-band
-        mechanisms (such as via a AAA or lower layer protocol).  This
-        includes impersonating another authenticator, or providing
-        inconsistent information to the peer and EAP server.
-
-   Depending on the lower layer, these attacks may be carried out
-   without requiring physical proximity.  Where EAP is used over
-   wireless networks, EAP packets may be forwarded by authenticators
-   (e.g., pre-authentication) so that the attacker need not be within
-   the coverage area of an authenticator in order to carry out an attack
-   on it or its peers.  Where EAP is used over the Internet, attacks may
-   be carried out at an even greater distance.
-
-7.2.  Security Claims
-
-   In order to clearly articulate the security provided by an EAP
-   method, EAP method specifications MUST include a Security Claims
-   section, including the following declarations:
-
-   [a] Mechanism.  This is a statement of the authentication technology:
-       certificates, pre-shared keys, passwords, token cards, etc.
-
-   [b] Security claims.  This is a statement of the claimed security
-       properties of the method, using terms defined in Section 7.2.1:
-       mutual authentication, integrity protection, replay protection,
-       confidentiality, key derivation, dictionary attack resistance,
-       fast reconnect, cryptographic binding.  The Security Claims
-       section of an EAP method specification SHOULD provide
-       justification for the claims that are made.  This can be
-       accomplished by including a proof in an Appendix, or including a
-       reference to a proof.
-
-   [c] Key strength.  If the method derives keys, then the effective key
-       strength MUST be estimated.  This estimate is meant for potential
-       users of the method to determine if the keys produced are strong
-       enough for the intended application.
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 43]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-       The effective key strength SHOULD be stated as a number of bits,
-       defined as follows: If the effective key strength is N bits, the
-       best currently known methods to recover the key (with non-
-       negligible probability) require, on average, an effort comparable
-       to 2^(N-1) operations of a typical block cipher.  The statement
-       SHOULD be accompanied by a short rationale, explaining how this
-       number was derived.  This explanation SHOULD include the
-       parameters required to achieve the stated key strength based on
-       current knowledge of the algorithms.
-
-       (Note: Although it is difficult to define what "comparable
-       effort" and "typical block cipher" exactly mean, reasonable
-       approximations are sufficient here.  Refer to e.g. [SILVERMAN]
-       for more discussion.)
-
-       The key strength depends on the methods used to derive the keys.
-       For instance, if keys are derived from a shared secret (such as a
-       password or a long-term secret), and possibly some public
-       information such as nonces, the effective key strength is limited
-       by the strength of the long-term secret (assuming that the
-       derivation procedure is computationally simple).  To take another
-       example, when using public key algorithms, the strength of the
-       symmetric key depends on the strength of the public keys used.
-
-   [d] Description of key hierarchy.  EAP methods deriving keys MUST
-       either provide a reference to a key hierarchy specification, or
-       describe how Master Session Keys (MSKs) and Extended Master
-       Session Keys (EMSKs) are to be derived.
-
-   [e] Indication of vulnerabilities.  In addition to the security
-       claims that are made, the specification MUST indicate which of
-       the security claims detailed in Section 7.2.1 are NOT being made.
-
-7.2.1.  Security Claims Terminology for EAP Methods
-
-   These terms are used to describe the security properties of EAP
-   methods:
-
-   Protected ciphersuite negotiation
-      This refers to the ability of an EAP method to negotiate the
-      ciphersuite used to protect the EAP conversation, as well as to
-      integrity protect the negotiation.  It does not refer to the
-      ability to negotiate the ciphersuite used to protect data.
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 44]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Mutual authentication
-      This refers to an EAP method in which, within an interlocked
-      exchange, the authenticator authenticates the peer and the peer
-      authenticates the authenticator.  Two independent one-way methods,
-      running in opposite directions do not provide mutual
-      authentication as defined here.
-
-   Integrity protection
-      This refers to providing data origin authentication and protection
-      against unauthorized modification of information for EAP packets
-      (including EAP Requests and Responses).  When making this claim, a
-      method specification MUST describe the EAP packets and fields
-      within the EAP packet that are protected.
-
-   Replay protection
-      This refers to protection against replay of an EAP method or its
-      messages, including success and failure result indications.
-
-   Confidentiality
-      This refers to encryption of EAP messages, including EAP Requests
-      and Responses, and success and failure result indications.  A
-      method making this claim MUST support identity protection (see
-      Section 7.3).
-
-   Key derivation
-      This refers to the ability of the EAP method to derive exportable
-      keying material, such as the Master Session Key (MSK), and
-      Extended Master Session Key (EMSK).  The MSK is used only for
-      further key derivation, not directly for protection of the EAP
-      conversation or subsequent data.  Use of the EMSK is reserved.
-
-   Key strength
-      If the effective key strength is N bits, the best currently known
-      methods to recover the key (with non-negligible probability)
-      require, on average, an effort comparable to 2^(N-1) operations of
-      a typical block cipher.
-
-   Dictionary attack resistance
-      Where password authentication is used, passwords are commonly
-      selected from a small set (as compared to a set of N-bit keys),
-      which raises a concern about dictionary attacks.  A method may be
-      said to provide protection against dictionary attacks if, when it
-      uses a password as a secret, the method does not allow an offline
-      attack that has a work factor based on the number of passwords in
-      an attacker's dictionary.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 45]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Fast reconnect
-      The ability, in the case where a security association has been
-      previously established, to create a new or refreshed security
-      association more efficiently or in a smaller number of round-
-      trips.
-
-   Cryptographic binding
-      The demonstration of the EAP peer to the EAP server that a single
-      entity has acted as the EAP peer for all methods executed within a
-      tunnel method.  Binding MAY also imply that the EAP server
-      demonstrates to the peer that a single entity has acted as the EAP
-      server for all methods executed within a tunnel method.  If
-      executed correctly, binding serves to mitigate man-in-the-middle
-      vulnerabilities.
-
-   Session independence
-      The demonstration that passive attacks (such as capture of the EAP
-      conversation) or active attacks (including compromise of the MSK
-      or EMSK) does not enable compromise of subsequent or prior MSKs or
-      EMSKs.
-
-   Fragmentation
-      This refers to whether an EAP method supports fragmentation and
-      reassembly.  As noted in Section 3.1, EAP methods should support
-      fragmentation and reassembly if EAP packets can exceed the minimum
-      MTU of 1020 octets.
-
-   Channel binding
-      The communication within an EAP method of integrity-protected
-      channel properties such as endpoint identifiers which can be
-      compared to values communicated via out of band mechanisms (such
-      as via a AAA or lower layer protocol).
-
-   Note: This list of security claims is not exhaustive.  Additional
-   properties, such as additional denial-of-service protection, may be
-   relevant as well.
-
-7.3.  Identity Protection
-
-   An Identity exchange is optional within the EAP conversation.
-   Therefore, it is possible to omit the Identity exchange entirely, or
-   to use a method-specific identity exchange once a protected channel
-   has been established.
-
-   However, where roaming is supported as described in [RFC2607], it may
-   be necessary to locate the appropriate backend authentication server
-   before the authentication conversation can proceed.  The realm
-   portion of the Network Access Identifier (NAI) [RFC2486] is typically
-
-
-
-Aboba, et al.               Standards Track                    [Page 46]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   included within the EAP-Response/Identity in order to enable the
-   authentication exchange to be routed to the appropriate backend
-   authentication server.  Therefore, while the peer-name portion of the
-   NAI may be omitted in the EAP-Response/Identity where proxies or
-   relays are present, the realm portion may be required.
-
-   It is possible for the identity in the identity response to be
-   different from the identity authenticated by the EAP method.  This
-   may be intentional in the case of identity privacy.  An EAP method
-   SHOULD use the authenticated identity when making access control
-   decisions.
-
-7.4.  Man-in-the-Middle Attacks
-
-   Where EAP is tunneled within another protocol that omits peer
-   authentication, there exists a potential vulnerability to a man-in-
-   the-middle attack.  For details, see [BINDING] and [MITM].
-
-   As noted in Section 2.1, EAP does not permit untunneled sequences of
-   authentication methods.  Were a sequence of EAP authentication
-   methods to be permitted, the peer might not have proof that a single
-   entity has acted as the authenticator for all EAP methods within the
-   sequence.  For example, an authenticator might terminate one EAP
-   method, then forward the next method in the sequence to another party
-   without the peer's knowledge or consent.  Similarly, the
-   authenticator might not have proof that a single entity has acted as
-   the peer for all EAP methods within the sequence.
-
-   Tunneling EAP within another protocol enables an attack by a rogue
-   EAP authenticator tunneling EAP to a legitimate server.  Where the
-   tunneling protocol is used for key establishment but does not require
-   peer authentication, an attacker convincing a legitimate peer to
-   connect to it will be able to tunnel EAP packets to a legitimate
-   server, successfully authenticating and obtaining the key.  This
-   allows the attacker to successfully establish itself as a man-in-
-   the-middle, gaining access to the network, as well as the ability to
-   decrypt data traffic between the legitimate peer and server.
-
-   This attack may be mitigated by the following measures:
-
-   [a] Requiring mutual authentication within EAP tunneling mechanisms.
-
-   [b] Requiring cryptographic binding between the EAP tunneling
-       protocol and the tunneled EAP methods.  Where cryptographic
-       binding is supported, a mechanism is also needed to protect
-       against downgrade attacks that would bypass it.  For further
-       details on cryptographic binding, see [BINDING].
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 47]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [c] Limiting the EAP methods authorized for use without protection,
-       based on peer and authenticator policy.
-
-   [d] Avoiding the use of tunnels when a single, strong method is
-       available.
-
-7.5.  Packet Modification Attacks
-
-   While EAP methods may support per-packet data origin authentication,
-   integrity, and replay protection, support is not provided within the
-   EAP layer.
-
-   Since the Identifier is only a single octet, it is easy to guess,
-   allowing an attacker to successfully inject or replay EAP packets.
-   An attacker may also modify EAP headers (Code, Identifier, Length,
-   Type) within EAP packets where the header is unprotected.  This could
-   cause packets to be inappropriately discarded or misinterpreted.
-
-   To protect EAP packets against modification, spoofing, or replay,
-   methods supporting protected ciphersuite negotiation, mutual
-   authentication, and key derivation, as well as integrity and replay
-   protection, are recommended.  See Section 7.2.1 for definitions of
-   these security claims.
-
-   Method-specific MICs may be used to provide protection.  If a per-
-   packet MIC is employed within an EAP method, then peers,
-   authentication servers, and authenticators not operating in pass-
-   through mode MUST validate the MIC.  MIC validation failures SHOULD
-   be logged.  Whether a MIC validation failure is considered a fatal
-   error or not is determined by the EAP method specification.
-
-   It is RECOMMENDED that methods providing integrity protection of EAP
-   packets include coverage of all the EAP header fields, including the
-   Code, Identifier, Length, Type, and Type-Data fields.
-
-   Since EAP messages of Types Identity, Notification, and Nak do not
-   include their own MIC, it may be desirable for the EAP method MIC to
-   cover information contained within these messages, as well as the
-   header of each EAP message.
-
-   To provide protection, EAP also may be encapsulated within a
-   protected channel created by protocols such as ISAKMP [RFC2408], as
-   is done in [IKEv2] or within TLS [RFC2246].  However, as noted in
-   Section 7.4, EAP tunneling may result in a man-in-the-middle
-   vulnerability.
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 48]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   Existing EAP methods define message integrity checks (MICs) that
-   cover more than one EAP packet.  For example, EAP-TLS [RFC2716]
-   defines a MIC over a TLS record that could be split into multiple
-   fragments; within the FINISHED message, the MIC is computed over
-   previous messages.  Where the MIC covers more than one EAP packet, a
-   MIC validation failure is typically considered a fatal error.
-
-   Within EAP-TLS [RFC2716], a MIC validation failure is treated as a
-   fatal error, since that is what is specified in TLS [RFC2246].
-   However, it is also possible to develop EAP methods that support
-   per-packet MICs, and respond to verification failures by silently
-   discarding the offending packet.
-
-   In this document, descriptions of EAP message handling assume that
-   per-packet MIC validation, where it occurs, is effectively performed
-   as though it occurs before sending any responses or changing the
-   state of the host which received the packet.
-
-7.6.  Dictionary Attacks
-
-   Password authentication algorithms such as EAP-MD5, MS-CHAPv1
-   [RFC2433], and Kerberos V [RFC1510] are known to be vulnerable to
-   dictionary attacks.  MS-CHAPv1 vulnerabilities are documented in
-   [PPTPv1]; MS-CHAPv2 vulnerabilities are documented in [PPTPv2];
-   Kerberos vulnerabilities are described in [KRBATTACK], [KRBLIM], and
-   [KERB4WEAK].
-
-   In order to protect against dictionary attacks, authentication
-   methods resistant to dictionary attacks (as defined in Section 7.2.1)
-   are recommended.
-
-   If an authentication algorithm is used that is known to be vulnerable
-   to dictionary attacks, then the conversation may be tunneled within a
-   protected channel in order to provide additional protection.
-   However, as noted in Section 7.4, EAP tunneling may result in a man-
-   in-the-middle vulnerability, and therefore dictionary attack
-   resistant methods are preferred.
-
-7.7.  Connection to an Untrusted Network
-
-   With EAP methods supporting one-way authentication, such as EAP-MD5,
-   the peer does not authenticate the authenticator, making the peer
-   vulnerable to attack by a rogue authenticator.  Methods supporting
-   mutual authentication (as defined in Section 7.2.1) address this
-   vulnerability.
-
-   In EAP there is no requirement that authentication be full duplex or
-   that the same protocol be used in both directions.  It is perfectly
-
-
-
-Aboba, et al.               Standards Track                    [Page 49]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   acceptable for different protocols to be used in each direction.
-   This will, of course, depend on the specific protocols negotiated.
-   However, in general, completing a single unitary mutual
-   authentication is preferable to two one-way authentications, one in
-   each direction.  This is because separate authentications that are
-   not bound cryptographically so as to demonstrate they are part of the
-   same session are subject to man-in-the-middle attacks, as discussed
-   in Section 7.4.
-
-7.8.  Negotiation Attacks
-
-   In a negotiation attack, the attacker attempts to convince the peer
-   and authenticator to negotiate a less secure EAP method.  EAP does
-   not provide protection for Nak Response packets, although it is
-   possible for a method to include coverage of Nak Responses within a
-   method-specific MIC.
-
-   Within or associated with each authenticator, it is not anticipated
-   that a particular named peer will support a choice of methods.  This
-   would make the peer vulnerable to attacks that negotiate the least
-   secure method from among a set.  Instead, for each named peer, there
-   SHOULD be an indication of exactly one method used to authenticate
-   that peer name.  If a peer needs to make use of different
-   authentication methods under different circumstances, then distinct
-   identities SHOULD be employed, each of which identifies exactly one
-   authentication method.
-
-7.9.  Implementation Idiosyncrasies
-
-   The interaction of EAP with lower layers such as PPP and IEEE 802 are
-   highly implementation dependent.
-
-   For example, upon failure of authentication, some PPP implementations
-   do not terminate the link, instead limiting traffic in Network-Layer
-   Protocols to a filtered subset, which in turn allows the peer the
-   opportunity to update secrets or send mail to the network
-   administrator indicating a problem.  Similarly, while an
-   authentication failure will result in denied access to the controlled
-   port in [IEEE-802.1X], limited traffic may be permitted on the
-   uncontrolled port.
-
-   In EAP there is no provision for retries of failed authentication.
-   However, in PPP the LCP state machine can renegotiate the
-   authentication protocol at any time, thus allowing a new attempt.
-   Similarly, in IEEE 802.1X the Supplicant or Authenticator can re-
-   authenticate at any time.  It is recommended that any counters used
-   for authentication failure not be reset until after successful
-   authentication, or subsequent termination of the failed link.
-
-
-
-Aboba, et al.               Standards Track                    [Page 50]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-7.10.  Key Derivation
-
-   It is possible for the peer and EAP server to mutually authenticate
-   and derive keys.  In order to provide keying material for use in a
-   subsequently negotiated ciphersuite, an EAP method supporting key
-   derivation MUST export a Master Session Key (MSK) of at least 64
-   octets, and an Extended Master Session Key (EMSK) of at least 64
-   octets.  EAP Methods deriving keys MUST provide for mutual
-   authentication between the EAP peer and the EAP Server.
-
-   The MSK and EMSK MUST NOT be used directly to protect data; however,
-   they are of sufficient size to enable derivation of a AAA-Key
-   subsequently used to derive Transient Session Keys (TSKs) for use
-   with the selected ciphersuite.  Each ciphersuite is responsible for
-   specifying how to derive the TSKs from the AAA-Key.
-
-   The AAA-Key is derived from the keying material exported by the EAP
-   method (MSK and EMSK).  This derivation occurs on the AAA server.  In
-   many existing protocols that use EAP, the AAA-Key and MSK are
-   equivalent, but more complicated mechanisms are possible (see
-   [KEYFRAME] for details).
-
-   EAP methods SHOULD ensure the freshness of the MSK and EMSK, even in
-   cases where one party may not have a high quality random number
-   generator.  A RECOMMENDED method is for each party to provide a nonce
-   of at least 128 bits, used in the derivation of the MSK and EMSK.
-
-   EAP methods export the MSK and EMSK, but not Transient Session Keys
-   so as to allow EAP methods to be ciphersuite and media independent.
-   Keying material exported by EAP methods MUST be independent of the
-   ciphersuite negotiated to protect data.
-
-   Depending on the lower layer, EAP methods may run before or after
-   ciphersuite negotiation, so that the selected ciphersuite may not be
-   known to the EAP method.  By providing keying material usable with
-   any ciphersuite, EAP methods can used with a wide range of
-   ciphersuites and media.
-
-   In order to preserve algorithm independence, EAP methods deriving
-   keys SHOULD support (and document) the protected negotiation of the
-   ciphersuite used to protect the EAP conversation between the peer and
-   server.  This is distinct from the ciphersuite negotiated between the
-   peer and authenticator, used to protect data.
-
-   The strength of Transient Session Keys (TSKs) used to protect data is
-   ultimately dependent on the strength of keys generated by the EAP
-   method.  If an EAP method cannot produce keying material of
-   sufficient strength, then the TSKs may be subject to a brute force
-
-
-
-Aboba, et al.               Standards Track                    [Page 51]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   attack.  In order to enable deployments requiring strong keys, EAP
-   methods supporting key derivation SHOULD be capable of generating an
-   MSK and EMSK, each with an effective key strength of at least 128
-   bits.
-
-   Methods supporting key derivation MUST demonstrate cryptographic
-   separation between the MSK and EMSK branches of the EAP key
-   hierarchy.  Without violating a fundamental cryptographic assumption
-   (such as the non-invertibility of a one-way function), an attacker
-   recovering the MSK or EMSK MUST NOT be able to recover the other
-   quantity with a level of effort less than brute force.
-
-   Non-overlapping substrings of the MSK MUST be cryptographically
-   separate from each other, as defined in Section 7.2.1.  That is,
-   knowledge of one substring MUST NOT help in recovering some other
-   substring without breaking some hard cryptographic assumption.  This
-   is required because some existing ciphersuites form TSKs by simply
-   splitting the AAA-Key to pieces of appropriate length.  Likewise,
-   non-overlapping substrings of the EMSK MUST be cryptographically
-   separate from each other, and from substrings of the MSK.
-
-   The EMSK is reserved for future use and MUST remain on the EAP peer
-   and EAP server where it is derived; it MUST NOT be transported to, or
-   shared with, additional parties, or used to derive any other keys.
-   (This restriction will be relaxed in a future document that specifies
-   how the EMSK can be used.)
-
-   Since EAP does not provide for explicit key lifetime negotiation, EAP
-   peers, authenticators, and authentication servers MUST be prepared
-   for situations in which one of the parties discards the key state,
-   which remains valid on another party.
-
-   This specification does not provide detailed guidance on how EAP
-   methods derive the MSK and EMSK, how the AAA-Key is derived from the
-   MSK and/or EMSK, or how the TSKs are derived from the AAA-Key.
-
-   The development and validation of key derivation algorithms is
-   difficult, and as a result, EAP methods SHOULD re-use well
-   established and analyzed mechanisms for key derivation (such as those
-   specified in IKE [RFC2409] or TLS [RFC2246]), rather than inventing
-   new ones. EAP methods SHOULD also utilize well established and
-   analyzed mechanisms for MSK and EMSK derivation.  Further details on
-   EAP Key Derivation are provided within [KEYFRAME].
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 52]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-7.11.  Weak Ciphersuites
-
-   If after the initial EAP authentication, data packets are sent
-   without per-packet authentication, integrity, and replay protection,
-   an attacker with access to the media can inject packets, "flip bits"
-   within existing packets, replay packets, or even hijack the session
-   completely.  Without per-packet confidentiality, it is possible to
-   snoop data packets.
-
-   To protect against data modification, spoofing, or snooping, it is
-   recommended that EAP methods supporting mutual authentication and key
-   derivation (as defined by Section 7.2.1) be used, along with lower
-   layers providing per-packet confidentiality, authentication,
-   integrity, and replay protection.
-
-   Additionally, if the lower layer performs ciphersuite negotiation, it
-   should be understood that EAP does not provide by itself integrity
-   protection of that negotiation.  Therefore, in order to avoid
-   downgrading attacks which would lead to weaker ciphersuites being
-   used, clients implementing lower layer ciphersuite negotiation SHOULD
-   protect against negotiation downgrading.
-
-   This can be done by enabling users to configure which ciphersuites
-   are acceptable as a matter of security policy, or the ciphersuite
-   negotiation MAY be authenticated using keying material derived from
-   the EAP authentication and a MIC algorithm agreed upon in advance by
-   lower-layer peers.
-
-7.12.  Link Layer
-
-   There are reliability and security issues with link layer indications
-   in PPP, IEEE 802 LANs, and IEEE 802.11 wireless LANs:
-
-   [a] PPP.  In PPP, link layer indications such as LCP-Terminate (a
-       link failure indication) and NCP (a link success indication) are
-       not authenticated or integrity protected.  They can therefore be
-       spoofed by an attacker with access to the link.
-
-   [b] IEEE 802.  IEEE 802.1X EAPOL-Start and EAPOL-Logoff frames are
-       not authenticated or integrity protected.  They can therefore be
-       spoofed by an attacker with access to the link.
-
-   [c] IEEE 802.11.  In IEEE 802.11, link layer indications include
-       Disassociate and Deauthenticate frames (link failure
-       indications), and the first message of the 4-way handshake (link
-       success indication).  These messages are not authenticated or
-       integrity protected, and although they are not forwardable, they
-       are spoofable by an attacker within range.
-
-
-
-Aboba, et al.               Standards Track                    [Page 53]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   In IEEE 802.11, IEEE 802.1X data frames may be sent as Class 3
-   unicast data frames, and are therefore forwardable.  This implies
-   that while EAPOL-Start and EAPOL-Logoff messages may be authenticated
-   and integrity protected, they can be spoofed by an authenticated
-   attacker far from the target when "pre-authentication" is enabled.
-
-   In IEEE 802.11, a "link down" indication is an unreliable indication
-   of link failure, since wireless signal strength can come and go and
-   may be influenced by radio frequency interference generated by an
-   attacker.  To avoid unnecessary resets, it is advisable to damp these
-   indications, rather than passing them directly to the EAP.  Since EAP
-   supports retransmission, it is robust against transient connectivity
-   losses.
-
-7.13.  Separation of Authenticator and Backend Authentication Server
-
-   It is possible for the EAP peer and EAP server to mutually
-   authenticate and derive a AAA-Key for a ciphersuite used to protect
-   subsequent data traffic.  This does not present an issue on the peer,
-   since the peer and EAP client reside on the same machine; all that is
-   required is for the client to derive the AAA-Key from the MSK and
-   EMSK exported by the EAP method, and to subsequently pass a Transient
-   Session Key (TSK) to the ciphersuite module.
-
-   However, in the case where the authenticator and authentication
-   server reside on different machines, there are several implications
-   for security.
-
-   [a] Authentication will occur between the peer and the authentication
-       server, not between the peer and the authenticator.  This means
-       that it is not possible for the peer to validate the identity of
-       the authenticator that it is speaking to, using EAP alone.
-
-   [b] As discussed in [RFC3579], the authenticator is dependent on the
-       AAA protocol in order to know the outcome of an authentication
-       conversation, and does not look at the encapsulated EAP packet
-       (if one is present) to determine the outcome.  In practice, this
-       implies that the AAA protocol spoken between the authenticator
-       and authentication server MUST support per-packet authentication,
-       integrity, and replay protection.
-
-   [c] After completion of the EAP conversation, where lower layer
-       security services such as per-packet confidentiality,
-       authentication, integrity, and replay protection will be enabled,
-       a secure association protocol SHOULD be run between the peer and
-       authenticator in order to provide mutual authentication between
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 54]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-       the peer and authenticator, guarantee liveness of transient
-       session keys, provide protected ciphersuite and capabilities
-       negotiation for subsequent data, and synchronize key usage.
-
-   [d] A AAA-Key derived from the MSK and/or EMSK negotiated between the
-       peer and authentication server MAY be transmitted to the
-       authenticator.  Therefore, a mechanism needs to be provided to
-       transmit the AAA-Key from the authentication server to the
-       authenticator that needs it.  The specification of the AAA-key
-       derivation, transport, and wrapping mechanisms is outside the
-       scope of this document.  Further details on AAA-Key Derivation
-       are provided within [KEYFRAME].
-
-7.14.  Cleartext Passwords
-
-   This specification does not define a mechanism for cleartext password
-   authentication.  The omission is intentional.  Use of cleartext
-   passwords would allow the password to be captured by an attacker with
-   access to a link over which EAP packets are transmitted.
-
-   Since protocols encapsulating EAP, such as RADIUS [RFC3579], may not
-   provide confidentiality, EAP packets may be subsequently encapsulated
-   for transport over the Internet where they may be captured by an
-   attacker.
-
-   As a result, cleartext passwords cannot be securely used within EAP,
-   except where encapsulated within a protected tunnel with server
-   authentication.  Some of the same risks apply to EAP methods without
-   dictionary attack resistance, as defined in Section 7.2.1.  For
-   details, see Section 7.6.
-
-7.15.  Channel Binding
-
-   It is possible for a compromised or poorly implemented EAP
-   authenticator to communicate incorrect information to the EAP peer
-   and/or server.  This may enable an authenticator to impersonate
-   another authenticator or communicate incorrect information via out-
-   of-band mechanisms (such as via a AAA or lower layer protocol).
-
-   Where EAP is used in pass-through mode, the EAP peer typically does
-   not verify the identity of the pass-through authenticator, it only
-   verifies that the pass-through authenticator is trusted by the EAP
-   server.  This creates a potential security vulnerability.
-
-   Section 4.3.7 of [RFC3579] describes how an EAP pass-through
-   authenticator acting as a AAA client can be detected if it attempts
-   to impersonate another authenticator (such by sending incorrect NAS-
-   Identifier [RFC2865], NAS-IP-Address [RFC2865] or NAS-IPv6-Address
-
-
-
-Aboba, et al.               Standards Track                    [Page 55]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [RFC3162] attributes via the AAA protocol).  However, it is possible
-   for a pass-through authenticator acting as a AAA client to provide
-   correct information to the AAA server while communicating misleading
-   information to the EAP peer via a lower layer protocol.
-
-   For example, it is possible for a compromised authenticator to
-   utilize another authenticator's Called-Station-Id or NAS-Identifier
-   in communicating with the EAP peer via a lower layer protocol, or for
-   a pass-through authenticator acting as a AAA client to provide an
-   incorrect peer Calling-Station-Id [RFC2865][RFC3580] to the AAA
-   server via the AAA protocol.
-
-   In order to address this vulnerability, EAP methods may support a
-   protected exchange of channel properties such as endpoint
-   identifiers, including (but not limited to): Called-Station-Id
-   [RFC2865][RFC3580], Calling-Station-Id [RFC2865][RFC3580], NAS-
-   Identifier [RFC2865], NAS-IP-Address [RFC2865], and NAS-IPv6-Address
-   [RFC3162].
-
-   Using such a protected exchange, it is possible to match the channel
-   properties provided by the authenticator via out-of-band mechanisms
-   against those exchanged within the EAP method.  Where discrepancies
-   are found, these SHOULD be logged; additional actions MAY also be
-   taken, such as denying access.
-
-7.16.  Protected Result Indications
-
-   Within EAP, Success and Failure packets are neither acknowledged nor
-   integrity protected.  Result indications improve resilience to loss
-   of Success and Failure packets when EAP is run over lower layers
-   which do not support retransmission or synchronization of the
-   authentication state.  In media such as IEEE 802.11, which provides
-   for retransmission, as well as synchronization of authentication
-   state via the 4-way handshake defined in [IEEE-802.11i], additional
-   resilience is typically of marginal benefit.
-
-   Depending on the method and circumstances, result indications can be
-   spoofable by an attacker.  A method is said to provide protected
-   result indications if it supports result indications, as well as the
-   "integrity protection" and "replay protection" claims.  A method
-   supporting protected result indications MUST indicate which result
-   indications are protected, and which are not.
-
-   Protected result indications are not required to protect against
-   rogue authenticators.  Within a mutually authenticating method,
-   requiring that the server authenticate to the peer before the peer
-   will accept a Success packet prevents an attacker from acting as a
-   rogue authenticator.
-
-
-
-Aboba, et al.               Standards Track                    [Page 56]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   However, it is possible for an attacker to forge a Success packet
-   after the server has authenticated to the peer, but before the peer
-   has authenticated to the server.  If the peer were to accept the
-   forged Success packet and attempt to access the network when it had
-   not yet successfully authenticated to the server, a denial of service
-   attack could be mounted against the peer.  After such an attack, if
-   the lower layer supports failure indications, the authenticator can
-   synchronize state with the peer by providing a lower layer failure
-   indication.  See Section 7.12 for details.
-
-   If a server were to authenticate the peer and send a Success packet
-   prior to determining whether the peer has authenticated the
-   authenticator, an idle timeout can occur if the authenticator is not
-   authenticated by the peer.  Where supported by the lower layer, an
-   authenticator sensing the absence of the peer can free resources.
-
-   In a method supporting result indications, a peer that has
-   authenticated the server does not consider the authentication
-   successful until it receives an indication that the server
-   successfully authenticated it.  Similarly, a server that has
-   successfully authenticated the peer does not consider the
-   authentication successful until it receives an indication that the
-   peer has authenticated the server.
-
-   In order to avoid synchronization problems, prior to sending a
-   success result indication, it is desirable for the sender to verify
-   that sufficient authorization exists for granting access, though, as
-   discussed below, this is not always possible.
-
-   While result indications may enable synchronization of the
-   authentication result between the peer and server, this does not
-   guarantee that the peer and authenticator will be synchronized in
-   terms of their authorization or that timeouts will not occur.  For
-   example, the EAP server may not be aware of an authorization decision
-   made by a AAA proxy; the AAA server may check authorization only
-   after authentication has completed successfully, to discover that
-   authorization cannot be granted, or the AAA server may grant access
-   but the authenticator may be unable to provide it due to a temporary
-   lack of resources.  In these situations, synchronization may only be
-   achieved via lower layer result indications.
-
-   Success indications may be explicit or implicit.  For example, where
-   a method supports error messages, an implicit success indication may
-   be defined as the reception of a specific message without a preceding
-   error message.  Failures are typically indicated explicitly.  As
-   described in Section 4.2, a peer silently discards a Failure packet
-   received at a point where the method does not explicitly permit this
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 57]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   to be sent.  For example, a method providing its own error messages
-   might require the peer to receive an error message prior to accepting
-   a Failure packet.
-
-   Per-packet authentication, integrity, and replay protection of result
-   indications protects against spoofing.  Since protected result
-   indications require use of a key for per-packet authentication and
-   integrity protection, methods supporting protected result indications
-   MUST also support the "key derivation", "mutual authentication",
-   "integrity protection", and "replay protection" claims.
-
-   Protected result indications address some denial-of-service
-   vulnerabilities due to spoofing of Success and Failure packets,
-   though not all.  EAP methods can typically provide protected result
-   indications only in some circumstances.  For example, errors can
-   occur prior to key derivation, and so it may not be possible to
-   protect all failure indications.  It is also possible that result
-   indications may not be supported in both directions or that
-   synchronization may not be achieved in all modes of operation.
-
-   For example, within EAP-TLS [RFC2716], in the client authentication
-   handshake, the server authenticates the peer, but does not receive a
-   protected indication of whether the peer has authenticated it.  In
-   contrast, the peer authenticates the server and is aware of whether
-   the server has authenticated it.  In the session resumption
-   handshake, the peer authenticates the server, but does not receive a
-   protected indication of whether the server has authenticated it.  In
-   this mode, the server authenticates the peer and is aware of whether
-   the peer has authenticated it.
-
-8.  Acknowledgements
-
-   This protocol derives much of its inspiration from Dave Carrel's AHA
-   document, as well as the PPP CHAP protocol [RFC1994].  Valuable
-   feedback was provided by Yoshihiro Ohba of Toshiba America Research,
-   Jari Arkko of Ericsson, Sachin Seth of Microsoft, Glen Zorn of Cisco
-   Systems, Jesse Walker of Intel, Bill Arbaugh, Nick Petroni and Bryan
-   Payne of the University of Maryland, Steve Bellovin of AT&T Research,
-   Paul Funk of Funk Software, Pasi Eronen of Nokia, Joseph Salowey of
-   Cisco, Paul Congdon of HP, and members of the EAP working group.
-
-   The use of Security Claims sections for EAP methods, as required by
-   Section 7.2 and specified for each EAP method described in this
-   document, was inspired by Glen Zorn through [EAP-EVAL].
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 58]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-9.  References
-
-9.1.  Normative References
-
-   [RFC1661]          Simpson, W., "The Point-to-Point Protocol (PPP)",
-                      STD 51, RFC 1661, July 1994.
-
-   [RFC1994]          Simpson, W., "PPP Challenge Handshake
-                      Authentication Protocol (CHAP)", RFC 1994, August
-                      1996.
-
-   [RFC2119]          Bradner, S., "Key words for use in RFCs to
-                      Indicate Requirement Levels", BCP 14, RFC 2119,
-                      March 1997.
-
-   [RFC2243]          Metz, C., "OTP Extended Responses", RFC 2243,
-                      November 1997.
-
-   [RFC2279]          Yergeau, F., "UTF-8, a transformation format of
-                      ISO 10646", RFC 2279, January 1998.
-
-   [RFC2289]          Haller, N., Metz, C., Nesser, P. and M. Straw, "A
-                      One-Time Password System", RFC 2289, February
-                      1998.
-
-   [RFC2434]          Narten, T. and H. Alvestrand, "Guidelines for
-                      Writing an IANA Considerations Section in RFCs",
-                      BCP 26, RFC 2434, October 1998.
-
-   [RFC2988]          Paxson, V. and M. Allman, "Computing TCP's
-                      Retransmission Timer", RFC 2988, November 2000.
-
-   [IEEE-802]         Institute of Electrical and Electronics Engineers,
-                      "Local and Metropolitan Area Networks: Overview
-                      and Architecture", IEEE Standard 802, 1990.
-
-   [IEEE-802.1X]      Institute of Electrical and Electronics Engineers,
-                      "Local and Metropolitan Area Networks: Port-Based
-                      Network Access Control", IEEE Standard 802.1X,
-                      September 2001.
-
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 59]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-9.2.  Informative References
-
-   [RFC793]           Postel, J., "Transmission Control Protocol", STD
-                      7, RFC 793, September 1981.
-
-   [RFC1510]          Kohl, J. and B. Neuman, "The Kerberos Network
-                      Authentication Service (V5)", RFC 1510, September
-                      1993.
-
-   [RFC1750]          Eastlake, D., Crocker, S. and J. Schiller,
-                      "Randomness Recommendations for Security", RFC
-                      1750, December 1994.
-
-   [RFC2246]          Dierks, T., Allen, C., Treese, W., Karlton, P.,
-                      Freier, A. and P. Kocher, "The TLS Protocol
-                      Version 1.0", RFC 2246, January 1999.
-
-   [RFC2284]          Blunk, L. and J. Vollbrecht, "PPP Extensible
-                      Authentication Protocol (EAP)", RFC 2284, March
-                      1998.
-
-   [RFC2486]          Aboba, B. and M. Beadles, "The Network Access
-                      Identifier", RFC 2486, January 1999.
-
-   [RFC2408]          Maughan, D., Schneider, M. and M. Schertler,
-                      "Internet Security Association and Key Management
-                      Protocol (ISAKMP)", RFC 2408, November 1998.
-
-   [RFC2409]          Harkins, D. and D. Carrel, "The Internet Key
-                      Exchange (IKE)", RFC 2409, November 1998.
-
-   [RFC2433]          Zorn, G. and S. Cobb, "Microsoft PPP CHAP
-                      Extensions", RFC 2433, October 1998.
-
-   [RFC2607]          Aboba, B. and J. Vollbrecht, "Proxy Chaining and
-                      Policy Implementation in Roaming", RFC 2607, June
-                      1999.
-
-   [RFC2661]          Townsley, W., Valencia, A., Rubens, A., Pall, G.,
-                      Zorn, G. and B. Palter, "Layer Two Tunneling
-                      Protocol "L2TP"", RFC 2661, August 1999.
-
-   [RFC2716]          Aboba, B. and D. Simon, "PPP EAP TLS
-                      Authentication Protocol", RFC 2716, October 1999.
-
-   [RFC2865]          Rigney, C., Willens, S., Rubens, A. and W.
-                      Simpson, "Remote Authentication Dial In User
-                      Service (RADIUS)", RFC 2865, June 2000.
-
-
-
-Aboba, et al.               Standards Track                    [Page 60]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [RFC2960]          Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
-                      Schwarzbauer, H., Taylor, T., Rytina, I., Kalla,
-                      M., Zhang, L. and V. Paxson, "Stream Control
-                      Transmission Protocol", RFC 2960, October 2000.
-
-   [RFC3162]          Aboba, B., Zorn, G. and D. Mitton, "RADIUS and
-                      IPv6", RFC 3162, August 2001.
-
-   [RFC3454]          Hoffman, P. and M. Blanchet, "Preparation of
-                      Internationalized Strings ("stringprep")", RFC
-                      3454, December 2002.
-
-   [RFC3579]          Aboba, B. and P. Calhoun, "RADIUS (Remote
-                      Authentication Dial In User Service) Support For
-                      Extensible Authentication Protocol (EAP)", RFC
-                      3579, September 2003.
-
-   [RFC3580]          Congdon, P., Aboba, B., Smith, A., Zorn, G. and J.
-                      Roese, "IEEE 802.1X Remote Authentication Dial In
-                      User Service (RADIUS) Usage Guidelines", RFC 3580,
-                      September 2003.
-
-   [RFC3692]          Narten, T., "Assigning Experimental and Testing
-                      Numbers Considered Useful", BCP 82, RFC 3692,
-                      January 2004.
-
-   [DECEPTION]        Slatalla, M. and J. Quittner, "Masters of
-                      Deception", Harper-Collins, New York, 1995.
-
-   [KRBATTACK]        Wu, T., "A Real-World Analysis of Kerberos
-                      Password Security", Proceedings of the 1999 ISOC
-                      Network and Distributed System Security Symposium,
-                      http://www.isoc.org/isoc/conferences/ndss/99/
-                      proceedings/papers/wu.pdf.
-
-   [KRBLIM]           Bellovin, S. and M. Merrit, "Limitations of the
-                      Kerberos authentication system", Proceedings of
-                      the 1991 Winter USENIX Conference, pp. 253-267,
-                      1991.
-
-   [KERB4WEAK]        Dole, B., Lodin, S. and E. Spafford, "Misplaced
-                      trust:  Kerberos 4 session keys", Proceedings of
-                      the Internet Society Network and Distributed
-                      System Security Symposium, pp. 60-70, March 1997.
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 61]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [PIC]              Aboba, B., Krawczyk, H. and Y. Sheffer, "PIC, A
-                      Pre-IKE Credential Provisioning Protocol", Work in
-                      Progress, October 2002.
-
-   [IKEv2]            Kaufman, C., "Internet Key Exchange (IKEv2)
-                      Protocol", Work in Progress, January 2004.
-
-   [PPTPv1]           Schneier, B. and Mudge, "Cryptanalysis of
-                      Microsoft's Point-to- Point Tunneling Protocol",
-                      Proceedings of the 5th ACM Conference on
-                      Communications and Computer Security, ACM Press,
-                      November 1998.
-
-   [IEEE-802.11]      Institute of Electrical and Electronics Engineers,
-                      "Wireless LAN Medium Access Control (MAC) and
-                      Physical Layer (PHY) Specifications", IEEE
-                      Standard 802.11, 1999.
-
-   [SILVERMAN]        Silverman, Robert D., "A Cost-Based Security
-                      Analysis of Symmetric and Asymmetric Key Lengths",
-                      RSA Laboratories Bulletin 13, April 2000 (Revised
-                      November 2001),
-                      http://www.rsasecurity.com/rsalabs/bulletins/
-                      bulletin13.html.
-
-   [KEYFRAME]         Aboba, B., "EAP Key Management Framework", Work in
-                      Progress, October 2003.
-
-   [SASLPREP]         Zeilenga, K., "SASLprep: Stringprep profile for
-                      user names and passwords", Work in Progress, March
-                      2004.
-
-   [IEEE-802.11i]     Institute of Electrical and Electronics Engineers,
-                      "Unapproved Draft Supplement to Standard for
-                      Telecommunications and Information Exchange
-                      Between Systems - LAN/MAN Specific Requirements -
-                      Part 11: Wireless LAN Medium Access Control (MAC)
-                      and Physical Layer (PHY) Specifications:
-                      Specification for Enhanced Security", IEEE Draft
-                      802.11i (work in progress), 2003.
-
-   [DIAM-EAP]         Eronen, P., Hiller, T. and G. Zorn, "Diameter
-                      Extensible Authentication Protocol (EAP)
-                      Application", Work in Progress, February 2004.
-
-   [EAP-EVAL]         Zorn, G., "Specifying Security Claims for EAP
-                      Authentication Types", Work in Progress, October
-                      2002.
-
-
-
-Aboba, et al.               Standards Track                    [Page 62]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   [BINDING]          Puthenkulam, J., "The Compound Authentication
-                      Binding Problem", Work in Progress, October 2003.
-
-   [MITM]             Asokan, N., Niemi, V. and K. Nyberg, "Man-in-the-
-                      Middle in Tunneled Authentication Protocols", IACR
-                      ePrint Archive Report 2002/163, October 2002,
-                      <http://eprint.iacr.org/2002/163>.
-
-   [IEEE-802.11i-req] Stanley, D., "EAP Method Requirements for Wireless
-                      LANs", Work in Progress, February 2004.
-
-   [PPTPv2]           Schneier, B. and Mudge, "Cryptanalysis of
-                      Microsoft's PPTP Authentication Extensions (MS-
-                      CHAPv2)", CQRE 99, Springer-Verlag, 1999, pp.
-                      192-203.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 63]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-Appendix A. Changes from RFC 2284
-
-   This section lists the major changes between [RFC2284] and this
-   document.  Minor changes, including style, grammar, spelling, and
-   editorial changes are not mentioned here.
-
-   o  The Terminology section (Section 1.2) has been expanded, defining
-      more concepts and giving more exact definitions.
-
-   o  The concepts of Mutual Authentication, Key Derivation, and Result
-      Indications are introduced and discussed throughout the document
-      where appropriate.
-
-   o In Section 2, it is explicitly specified that more than one
-      exchange of Request and Response packets may occur as part of the
-      EAP authentication exchange.  How this may be used and how it may
-      not be used is specified in detail in Section 2.1.
-
-   o  Also in Section 2, some requirements have been made explicit for
-      the authenticator when acting in pass-through mode.
-
-   o  An EAP multiplexing model (Section 2.2) has been added to
-      illustrate a typical implementation of EAP.  There is no
-      requirement that an implementation conform to this model, as long
-      as the on-the-wire behavior is consistent with it.
-
-   o  As EAP is now in use with a variety of lower layers, not just PPP
-      for which it was first designed, Section 3 on lower layer behavior
-      has been added.
-
-   o  In the description of the EAP Request and Response interaction
-      (Section 4.1), both the behavior on receiving duplicate requests,
-      and when packets should be silently discarded has been more
-      exactly specified.  The implementation notes in this section have
-      been substantially expanded.
-
-   o  In Section 4.2, it has been clarified that Success and Failure
-      packets must not contain additional data, and the implementation
-      note has been expanded.  A subsection giving requirements on
-      processing of success and failure packets has been added.
-
-   o  Section 5 on EAP Request/Response Types lists two new Type values:
-      the Expanded Type (Section 5.7), which is used to expand the Type
-      value number space, and the Experimental Type.  In the Expanded
-      Type number space, the new Expanded Nak (Section 5.3.2) Type has
-      been added.  Clarifications have been made in the description of
-      most of the existing Types.  Security claims summaries have been
-      added for authentication methods.
-
-
-
-Aboba, et al.               Standards Track                    [Page 64]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-   o  In Sections 5, 5.1, and 5.2, a requirement has been added such
-      that fields with displayable messages should contain UTF-8 encoded
-      ISO 10646 characters.
-
-   o  It is now required in Section 5.1 that if the Type-Data field of
-      an Identity Request contains a NUL-character, only the part before
-      the null is displayed.  RFC 2284 prohibits the null termination of
-      the Type-Data field of Identity messages.  This rule has been
-      relaxed for Identity Request messages and the Identity Request
-      Type-Data field may now be null terminated.
-
-   o  In Section 5.5, support for OTP Extended Responses [RFC2243] has
-      been added to EAP OTP.
-
-   o  An IANA Considerations section (Section 6) has been added, giving
-      registration policies for the numbering spaces defined for EAP.
-
-   o  The Security Considerations (Section 7) have been greatly
-      expanded, giving a much more comprehensive coverage of possible
-      threats and other security considerations.
-
-   o  In Section 7.5, text has been added on method-specific behavior,
-      providing guidance on how EAP method-specific integrity checks
-      should be processed.  Where possible, it is desirable for a
-      method-specific MIC to be computed over the entire EAP packet,
-      including the EAP layer header (Code, Identifier, Length) and EAP
-      method layer header (Type, Type-Data).
-
-   o  In Section 7.14 the security risks involved in use of cleartext
-      passwords with EAP are described.
-
-   o  In Section 7.15 text has been added relating to detection of rogue
-      NAS behavior.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 65]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-Authors' Addresses
-
-   Bernard Aboba
-   Microsoft Corporation
-   One Microsoft Way
-   Redmond, WA  98052
-   USA
-
-   Phone: +1 425 706 6605
-   Fax:   +1 425 936 6605
-   EMail: bernarda@microsoft.com
-
-   Larry J. Blunk
-   Merit Network, Inc
-   4251 Plymouth Rd., Suite 2000
-   Ann Arbor, MI  48105-2785
-   USA
-
-   Phone: +1 734-647-9563
-   Fax:   +1 734-647-3185
-   EMail: ljb@merit.edu
-
-   John R. Vollbrecht
-   Vollbrecht Consulting LLC
-   9682 Alice Hill Drive
-   Dexter, MI  48130
-   USA
-
-   EMail: jrv@umich.edu
-
-   James Carlson
-   Sun Microsystems, Inc
-   1 Network Drive
-   Burlington, MA  01803-2757
-   USA
-
-   Phone: +1 781 442 2084
-   Fax:   +1 781 442 1677
-   EMail: james.d.carlson@sun.com
-
-   Henrik Levkowetz
-   ipUnplugged AB
-   Arenavagen 33
-   Stockholm  S-121 28
-   SWEDEN
-
-   Phone: +46 708 32 16 08
-   EMail: henrik@levkowetz.com
-
-
-
-Aboba, et al.               Standards Track                    [Page 66]
-\f
-RFC 3748                          EAP                          June 2004
-
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (2004).  This document is subject
-   to the rights, licenses and restrictions contained in BCP 78, and
-   except as set forth therein, the authors retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
-   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
-   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at ietf-
-   ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is currently provided by the
-   Internet Society.
-
-
-
-
-
-
-
-
-
-Aboba, et al.               Standards Track                    [Page 67]
-\f
diff --git a/doc/rfc/rfc4372.txt b/doc/rfc/rfc4372.txt
deleted file mode 100644 (file)
index 228ab8f..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         F. Adrangi
-Request for Comments: 4372                                         Intel
-Category: Standards Track                                        A. Lior
-                                                     Bridgewater Systems
-                                                             J. Korhonen
-                                                             Teliasonera
-                                                             J. Loughney
-                                                                   Nokia
-                                                            January 2006
-
-
-                        Chargeable User Identity
-
-Status of This Memo
-
-   This document specifies an Internet standards track protocol for the
-   Internet community, and requests discussion and suggestions for
-   improvements.  Please refer to the current edition of the "Internet
-   Official Protocol Standards" (STD 1) for the standardization state
-   and status of this protocol.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (2006).
-
-Abstract
-
-   This document describes a new Remote Authentication Dial-In User
-   Service (RADIUS) attribute, Chargeable-User-Identity.  This attribute
-   can be used by a home network to identify a user for the purpose of
-   roaming transactions that occur outside of the home network.
-
-Table of Contents
-
-   1. Introduction ....................................................2
-      1.1. Motivation .................................................3
-      1.2. Terminology ................................................4
-   2. Operation .......................................................5
-      2.1. Chargeable-User-Identity (CUI) Attribute ...................5
-      2.2. CUI Attribute ..............................................6
-   3. Attribute Table .................................................7
-   4. Diameter Consideration ..........................................7
-   5. IANA Considerations .............................................7
-   6. Security Considerations .........................................7
-   7. Acknowledgements ................................................8
-   8. References ......................................................8
-      8.1. Normative References .......................................8
-      8.2. Informative References .....................................8
-
-
-
-Adrangi, et al.             Standards Track                     [Page 1]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-1.  Introduction
-
-   Some authentication methods, including EAP-PEAP, EAP-TTLS, EAP-SIM
-   and EAP-AKA, can hide the true identity of the user from RADIUS
-   servers outside of the user's home network.  In these methods, the
-   User-Name(1) attribute contains an anonymous identity (e.g.,
-   @example.com) sufficient to route the RADIUS packets to the home
-   network but otherwise insufficient to identify the user.  While this
-   mechanism is good practice in some circumstances, there are problems
-   if local and intermediate networks require a surrogate identity to
-   bind the current session.
-
-   This document introduces an attribute that serves as an alias or
-   handle (hereafter, it is called Chargeable-User-Identity) to the real
-   user's identity.  Chargeable-User-Identity can be used outside the
-   home network in scenarios that traditionally relied on User-Name(1)
-   to correlate a session to a user.
-
-   For example, local or intermediate networks may limit the number of
-   simultaneous sessions for specific users; they may require a
-   Chargeable-User-Identity in order to demonstrate willingness to pay
-   or otherwise limit the potential for fraud.
-
-   This implies that a unique identity provided by the home network
-   should be able to be conveyed to all parties involved in the roaming
-   transaction for correlating the authentication and accounting
-   packets.
-
-   Providing a unique identity, Chargeable-User-Identity (CUI), to
-   intermediaries, is necessary to fulfill certain business needs.  This
-   should not undermine the anonymity of the user.  The mechanism
-   provided by this document allows the home operator to meet these
-   business requirements by providing a temporary identity representing
-   the user and at the same time protecting the anonymity of the user.
-
-   When the home network assigns a value to the CUI, it asserts that
-   this value represents a user in the home network.  The assertion
-   should be temporary -- long enough to be useful for the external
-   applications and not too long such that it can be used to identify
-   the user.
-
-   Several organizations, including WISPr, GSMA, 3GPP, Wi-Fi Alliance,
-   and IRAP, have been studying mechanisms to provide roaming services,
-   using RADIUS.  Missing elements include mechanisms for billing and
-   fraud prevention.
-
-
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 2]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-   The CUI attribute is intended to close operational loopholes in
-   RADIUS specifications that have impacted roaming solutions
-   negatively.  Use of the CUI is geared toward EAP methods supporting
-   privacy (such as PEAP and EAP-TTLS), which are, for the most part,
-   recent deployments.  A chargeable identity reflecting the user
-   profile by the home network is needed in such roaming scenarios.
-
-1.1.  Motivation
-
-   Some other mechanisms have been proposed in place of the CUI
-   attribute.  These mechanisms are insufficient or cause other
-   problems.  It has been suggested that standard RADIUS Class(25) or
-   User-Name(1) attributes could be used to indicate the CUI.  However,
-   in a complex global roaming environment where there could be one or
-   more intermediaries between the NAS [RFC4282] and the home RADIUS
-   server, the use of aforementioned attributes could lead to problems
-   as described below.
-
-      - On the use of RADIUS Class(25) attribute:
-
-      [RFC2865] states: "This Attribute is available to be sent by the
-      server to the client in an Access-Accept packet and SHOULD be sent
-      unmodified by the client to the accounting server as part of the
-      Accounting-Request packet if accounting is supported.  The client
-      MUST NOT interpret the attribute locally."  So RADIUS clients or
-      intermediaries MUST NOT interpret the Class(25) attribute, which
-      precludes determining whether it contains a CUI.  Additionally,
-      there could be multiple class attributes in a RADIUS packet, and
-      since the contents of Class(25) attribute is not to be interpreted
-      by clients, this makes it hard for the entities outside the home
-      network to determine which one contains the CUI.
-
-      - On the use of RADIUS User-Name(1) attribute:
-
-      The User-Name(1) attribute included in the Access-Request packet
-      may be used for the purpose of routing the Access-Request packet,
-      and in the process may be rewritten by intermediaries.  As a
-      result, a RADIUS server receiving an Access-Request packet relayed
-      by a proxy cannot assume that the User-Name(1) attribute remained
-      unmodified.
-
-      On the other hand, rewriting of a User-Name(1) attribute sent
-      within an Access-Accept packet occurs more rarely, since a
-      Proxy-State(33) attribute can be used to route the Access-Accept
-      packet without parsing the User-Name(1) attribute.  As a result, a
-      RADIUS server cannot assume that a proxy stripping routing
-      information from a User-Name(1) attribute within an Access-Request
-      packet will add this information to a User-Name(1) attribute
-
-
-
-Adrangi, et al.             Standards Track                     [Page 3]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-      included within an Access-Accept packet.  The result is that when
-      a User-Name(1) attribute is sent in an Access-Accept packet, it is
-      possible that the Access-Request packet and Accounting-Request
-      packets will follow different paths.  Where this outcome is
-      undesirable, the RADIUS client should use the original
-      User-Name(1) in accounting packets.  Therefore, another mechanism
-      is required to convey a CUI within an Access-Accept packet to the
-      RADIUS client, so that the CUI can be included in the accounting
-      packets.
-
-   The CUI attribute provides a solution to the above problems and
-   avoids overloading RADIUS User-Name(1) attribute or changing the
-   usage of existing RADIUS Class(25) attribute.  The CUI therefore
-   provides a standard approach to billing and fraud prevention when EAP
-   methods supporting privacy are used.  It does not solve all related
-   problems, but does provide for billing and fraud prevention.
-
-1.2.  Terminology
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in [RFC2119].
-
-   The following acronyms are used:
-
-      3GPP - Third Generation Partnership Project
-      AAA - Authentication, Authorization, and Accounting
-      AKA - Authentication and Key Agreement
-      CUI - Chargeable-User-Identity
-      GSMA - GSM Association
-      IRAP - International Roaming Access Protocols Program
-      NAS - Network Access Server
-      PEAP - Protected Extensible Authentication Protocol
-      SIM - Subscriber Identity Modules
-      TTLS - Tunneled Transport Layer Security
-      WISPr - Wireless ISP Roaming
-      WPA - Wi-Fi Protected Access
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 4]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-2.  Operation
-
-   This document assumes that the RADIUS protocol operates as specified
-   in [RFC2865] and [RFC2866], dynamic authorization as specified in
-   [RFC3576], and the Diameter protocol as specified in [RFC3588].
-
-2.1.  Chargeable-User-Identity (CUI) Attribute
-
-   The CUI attribute serves as an alias to the user's real identity,
-   representing a chargeable identity as defined and provided by the
-   home network as a supplemental or alternative information to
-   User-Name(1).  Typically, the CUI represents the identity of the
-   actual user, but it may also indicate other chargeable identities
-   such as a group of users.  RADIUS clients (proxy or NAS) outside the
-   home network MUST NOT modify the CUI attribute.
-
-   The RADIUS server (a RADIUS proxy, home RADIUS server) may include
-   the CUI attribute in the Access-Accept packet destined to a roaming
-   partner.  The CUI support by RADIUS infrastructure is driven by the
-   business requirements between roaming entities.  Therefore, a RADIUS
-   server supporting this specification may choose not to send the CUI
-   in response to an Access-Request packet from a given NAS, even if the
-   NAS has indicated that it supports CUI.
-
-   If an Access-Accept packet without the CUI attribute was received by
-   a RADIUS client that requested the CUI attribute, then the
-   Access-Accept packet MAY be treated as an Access-Reject.
-
-   If the CUI was included in an Access-Accept packet, RADIUS clients
-   supporting the CUI attribute MUST ensure that the CUI attribute
-   appears in the RADIUS Accounting-Request (Start, Interim, and Stop).
-   This requirement applies regardless of whether the RADIUS client
-   requested the CUI attribute.
-
-   RFC 2865 includes the following statements about behaviors of RADIUS
-   client and server with respect to unsupported attributes:
-
-      - "A RADIUS client MAY ignore Attributes with an unknown Type."
-      - "A RADIUS server MAY ignore Attributes with an unknown Type."
-
-   Therefore, RADIUS clients or servers that do not support the CUI may
-   ignore the attribute.
-
-   A RADIUS client requesting the CUI attribute in an Access-Accept
-   packet MUST include within the Access-Request packet a CUI attribute.
-   For the initial authentication, the CUI attribute will include a
-   single NUL character (referred to as a nul CUI).  And, during
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 5]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-   re-authentication, the CUI attribute will include a previously
-   received CUI value (referred to as a non-nul CUI value) in the
-   Access-Accept.
-
-   Upon receiving a non-nul CUI value in an Access-Request, the home
-   RADIUS server MAY verify that the value of CUI matches the CUI from
-   the previous Access-Accept.  If the verification fails, then the
-   RADIUS server SHOULD respond with an Access-Reject message.
-
-   If a home RADIUS server that supports the CUI attribute receives an
-   Access-Request packet containing a CUI (set to nul or otherwise), it
-   MUST include the CUI attribute in the Access-Accept packet.
-   Otherwise, if the Access-Request packet does not contain a CUI, the
-   home RADIUS server SHOULD NOT include the CUI attribute in the
-   Access-Accept packet.  The Access-Request may be sent either in the
-   initial authentication or during re-authentication.
-
-   A NAS that requested the CUI during re-authentication by including
-   the CUI in the Access-Request will receive the CUI in the
-   Access-Accept.  The NAS MUST include the value of that CUI in all
-   Accounting Messages.
-
-2.2.  CUI Attribute
-
-   A summary of the RADIUS CUI attribute is given below.
-
-
-      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |     Type      |    Length     | String...
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type: 89 for Chargeable-User-Identity.
-
-   Length: >= 3
-
-   String:
-
-      The string identifies the CUI of the end-user.  This string value
-      is a reference to a particular user.  The format and content of
-      the string value are determined by the Home RADIUS server.  The
-      binding lifetime of the reference to the user is determined based
-      on business agreements.  For example, the lifetime can be set to
-      one billing period.  RADIUS entities other than the Home RADIUS
-      server MUST treat the CUI content as an opaque token, and SHOULD
-      NOT perform operations on its content other than a binary equality
-      comparison test, between two instances of CUI.  In cases where the
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 6]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-      attribute is used to indicate the NAS support for the CUI, the
-      string value contains a nul character.
-
-3.  Attribute Table
-
-   The following table provides a guide to which attribute(s) may be
-   found in which kinds of packets, and in what quantity.
-
-   Request Accept Reject Challenge Accounting #     Attribute
-                                    Request
-     0-1    0-1     0        0        0-1    89 Chargeable-User-Identity
-
-   Note: If the Access-Accept packet contains CUI, then the NAS MUST
-   include the CUI in Accounting Requests (Start, Interim, and Stop)
-   packets.
-
-4.  Diameter Consideration
-
-   Diameter needs to define an identical attribute with the same Type
-   value.  The CUI should be available as part of the NASREQ application
-   [RFC4005].
-
-5.  IANA Considerations
-
-   This document uses the RADIUS [RFC2865] namespace; see
-   http://www.iana.org/assignments/radius-types.  The IANA has assigned
-   a new RADIUS attribute number for the CUI attribute.
-
-   CUI 89
-
-6.  Security Considerations
-
-   It is strongly recommended that the CUI format used is such that the
-   real user identity is not revealed.  Furthermore, where a reference
-   is used to a real user identity, it is recommended that the binding
-   lifetime of that reference to the real user be kept as short as
-   possible.
-
-   The RADIUS entities (RADIUS proxies and clients) outside the home
-   network MUST NOT modify the CUI or insert a CUI in an Access-Accept.
-   However, there is no way to detect or prevent this.
-
-   Attempting theft of service, a man-in-the-middle may try to insert,
-   modify, or remove the CUI in the Access-Accept packets and Accounting
-   packets.  However, RADIUS Access-Accept and Accounting packets
-   already provide integrity protection.
-
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 7]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-   If the NAS includes CUI in an Access-Request packet, a
-   man-in-the-middle may remove it.  This will cause the Access-Accept
-   packet to not include a CUI attribute, which may cause the NAS to
-   reject the session.  To prevent such a denial of service (DoS)
-   attack, the NAS SHOULD include a Message-Authenticator(80) attribute
-   within Access-Request packets containing a CUI attribute.
-
-7.  Acknowledgements
-
-   The authors would like to thank Jari Arkko, Bernard Aboba, David
-   Nelson, Barney Wolff, Blair Bullock, Sami Ala-Luukko, Lothar Reith,
-   David Mariblanca, Eugene Chang, Greg Weber, and Mark Grayson for
-   their feedback and guidance.
-
-8.  References
-
-8.1.  Normative References
-
-   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
-              Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-   [RFC2865]  Rigney, C., Willens, S., Rubens, A., and W. Simpson,
-              "Remote Authentication Dial In User Service (RADIUS)",
-              RFC 2865, June 2000.
-
-   [RFC2866]  Rigney, C., "RADIUS Accounting", RFC 2866, June 2000.
-
-   [RFC4005]  Calhoun, P., Zorn, G., Spence, D., and D. Mitton,
-              "Diameter Network Access Server Application", RFC 4005,
-              August 2005.
-
-   [RFC4282]  Aboba, B., Beadles, M., Arkko, J., and P. Eronen, "The
-              Network Access Identifier", RFC 4282, December 2005.
-
-8.2.  Informative References
-
-   [RFC3576]  Chiba, M., Dommety, G., Eklund, M., Mitton, D., and B.
-              Aboba, "Dynamic Authorization Extensions to Remote
-              Authentication Dial In User Service (RADIUS)", RFC 3576,
-              July 2003.
-
-   [RFC3588]  Calhoun, P., Loughney, J., Guttman, E., Zorn, G., and J.
-              Arkko, "Diameter Base Protocol", RFC 3588, September 2003.
-
-
-
-
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 8]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-Authors' Addresses
-
-   Farid Adrangi
-   Intel Corporation
-   2111 N.E. 25th Avenue
-   Hillsboro, OR  97124
-   USA
-
-   Phone: +1 503-712-1791
-   EMail: farid.adrangi@intel.com
-
-
-   Avi Lior
-   Bridgewater Systems Corporation
-   303 Terry Fox Drive
-   Ottawa, Ontario  K2K 3J1
-   Canada
-
-   Phone: +1 613-591-9104
-   EMail: avi@bridgewatersystems.com
-
-
-   Jouni Korhonen
-   Teliasonera Corporation
-   P.O.Box 970
-   FIN-00051,   Sonera
-   Finland
-
-   Phone: +358405344455
-   EMail: jouni.korhonen@teliasonera.com
-
-
-   John Loughney
-   Nokia
-   Itamerenkatu 11-13
-   FIN-00180,   Helsinki
-   Finland
-
-   Phone: +358504836342
-   EMail: john.loughney@nokia.com
-
-
-
-
-
-
-
-
-
-
-
-Adrangi, et al.             Standards Track                     [Page 9]
-\f
-RFC 4372                Chargeable User Identity            January 2006
-
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (2006).
-
-   This document is subject to the rights, licenses and restrictions
-   contained in BCP 78, and except as set forth therein, the authors
-   retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
-   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
-   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at
-   ietf-ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is provided by the IETF
-   Administrative Support Activity (IASA).
-
-
-
-
-
-
-
-Adrangi, et al.             Standards Track                    [Page 10]
-\f
diff --git a/doc/rfc/rfc4590.txt b/doc/rfc/rfc4590.txt
deleted file mode 100644 (file)
index fad3d22..0000000
+++ /dev/null
@@ -1,1795 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         B. Sterman
-Request for Comments: 4590                               Kayote Networks
-Category: Standards Track                                  D. Sadolevsky
-                                                          SecureOL, Inc.
-                                                             D. Schwartz
-                                                         Kayote Networks
-                                                             D. Williams
-                                                           Cisco Systems
-                                                                 W. Beck
-                                                     Deutsche Telekom AG
-                                                               July 2006
-
-
-               RADIUS Extension for Digest Authentication
-
-Status of This Memo
-
-   This document specifies an Internet standards track protocol for the
-   Internet community, and requests discussion and suggestions for
-   improvements.  Please refer to the current edition of the "Internet
-   Official Protocol Standards" (STD 1) for the standardization state
-   and status of this protocol.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (2006).
-
-Abstract
-
-   This document defines an extension to the Remote Authentication
-   Dial-In User Service (RADIUS) protocol to enable support of Digest
-   Authentication, for use with HTTP-style protocols like the Session
-   Initiation Protocol (SIP) and HTTP.
-
-Table of Contents
-
-1. Introduction ....................................................2
-   1.1. Terminology ................................................2
-   1.2. Motivation .................................................3
-   1.3. Overview ...................................................4
-2. Detailed Description ............................................6
-   2.1. RADIUS Client Behavior .....................................6
-        2.1.1. Credential Selection ................................6
-        2.1.2. Constructing an Access-Request ......................6
-        2.1.3. Constructing an Authentication-Info Header ..........7
-        2.1.4. Failed Authentication ...............................8
-        2.1.5. Obtaining Nonces ....................................9
-   2.2. RADIUS Server Behavior .....................................9
-
-
-
-Sterman, et al.             Standards Track                     [Page 1]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-        2.2.1. General Attribute Checks ............................9
-        2.2.2. Authentication .....................................10
-        2.2.3. Constructing the Reply .............................11
-3. New RADIUS Attributes ..........................................12
-   3.1. Digest-Response attribute .................................12
-   3.2. Digest-Realm Attribute ....................................13
-   3.3. Digest-Nonce Attribute ....................................13
-   3.4. Digest-Response-Auth Attribute ............................14
-   3.5. Digest-Nextnonce Attribute ................................14
-   3.6. Digest-Method Attribute ...................................14
-   3.7. Digest-URI Attribute ......................................15
-   3.8. Digest-Qop Attribute ......................................15
-   3.9. Digest-Algorithm Attribute ................................16
-   3.10. Digest-Entity-Body-Hash Attribute ........................16
-   3.11. Digest-CNonce Attribute ..................................17
-   3.12. Digest-Nonce-Count Attribute .............................17
-   3.13. Digest-Username Attribute ................................17
-   3.14. Digest-Opaque Attribute ..................................18
-   3.15. Digest-Auth-Param Attribute ..............................18
-   3.16. Digest-AKA-Auts Attribute ................................19
-   3.17. Digest-Domain Attribute ..................................19
-   3.18. Digest-Stale Attribute ...................................20
-   3.19. Digest-HA1 Attribute .....................................20
-   3.20. SIP-AOR Attribute ........................................21
-4. Diameter Compatibility .........................................21
-5. Table of Attributes ............................................22
-6. Examples .......................................................23
-7. IANA Considerations ............................................27
-8. Security Considerations ........................................27
-   8.1. Denial of Service .........................................28
-   8.2. Confidentiality and Data Integrity ........................28
-9. Acknowledgements ...............................................29
-10. References ....................................................29
-   10.1. Normative References .....................................29
-   10.2. Informative References ...................................30
-
-1.  Introduction
-
-1.1.  Terminology
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in [RFC2119].
-
-   The use of normative requirement key words in this document shall
-   apply only to RADIUS client and RADIUS server implementations that
-   include the features described in this document.  This document
-   creates no normative requirements for existing implementations.
-
-
-
-Sterman, et al.             Standards Track                     [Page 2]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   HTTP-style protocol
-         The term 'HTTP-style' denotes any protocol that uses HTTP-like
-         headers and uses HTTP Digest Authentication as described in
-         [RFC2617].  Examples are HTTP and the Session Initiation
-         Protocol (SIP).
-
-   NAS
-         Network Access Server, the RADIUS client.
-
-   nonce
-         An unpredictable value used to prevent replay attacks.  The
-         nonce generator may use cryptographic mechanisms to produce
-         nonces it can recognize without maintaining state.
-
-   protection space
-         HTTP-style protocols differ in their definition of the
-         protection space.  For HTTP, it is defined as the combination
-         of realm and canonical root URL of the requested resource for
-         which the use is authorized by the RADIUS server.  In the case
-         of SIP, the realm string alone defines the protection space.
-
-   SIP UA
-         SIP User Agent, an Internet endpoint that uses the Session
-         Initiation Protocol.
-
-   SIP UAS
-         SIP User Agent Server, a logical entity that generates a
-         response to a SIP (Session Initiation Protocol) request.
-
-1.2.  Motivation
-
-   The HTTP Digest Authentication mechanism, defined in [RFC2617], was
-   subsequently adapted for use with SIP [RFC3261].  Due to the
-   limitations and weaknesses of Digest Authentication (see [RFC2617],
-   section 4), additional authentication and encryption mechanisms are
-   defined in SIP [RFC3261], including Transport Layer Security (TLS)
-   [RFC4346] and Secure MIME (S/MIME) [RFC3851].  However, Digest
-   Authentication support is mandatory in SIP implementations, and
-   Digest Authentication is the preferred way for a SIP UA to
-   authenticate itself to a proxy server.  Digest Authentication is used
-   in other protocols as well.
-
-   To simplify the provisioning of users, there is a need to support
-   this authentication mechanism within Authentication, Authorization,
-   and Accounting (AAA) protocols such as RADIUS [RFC2865] and Diameter
-   [RFC3588].
-
-
-
-
-
-Sterman, et al.             Standards Track                     [Page 3]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   This document defines an extension to the RADIUS protocol to enable
-   support of Digest Authentication for use with SIP, HTTP, and other
-   HTTP-style protocols using this authentication method.  Support for
-   Digest mechanisms such as Authentication and Key Agreement (AKA)
-   [RFC3310] is also supported.  A companion document [SIP-APP] defines
-   support for Digest Authentication within Diameter.
-
-1.3.  Overview
-
-   HTTP Digest is a challenge-response protocol used to authenticate a
-   client's request to access some resource on a server.  Figure 1 shows
-   a single HTTP Digest transaction.
-
-                                 HTTP/SIP..
-                  +------------+  (1)     +------------+
-                  |            |--------->|            |
-                  | HTTP-style |  (2)     | HTTP-style |
-                  | client     |<---------| server     |
-                  |            |  (3)     |            |
-                  |            |--------->|            |
-                  |            |  (4)     |            |
-                  |            |<---------|            |
-                  +------------+          +------------+
-
-                 Figure 1: Digest operation without RADIUS
-
-   If the client sends a request without any credentials (1), the server
-   will reply with an error response (2) containing a nonce.  The client
-   creates a cryptographic digest from parts of the request, from the
-   nonce it received from the server, and from a shared secret.  The
-   client re-transmits the request (3) to the server, but now includes
-   the digest within the packet.  The server does the same digest
-   calculation as the client and compares the result with the digest it
-   received in (3).  If the digest values are identical, the server
-   grants access to the resource and sends a positive response to the
-   client (4).  If the digest values differ, the server sends a negative
-   response to the client (4).
-
-   Instead of maintaining a local user database, the server could use
-   RADIUS to access a centralized user database.  However, RADIUS
-   [RFC2865] does not include support for HTTP Digest Authentication.
-   The RADIUS client cannot use the User-Password attribute, since it
-   does not receive a password from the HTTP-style client.  The
-   CHAP-Challenge and CHAP-Password attributes described in [RFC1994]
-   are also not suitable since the CHAP algorithm is not compatible with
-   HTTP Digest.
-
-
-
-
-
-Sterman, et al.             Standards Track                     [Page 4]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   This document defines new attributes that enable the RADIUS server to
-   perform the digest calculation defined in [RFC2617], providing
-   support for Digest Authentication as a native authentication
-   mechanism within RADIUS.
-
-   The nonces required by the digest algorithm are generated by the
-   RADIUS server.  Generating them in the RADIUS client would save a
-   round-trip, but introduce security and operational issues.  Some
-   digest algorithms -- e.g., AKA [RFC3310] -- would not work.
-
-   Figure 2 depicts a scenario in which the HTTP-style server defers
-   authentication to a RADIUS server.  Entities A and B communicate
-   using HTTP or SIP, while entities B and C communicate using RADIUS.
-
-                        HTTP/SIP           RADIUS
-
-               +-----+    (1)    +-----+           +-----+
-               |     |==========>|     |    (2)    |     |
-               |     |           |     |---------->|     |
-               |     |           |     |    (3)    |     |
-               |     |    (4)    |     |<----------|     |
-               |     |<==========|     |           |     |
-               |     |    (5)    |     |           |     |
-               |     |==========>|     |           |     |
-               |  A  |           |  B  |    (6)    |  C  |
-               |     |           |     |---------->|     |
-               |     |           |     |    (7)    |     |
-               |     |           |     |<----------|     |
-               |     |    (8)    |     |           |     |
-               |     |<==========|     |           |     |
-               +-----+           +-----+           +-----+
-
-               ====> HTTP/SIP
-               ----> RADIUS
-
-                    Figure 2: HTTP Digest over RADIUS
-
-   The entities have the following roles:
-
-   A: HTTP client / SIP UA
-
-   B: {HTTP server / HTTP proxy server / SIP proxy server / SIP UAS}
-      acting also as a RADIUS NAS
-
-   C: RADIUS server
-
-
-
-
-
-
-Sterman, et al.             Standards Track                     [Page 5]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   The following messages are sent in this scenario:
-
-   A sends B an HTTP/SIP request without an authorization header (step
-   1).  B sends an Access-Request packet with the newly defined
-   Digest-Method and Digest-URI attributes but without a Digest-Nonce
-   attribute to the RADIUS server, C (step 2).  C chooses a nonce and
-   responds with an Access-Challenge (step 3).  This Access-Challenge
-   contains Digest attributes, from which B takes values to construct an
-   HTTP/SIP "(Proxy) Authorization required" response.  B sends this
-   response to A (step 4).  A resends its request with its credentials
-   (step 5).  B sends an Access-Request to C (step 6).  C checks the
-   credentials and replies with Access-Accept or Access-Reject (step 7).
-   Depending on C's result, B processes A's request or rejects it with a
-   "(Proxy) Authorization required" response (step 8).
-
-2.  Detailed Description
-
-2.1.  RADIUS Client Behavior
-
-   The attributes described in this document are sent in cleartext.
-   Therefore, were a RADIUS client to accept secure connections (HTTPS
-   or SIPS) from HTTP-style clients, this could result in information
-   intentionally protected by HTTP-style clients being sent in the clear
-   during RADIUS exchange.
-
-2.1.1.  Credential Selection
-
-   On reception of an HTTP-style request message, the RADIUS client
-   checks whether it is authorized to authenticate the request.  Where
-   an HTTP-style request traverses several proxies and each of the
-   proxies requests to authenticate the HTTP-style client, the request
-   at the HTTP-style server may contain multiple credential sets.
-
-   The RADIUS client can use the 'realm' directive in HTTP to determine
-   which credentials are applicable.  Where none of the realms are of
-   interest, the RADIUS client MUST behave as though no relevant
-   credentials were sent.  In all situations, the RADIUS client MUST
-   send zero or exactly one credential to the RADIUS server.  The RADIUS
-   client MUST choose the credential of the (Proxy-)Authorization header
-   if the realm directive matches its locally configured realm.
-
-2.1.2.  Constructing an Access-Request
-
-   If a matching (Proxy-)Authorization header is present and contains
-   HTTP Digest information, the RADIUS client checks the 'nonce'
-   parameter.
-
-
-
-
-
-Sterman, et al.             Standards Track                     [Page 6]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   If the RADIUS client recognizes the nonce, it takes the header
-   directives and puts them into a RADIUS Access-Request packet.  It
-   puts the 'response' directive into a Digest-Response attribute and
-   the realm, nonce, digest-uri, qop, algorithm, cnonce, nc, username,
-   and opaque directives into the respective Digest-Realm, Digest-Nonce,
-   Digest-URI, Digest-Qop, Digest-Algorithm, Digest-CNonce,
-   Digest-Nonce-Count, Digest-Username, and Digest-Opaque attributes.
-   The RADIUS client puts the request method into the Digest-Method
-   attribute.
-
-   Due to syntactic requirements, HTTP-style protocols have to escape
-   with backslash all quote and backslash characters in contents of HTTP
-   Digest directives.  When translating directives into RADIUS
-   attributes, the RADIUS client only removes the surrounding quotes
-   where present.  See Section 3 for an example.
-
-   If the Quality of Protection (qop) directive's value is 'auth-int',
-   the RADIUS client calculates H(entity-body) as described in
-   [RFC2617], Section 3.2.1, and puts the result in a
-   Digest-Entity-Body-Hash attribute.
-
-   The RADIUS client adds a Message-Authenticator attribute, defined in
-   [RFC3579], and sends the Access-Request packet to the RADIUS server.
-
-   The RADIUS server processes the packet and responds with an
-   Access-Accept or an Access-Reject.
-
-2.1.3.  Constructing an Authentication-Info Header
-
-   After having received an Access-Accept from the RADIUS server, the
-   RADIUS client constructs an Authentication-Info header:
-
-   o  If the Access-Accept packet contains a Digest-Response-Auth
-      attribute, the RADIUS client checks the Digest-Qop attribute:
-
-      *  If the Digest-Qop attribute's value is 'auth' or not specified,
-         the RADIUS client puts the Digest-Response-Auth attribute's
-         content into the Authentication-Info header's 'rspauth'
-         directive of the HTTP-style response.
-
-      *  If the Digest-Qop attribute's value is 'auth-int', the RADIUS
-         client ignores the Access-Accept packet and behaves as if it
-         had received an Access-Reject packet (Digest-Response-Auth
-         can't be correct as the RADIUS server does not know the
-         contents of the HTTP-style response's body).
-
-
-
-
-
-
-Sterman, et al.             Standards Track                     [Page 7]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   o  If the Access-Accept packet contains a Digest-HA1 attribute, the
-      RADIUS client checks the 'qop' and 'algorithm' directives in the
-      Authorization header of the HTTP-style request it wants to
-      authorize:
-
-      *  If the 'qop' directive is missing or its value is 'auth', the
-         RADIUS client ignores the Digest-HA1 attribute.  It does not
-         include an Authentication-Info header in its HTTP-style
-         response.
-
-      *  If the 'qop' directive's value is 'auth-int' and at least one
-         of the following conditions is true, the RADIUS client
-         calculates the contents of the HTTP-style response's 'rspauth'
-         directive:
-
-         +  The algorithm directive's value is 'MD5-sess' or
-            'AKAv1-MD5-sess'.
-
-         +  IP Security (IPsec) is configured to protect traffic between
-            the RADIUS client and RADIUS server with IPsec (see
-            Section 8).
-
-         It creates the HTTP-style response message and calculates the
-         hash of this message's body.  It uses the result and the
-         Digest-URI attribute's value of the corresponding
-         Access-Request packet to perform the H(A2) calculation.  It
-         takes the Digest-Nonce, Digest-Nonce-Count, Digest-CNonce, and
-         Digest-Qop values of the corresponding Access-Request and the
-         Digest-HA1 attribute's value to finish the computation of the
-         'rspauth' value.
-
-   o  If the Access-Accept packet contains neither a
-      Digest-Response-Auth nor a Digest-HA1 attribute, the RADIUS client
-      will not create an Authentication-Info header for its HTTP-style
-      response.
-
-   When the RADIUS server provides a Digest-Nextnonce attribute in the
-   Access-Accept packet, the RADIUS client puts the contents of this
-   attribute into a 'nextnonce' directive.  Now it can send an
-   HTTP-style response.
-
-2.1.4.  Failed Authentication
-
-   If the RADIUS client did receive an HTTP-style request without a
-   (Proxy-)Authorization header matching its locally configured realm
-   value, it obtains a new nonce and sends an error response (401 or
-   407) containing a (Proxy-)Authenticate header.
-
-
-
-
-Sterman, et al.             Standards Track                     [Page 8]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   If the RADIUS client receives an Access-Challenge packet in response
-   to an Access-Request containing a Digest-Nonce attribute, the RADIUS
-   server did not accept the nonce.  If a Digest-Stale attribute is
-   present in the Access-Challenge and has a value of 'true' (without
-   surrounding quotes), the RADIUS client sends an error response (401
-   or 407) containing a WWW-/Proxy-Authenticate header with the
-   directive 'stale' and the digest directives derived from the Digest-*
-   attributes.
-
-   If the RADIUS client receives an Access-Reject from the RADIUS
-   server, it sends an error response to the HTTP-style request it has
-   received.  If the RADIUS client does not receive a response, it
-   retransmits or fails over to another RADIUS server as described in
-   [RFC2865].
-
-2.1.5.  Obtaining Nonces
-
-   The RADIUS client has two ways to obtain nonces: it has received one
-   in a Digest-Nextnonce attribute of a previously received
-   Access-Accept packet or it asks the RADIUS server for one.  To do the
-   latter, it sends an Access-Request containing a Digest-Method and a
-   Digest-URI attribute but without a Digest-Nonce attribute.  It adds a
-   Message-Authenticator (see [RFC3579]) attribute to the Access-Request
-   packet.  The RADIUS server chooses a nonce and responds with an
-   Access-Challenge containing a Digest-Nonce attribute.
-
-   The RADIUS client constructs a (Proxy-)Authenticate header using the
-   received Digest-Nonce and Digest-Realm attributes to fill the nonce
-   and realm directives.  The RADIUS server can send Digest-Qop,
-   Digest-Algorithm, Digest-Domain, and Digest-Opaque attributes in the
-   Access-Challenge carrying the nonce.  If these attributes are
-   present, the client MUST use them.
-
-2.2.  RADIUS Server Behavior
-
-   If the RADIUS server receives an Access-Request packet with a
-   Digest-Method and a Digest-URI attribute but without a Digest-Nonce
-   attribute, it chooses a nonce.  It puts the nonce into a Digest-Nonce
-   attribute and sends it in an Access-Challenge packet to the RADIUS
-   client.  The RADIUS server MUST add Digest-Realm,
-   Message-Authenticator (see [RFC3579]), SHOULD add Digest-Algorithm
-   and one or more Digest-Qop, and MAY add Digest-Domain or
-   Digest-Opaque attributes to the Access-Challenge packet.
-
-2.2.1.  General Attribute Checks
-
-   If the RADIUS server receives an Access-Request packet containing a
-   Digest-Response attribute, it looks for the following attributes:
-
-
-
-Sterman, et al.             Standards Track                     [Page 9]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Digest-Realm, Digest-Nonce, Digest-Method, Digest-URI, Digest-Qop,
-   Digest-Algorithm, and Digest-Username.  Depending on the content of
-   Digest-Algorithm and Digest-Qop, it looks for
-   Digest-Entity-Body-Hash, Digest-CNonce, and Digest-AKA-Auts, too.
-   See [RFC2617] and [RFC3310] for details.  If the Digest-Algorithm
-   attribute is missing, 'MD5' is assumed.  If the RADIUS server has
-   issued a Digest-Opaque attribute along with the nonce, the
-   Access-Request MUST have a matching Digest-Opaque attribute.
-
-   If mandatory attributes are missing, it MUST respond with an
-   Access-Reject packet.
-
-   The RADIUS server removes '\' characters that escape quote and '\'
-   characters from the text values it has received in the Digest-*
-   attributes.
-
-   If the mandatory attributes are present, the RADIUS server MUST check
-   if the RADIUS client is authorized to serve users of the realm
-   mentioned in the Digest-Realm attribute.  If the RADIUS client is not
-   authorized, the RADIUS server MUST send an Access-Reject.  The RADIUS
-   server SHOULD log the event so as to notify the operator, and MAY
-   take additional action such as sending an Access-Reject in response
-   to all future requests from this client, until this behavior is reset
-   by management action.
-
-   The RADIUS server determines the age of the nonce in Digest-Nonce by
-   using an embedded time-stamp or by looking it up in a local table.
-   The RADIUS server MUST check the integrity of the nonce if it embeds
-   the time-stamp in the nonce.  Section 2.2.2 describes how the server
-   handles old nonces.
-
-2.2.2.  Authentication
-
-   If the Access-Request message has passed the checks described above,
-   the RADIUS server calculates the digest response as described in
-   [RFC2617].  To look up the password, the RADIUS server uses the
-   RADIUS User-Name attribute.  The RADIUS server MUST check if the user
-   identified by the User-Name attribute
-
-   o  is authorized to access the protection space and
-
-   o  is authorized to use the URI included in the SIP-AOR attribute, if
-      this attribute is present.
-
-   If any of those checks fails, the RADIUS server MUST send an
-   Access-Reject.
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 10]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Correlation between User-Name and SIP-AOR AVP values is required just
-   to avoid that any user can register or misuse a SIP-AOR allocated to
-   a different user.
-
-   All values required for the digest calculation are taken from the
-   Digest attributes described in this document.  If the calculated
-   digest response equals the value received in the Digest-Response
-   attribute, the authentication was successful.
-
-   If the response values match, but the RADIUS server considers the
-   nonce in the Digest-Nonce attribute as too old, it sends an
-   Access-Challenge packet containing a new nonce and a Digest-Stale
-   attribute with a value of 'true' (without surrounding quotes).
-
-   If the response values don't match, the RADIUS server responds with
-   an Access-Reject.
-
-2.2.3.  Constructing the Reply
-
-   If the authentication was successful, the RADIUS server adds an
-   attribute to the Access-Accept packet that can be used by the RADIUS
-   client to construct an Authentication-Info header:
-
-   o  If the Digest-Qop attribute's value is 'auth' or unspecified, the
-      RADIUS server SHOULD put a Digest-Response-Auth attribute into the
-      Access-Accept packet.
-
-   o  If the Digest-Qop attribute's value is 'auth-int' and at least one
-      of the following conditions is true, the RADIUS server SHOULD put
-      a Digest-HA1 attribute into the Access-Accept packet:
-
-      *  The Digest-Algorithm attribute's value is 'MD5-sess' or
-         'AKAv1-MD5-sess'.
-
-      *  IPsec is configured to protect traffic between the RADIUS
-         client and RADIUS server with IPsec (see Section 8).
-
-   In all other cases, Digest-Response-Auth or Digest-HA1 MUST NOT be
-   sent.
-
-   RADIUS servers MAY construct a Digest-Nextnonce attribute and add it
-   to the Access-Accept packet.  This is useful to limit the lifetime of
-   a nonce and to save a round-trip in future requests (see nextnonce
-   discussion in [RFC2617], section 3.2.3).  The RADIUS server adds a
-   Message-Authenticator attribute (see [RFC3579]) and sends the
-   Access-Accept packet to the RADIUS client.
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 11]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   If the RADIUS server does not accept the nonce received in an
-   Access-Request packet but authentication was successful, the RADIUS
-   server MUST send an Access-Challenge packet containing a Digest-Stale
-   attribute set to 'true' (without surrounding quotes).  The RADIUS
-   server MUST add Message-Authenticator (see [RFC3579]), Digest-Nonce,
-   Digest-Realm, SHOULD add Digest-Algorithm and one or more Digest-Qop
-   and MAY add Digest-Domain, Digest-Opaque attributes to the
-   Access-Challenge packet.
-
-3.  New RADIUS Attributes
-
-   If not stated otherwise, the attributes have the following format:
-
-   0                   1                   2
-   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Type      |  Length       | Text ...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Quote and backslash characters in Digest-* attributes representing
-   HTTP-style directives with a quoted-string syntax are escaped.  The
-   surrounding quotes are removed.  They are syntactical delimiters that
-   are redundant in RADIUS.  For example, the directive
-
-   realm="the \"example\" value"
-
-   is represented as follows:
-
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Digest-Realm  |       23      | the \"example\" value |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-3.1.  Digest-Response attribute
-
-   Description
-         If this attribute is present in an Access-Request message, a
-         RADIUS server implementing this specification MUST treat the
-         Access-Request as a request for Digest Authentication.  When a
-         RADIUS client receives a (Proxy-)Authorization header, it puts
-         the request-digest value into a Digest-Response attribute.
-         This attribute (which enables the user to prove possession of
-         the password) MUST only be used in Access-Requests.
-   Type
-         103 for Digest-Response.
-   Length
-         >= 3
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 12]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Text
-         When using HTTP Digest, the text field is 32 octets long and
-         contains a hexadecimal representation of a 16-octet digest
-         value as it was calculated by the authenticated client.  Other
-         digest algorithms MAY define different digest lengths.  The
-         text field MUST be copied from request-digest of
-         digest-response ([RFC2617]) without surrounding quotes.
-
-3.2.  Digest-Realm Attribute
-
-   Description
-         This attribute describes a protection space component of the
-         RADIUS server.  HTTP-style protocols differ in their definition
-         of the protection space.  See [RFC2617], Section 1.2, for
-         details.  It MUST only be used in Access-Request and
-         Access-Challenge packets.
-   Type
-         104 for Digest-Realm
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         realm directive (realm-value according to [RFC2617]) without
-         surrounding quotes from the HTTP-style request it wants to
-         authenticate.  In Access-Challenge packets, the RADIUS server
-         puts the expected realm value into this attribute.
-
-3.3.  Digest-Nonce Attribute
-
-   Description
-
-         This attribute holds a nonce to be used in the HTTP Digest
-         calculation.  If the Access-Request had a Digest-Method and a
-         Digest-URI but no Digest-Nonce attribute, the RADIUS server
-         MUST put a Digest-Nonce attribute into its Access-Challenge
-         packet.  This attribute MUST only be used in Access-Request and
-         Access-Challenge packets.
-   Type
-         105 for Digest-Nonce
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         nonce directive (nonce-value in [RFC2617]) without surrounding
-         quotes from the HTTP-style request it wants to authenticate.
-         In Access-Challenge packets, the attribute contains the nonce
-         selected by the RADIUS server.
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 13]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-3.4.  Digest-Response-Auth Attribute
-
-   Description
-         This attribute enables the RADIUS server to prove possession of
-         the password.  If the previously received Digest-Qop attribute
-         was 'auth-int' (without surrounding quotes), the RADIUS server
-         MUST send a Digest-HA1 attribute instead of a
-         Digest-Response-Auth attribute.  The Digest-Response-Auth
-         attribute MUST only be used in Access-Accept packets.  The
-         RADIUS client puts the attribute value without surrounding
-         quotes into the rspauth directive of the Authentication-Info
-         header.
-   Type
-         106 for Digest-Response-Auth.
-   Length
-         >= 3
-   Text
-         The RADIUS server calculates a digest according to section
-         3.2.3 of [RFC2617] and copies the result into this attribute.
-         Digest algorithms other than the one defined in [RFC2617] MAY
-         define digest lengths other than 32.
-
-3.5.  Digest-Nextnonce Attribute
-
-   This attribute holds a nonce to be used in the HTTP Digest
-   calculation.
-
-   Description
-
-         The RADIUS server MAY put a Digest-Nextnonce attribute into an
-         Access-Accept packet.  If this attribute is present, the RADIUS
-         client MUST put the contents of this attribute into the
-         nextnonce directive of an Authentication-Info header in its
-         HTTP-style response.  This attribute MUST only be used in
-         Access-Accept packets.
-   Type
-         107 for Digest-Nextnonce
-   Length
-         >=3
-   Text
-         It is recommended that this text be base64 or hexadecimal data.
-
-3.6.  Digest-Method Attribute
-
-   Description
-         This attribute holds the method value to be used in the HTTP
-         Digest calculation.  This attribute MUST only be used in
-         Access-Request packets.
-
-
-
-Sterman, et al.             Standards Track                    [Page 14]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Type
-         108 for Digest-Method
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         request method from the HTTP-style request it wants to
-         authenticate.
-
-3.7.  Digest-URI Attribute
-
-   Description
-         This attribute is used to transport the contents of the
-         digest-uri directive or the URI of the HTTP-style request.  It
-         MUST only be used in Access-Request packets.
-   Type
-         109 for Digest-URI
-   Length
-         >=3
-   Text
-         If the HTTP-style request has an Authorization header, the
-         RADIUS client puts the value of the "uri" directive found in
-         the HTTP-style request Authorization header (known as
-         "digest-uri-value" in section 3.2.2 of [RFC2617]) without
-         surrounding quotes into this attribute.  If there is no
-         Authorization header, the RADIUS client takes the value of the
-         request URI from the HTTP-style request it wants to
-         authenticate.
-
-3.8.  Digest-Qop Attribute
-
-   Description
-         This attribute holds the Quality of Protection parameter that
-         influences the HTTP Digest calculation.  This attribute MUST
-         only be used in Access-Request and Access-Challenge packets.  A
-         RADIUS client SHOULD insert one of the Digest-Qop attributes it
-         has received in a previous Access-Challenge packet.  RADIUS
-         servers SHOULD insert at least one Digest-Qop attribute in an
-         Access-Challenge packet.  Digest-Qop is optional in order to
-         preserve backward compatibility with a minimal implementation
-         of [RFC2069].
-   Type
-         110 for Digest-Qop
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         qop directive (qop-value as described in [RFC2617]) from the
-
-
-
-Sterman, et al.             Standards Track                    [Page 15]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-         HTTP-style request it wants to authenticate.  In
-         Access-Challenge packets, the RADIUS server puts a desired
-         qop-value into this attribute.  If the RADIUS server supports
-         more than one "quality of protection" value, it puts each
-         qop-value into a separate Digest-Qop attribute.
-
-3.9.  Digest-Algorithm Attribute
-
-   Description
-         This attribute holds the algorithm parameter that influences
-         the HTTP Digest calculation.  It MUST only be used in
-         Access-Request and Access-Challenge packets.  If this attribute
-         is missing, MD5 is assumed.
-   Type
-         111 for Digest-Algorithm
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         algorithm directive (as described in [RFC2617], section 3.2.1)
-         from the HTTP-style request it wants to authenticate.  In
-         Access-Challenge packets, the RADIUS server SHOULD put the
-         desired algorithm into this attribute.
-
-3.10.  Digest-Entity-Body-Hash Attribute
-
-   Description
-         When using the qop-level 'auth-int', a hash of the HTTP-style
-         message body's contents is required for digest calculation.
-         Instead of sending the complete body of the message, only its
-         hash value is sent.  This hash value can be used directly in
-         the digest calculation.
-
-         The clarifications described in section 22.4 of [RFC3261] about
-         the hash of empty entity bodies apply to the
-         Digest-Entity-Body-Hash attribute.  This attribute MUST only be
-         sent in Access-Request packets.
-   Type
-         112 for Digest-Entity-Body-Hash
-   Length
-         >=3
-   Text
-         The attribute holds the hexadecimal representation of
-         H(entity-body).  This hash is required by certain
-         authentication mechanisms, such as HTTP Digest with quality of
-         protection set to "auth-int".  RADIUS clients MUST use this
-         attribute to transport the hash of the entity body when HTTP
-         Digest is the authentication mechanism and the RADIUS server
-
-
-
-Sterman, et al.             Standards Track                    [Page 16]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-         requires that the integrity of the entity body (e.g., qop
-         parameter set to "auth-int") be verified.  Extensions to this
-         document may define support for authentication mechanisms other
-         than HTTP Digest.
-
-3.11.  Digest-CNonce Attribute
-
-   Description
-         This attribute holds the client nonce parameter that is used in
-         the HTTP Digest calculation.  It MUST only be used in
-         Access-Request packets.
-   Type
-         113 for Digest-CNonce
-   Length
-         >=3
-   Text
-         This attribute includes the value of the cnonce-value [RFC2617]
-         without surrounding quotes, taken from the HTTP-style request.
-
-3.12.  Digest-Nonce-Count Attribute
-
-   Description
-         This attribute includes the nonce count parameter that is used
-         to detect replay attacks.  The attribute MUST only be used in
-         Access-Request packets.
-
-   Type
-         114 for Digest-Nonce-Count
-   Length
-         10
-   Text
-         In Access-Requests, the RADIUS client takes the value of the nc
-         directive (nc-value according to [RFC2617]) without surrounding
-         quotes from the HTTP-style request it wants to authenticate.
-
-3.13.  Digest-Username Attribute
-
-   Description
-         This attribute holds the user name used in the HTTP Digest
-         calculation.  The RADIUS server MUST use this attribute only
-         for the purposes of calculating the digest.  In order to
-         determine the appropriate user credentials, the RADIUS server
-         MUST use the User-Name (1) attribute, and MUST NOT use the
-         Digest-Username attribute.  This attribute MUST only be used in
-         Access-Request packets.
-   Type
-         115 for Digest-Username
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 17]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Length
-         >= 3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         username directive (username-value according to [RFC2617])
-         without surrounding quotes from the HTTP-style request it wants
-         to authenticate.
-
-3.14.  Digest-Opaque Attribute
-
-   Description
-         This attribute holds the opaque parameter that is passed to the
-         HTTP-style client.  The HTTP-style client will pass this value
-         back to the server (i.e., the RADIUS client) without
-         modification.  This attribute MUST only be used in
-         Access-Request and Access-Challenge packets.
-   Type
-         116 for Digest-Opaque
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         opaque directive (opaque-value according to [RFC2617]) without
-         surrounding quotes from the HTTP-style request it wants to
-         authenticate and puts it into this attribute.  In
-         Access-Challenge packets, the RADIUS server MAY include this
-         attribute.
-
-3.15.  Digest-Auth-Param Attribute
-
-   Description
-         This attribute is a placeholder for future extensions and
-         corresponds to the "auth-param" parameter defined in section
-         3.2.1 of [RFC2617].  The Digest-Auth-Param is the mechanism
-         whereby the RADIUS client and RADIUS server can exchange
-         auth-param extension parameters contained within Digest headers
-         that are not understood by the RADIUS client and for which
-         there are no corresponding stand-alone attributes.
-
-         Unlike the previously listed Digest-* attributes, the
-         Digest-Auth-Param contains not only the value but also the
-         parameter name, since the parameter name is unknown to the
-         RADIUS client.  If the Digest header contains several unknown
-         parameters, then the RADIUS implementation MUST repeat this
-         attribute and each instance MUST contain one different unknown
-         Digest parameter/value combination.  This attribute MUST ONLY
-         be used in Access-Request, Access-Challenge, or Access-Accept
-         packets.
-
-
-
-Sterman, et al.             Standards Track                    [Page 18]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Type
-         117 for Digest-Auth-Param
-   Length
-         >=3
-   Text
-         The text consists of the whole parameter, including its name
-         and the equal sign ('=') and quotes.
-
-3.16.  Digest-AKA-Auts Attribute
-
-   Description
-         This attribute holds the auts parameter that is used in the
-         Digest AKA ([RFC3310]) calculation.  It is only used if the
-         algorithm of the digest-response denotes a version of AKA
-         Digest [RFC3310].  This attribute MUST only be used in
-         Access-Request packets.
-   Type
-         118 for Digest-AKA-Auts
-   Length
-         >=3
-   Text
-         In Access-Requests, the RADIUS client takes the value of the
-         auts directive (auts-param according to section 3.4 of
-         [RFC3310]) without surrounding quotes from the HTTP-style
-         request it wants to authenticate.
-
-3.17.  Digest-Domain Attribute
-
-   Description
-         When a RADIUS client has asked for a nonce, the RADIUS server
-         MAY send one or more Digest-Domain attributes in its
-         Access-Challenge packet.  The RADIUS client puts them into the
-         quoted, space-separated list of URIs of the 'domain' directive
-         of a WWW-Authenticate header.  Together with Digest-Realm, the
-         URIs in the list define the protection space (see [RFC2617],
-         section 3.2.1) for some HTTP-style protocols.  This attribute
-         MUST only be used in Access-Challenge packets.
-   Type
-         119 for Digest-Domain
-   Length
-         3
-   Text
-         This attribute consists of a single URI that defines a
-         protection space component.
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 19]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-3.18.  Digest-Stale Attribute
-
-   Description
-         This attribute is sent by a RADIUS server in order to notify
-         the RADIUS client whether it has accepted a nonce.  If the
-         nonce presented by the RADIUS client was stale, the value is
-         'true' and is 'false' otherwise.  The RADIUS client puts the
-         content of this attribute into a 'stale' directive of the
-         WWW-Authenticate header in the HTTP-style response to the
-         request it wants to authenticate.  The attribute MUST only be
-         used in Access-Challenge packets.
-   Type
-         120 for Digest-Stale
-   Length
-         3
-   Text
-         The attribute has either the value 'true' or 'false' (both
-         values without surrounding quotes).
-
-3.19.  Digest-HA1 Attribute
-
-   Description
-         This attribute is used to allow the generation of an
-         Authentication-Info header, even if the HTTP-style response's
-         body is required for the calculation of the rspauth value.  It
-         SHOULD be used in Access-Accept packets if the required quality
-         of protection ('qop') is 'auth-int'.
-
-         This attribute MUST NOT be sent if the qop parameter was not
-         specified or has a value of 'auth' (in this case, use
-         Digest-Response-Auth instead).
-
-         The Digest-HA1 attribute MUST only be sent by the RADIUS server
-         or processed by the RADIUS client if at least one of the
-         following conditions is true:
-
-         +  The Digest-Algorithm attribute's value is 'MD5-sess' or
-            'AKAv1-MD5-sess'.
-
-         +  IPsec is configured to protect traffic between RADIUS client
-            and RADIUS server with IPsec (see Section 8).
-
-         This attribute MUST only be used in Access-Accept packets.
-   Type
-         121 for Digest-HA1
-   Length
-         >= 3
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 20]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   Text
-         This attribute contains the hexadecimal representation of H(A1)
-         as described in [RFC2617], sections 3.1.3, 3.2.1, and 3.2.2.2.
-
-3.20.  SIP-AOR Attribute
-
-   Description
-         This attribute is used for the authorization of SIP messages.
-         The SIP-AOR attribute identifies the URI, the use of which must
-         be authenticated and authorized.  The RADIUS server uses this
-         attribute to authorize the processing of the SIP request.  The
-         SIP-AOR can be derived from, for example, the To header field
-         in a SIP REGISTER request (user under registration), or the
-         From header field in other SIP requests.  However, the exact
-         mapping of this attribute to SIP can change due to new
-         developments in the protocol.  This attribute MUST only be used
-         when the RADIUS client wants to authorize SIP users and MUST
-         only be used in Access-Request packets.
-   Type
-         122 for SIP-AOR
-   Length
-         >=3
-   Text
-         The syntax of this attribute corresponds either to a SIP URI
-         (with the format defined in [RFC3261] or a tel URI (with the
-         format defined in [RFC3966]).
-
-         The SIP-AOR attribute holds the complete URI, including
-         parameters and other parts.  It is up to the RADIUS server what
-         components of the URI are regarded in the authorization
-         decision.
-
-4.  Diameter Compatibility
-
-   This document defines support for Digest Authentication in RADIUS.  A
-   companion document "Diameter Session Initiation Protocol (SIP)
-   Application" [SIP-APP] defines support for Digest Authentication in
-   Diameter, and addresses compatibility issues between RADIUS and
-   Diameter.
-
-
-
-
-
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 21]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-5.  Table of Attributes
-
-   The following table provides a guide to which attributes may be found
-   in which kinds of packets, and in what quantity.
-
-   +-----+--------+--------+-----------+-----+-------------------------+
-   | Req | Accept | Reject | Challenge | #   | Attribute               |
-   +-----+--------+--------+-----------+-----+-------------------------+
-   | 1   | 0      | 0      | 0         | 1   | User-Name               |
-   | 1   | 1      | 1      | 1         | 80  | Message-Authenticator   |
-   | 0-1 | 0      | 0      | 0         | 103 | Digest-Response         |
-   | 0-1 | 0      | 0      | 1         | 104 | Digest-Realm            |
-   | 0-1 | 0      | 0      | 1         | 105 | Digest-Nonce            |
-   | 0   | 0-1    | 0      | 0         | 106 | Digest-Response-Auth    |
-   |     |        |        |           |     | (see Note 1, 2)         |
-   | 0   | 0-1    | 0      | 0         | 107 | Digest-Nextnonce        |
-   | 0-1 | 0      | 0      | 0         | 108 | Digest-Method           |
-   | 0-1 | 0      | 0      | 0         | 109 | Digest-URI              |
-   | 0-1 | 0      | 0      | 0+        | 110 | Digest-Qop              |
-   | 0-1 | 0      | 0      | 0-1       | 111 | Digest-Algorithm (see   |
-   |     |        |        |           |     | Note 3)                 |
-   | 0-1 | 0      | 0      | 0         | 112 | Digest-Entity-Body-Hash |
-   | 0-1 | 0      | 0      | 0         | 113 | Digest-CNonce           |
-   | 0-1 | 0      | 0      | 0         | 114 | Digest-Nonce-Count      |
-   | 0-1 | 0      | 0      | 0         | 115 | Digest-Username         |
-   | 0-1 | 0      | 0      | 0-1       | 116 | Digest-Opaque           |
-   | 0+  | 0+     | 0      | 0+        | 117 | Digest-Auth-Param       |
-   | 0-1 | 0      | 0      | 0         | 118 | Digest-AKA-Auts         |
-   | 0   | 0      | 0      | 0+        | 119 | Digest-Domain           |
-   | 0   | 0      | 0      | 0-1       | 120 | Digest-Stale            |
-   | 0   | 0-1    | 0      | 0         | 121 | Digest-HA1 (see Note 1, |
-   |     |        |        |           |     | 2)                      |
-   | 0-1 | 0      | 0      | 0         | 122 | SIP-AOR                 |
-   +-----+--------+--------+-----------+-----+-------------------------+
-
-                                  Table 1
-
-   [Note 1] Digest-HA1 MUST be used instead of Digest-Response-Auth if
-      Digest-Qop is 'auth-int'.
-
-   [Note 2] Digest-Response-Auth MUST be used instead of Digest-HA1 if
-      Digest-Qop is 'auth'.
-
-   [Note 3] If Digest-Algorithm is missing, 'MD5' is assumed.
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 22]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-6.  Examples
-
-   This is an example selected from the traffic between a softphone (A),
-   a Proxy Server (B), and an example.com RADIUS server (C).  The
-   communication between the Proxy Server and a SIP Public Switched
-   Telephone Network (PSTN) gateway is omitted for brevity.  The SIP
-   messages are not shown completely.
-
-   A->B
-
-      INVITE sip:97226491335@example.com SIP/2.0
-      From: <sip:12345678@example.com>
-      To: <sip:97226491335@example.com>
-
-   B->A
-
-      SIP/2.0 100 Trying
-
-   B->C
-
-      Code = 1 (Access-Request)
-      Attributes:
-      NAS-IP-Address = c0 0 2 26 (192.0.2.38)
-      NAS-Port-Type = 5 (Virtual)
-      User-Name = 12345678
-      Digest-Method = INVITE
-      Digest-URI = sip:97226491335@example.com
-      Message-Authenticator =
-       08 af 7e 01 b6 8d 74 c3 a4 3c 33 e1 56 2a 80 43
-
-   C->B
-
-      Code = 11 (Access-Challenge)
-      Attributes:
-      Digest-Nonce = 3bada1a0
-      Digest-Realm = example.com
-      Digest-Qop = auth
-      Digest-Algorithm = MD5
-      Message-Authenticator =
-       f8 01 26 9f 70 5e ef 5d 24 ac f5 ca fb 27 da 40
-
-   B->A
-
-      SIP/2.0 407 Proxy Authentication Required
-      Proxy-Authenticate: Digest realm="example.com"
-           ,nonce="3bada1a0",qop=auth,algorithm=MD5
-      Content-Length: 0
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 23]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   A->B
-
-      ACK sip:97226491335@example.com SIP/2.0
-
-   A->B
-
-      INVITE sip:97226491335@example.com SIP/2.0
-      Proxy-Authorization: Digest algorithm="md5",nonce="3bada1a0"
-           ,realm="example.com"
-           ,response="f3ce87e6984557cd0fecc26f3c5e97a4"
-           ,uri="sip:97226491335@example.com",username="12345678"
-           ,qop=auth,algorithm=MD5
-      From: <sip:12345678@example.com>
-      To: <sip:97226491335@example.com>
-
-   B->C
-
-      Code = 1 (Access-Request)
-      Attributes:
-      NAS-IP-Address = c0 0 2 26 (192.0.2.38)
-      NAS-Port-Type = 5 (Virtual)
-      User-Name = 12345678
-      Digest-Response = f3ce87e6984557cd0fecc26f3c5e97a4
-      Digest-Realm = example.com
-      Digest-Nonce = 3bada1a0
-      Digest-Method = INVITE
-      Digest-URI = sip:97226491335@example.com
-      Digest-Qop = auth
-      Digest-Algorithm = md5
-      Digest-Username =  12345678
-      SIP-AOR =  sip:12345678@example.com
-      Message-Authenticator =
-          ff 67 f4 13 8e b8 59 32 22 f9 37 0f 32 f8 e0 ff
-
-   C->B
-
-      Code = 2 (Access-Accept)
-      Attributes:
-      Digest-Response-Auth =
-                      6303c41b0e2c3e524e413cafe8cce954
-      Message-Authenticator =
-          75 8d 44 49 66 1f 7b 47 9d 10 d0 2d 4a 2e aa f1
-
-   B->A
-
-      SIP/2.0 180 Ringing
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 24]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   B->A
-
-      SIP/2.0 200 OK
-
-   A->B
-
-      ACK sip:97226491335@example.com SIP/2.0
-
-   A second example shows the traffic between a web browser (A), web
-   server (B), and a RADIUS server (C).
-
-   A->B
-
-      GET /index.html HTTP/1.1
-
-   B->C
-
-      Code = 1 (Access-Request)
-      Attributes:
-      NAS-IP-Address = c0 0 2 26 (192.0.2.38)
-      NAS-Port-Type = 5 (Virtual)
-      Digest-Method = GET
-      Digest-URI = /index.html
-      Message-Authenticator =
-       34 a6 26 46 f3 81 f9 b4 97 c0 dd 9d 11 8f ca c7
-
-   C->B
-
-      Code = 11 (Access-Challenge)
-      Attributes:
-      Digest-Nonce = a3086ac8
-      Digest-Realm = example.com
-      Digest-Qop = auth
-      Digest-Algorithm = MD5
-      Message-Authenticator =
-       f8 01 26 9f 70 5e ef 5d 24 ac f5 ca fb 27 da 40
-
-   B->A
-
-      HTTP/1.1 401 Authentication Required
-      WWW-Authenticate: Digest realm="example.com",
-          nonce="a3086ac8",qop=auth,algorithm=MD5
-      Content-Length: 0
-
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 25]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   A->B
-
-      GET /index.html HTTP/1.1
-      Authorization: Digest algorithm=MD5,nonce="a3086ac8"
-           ,realm="example.com"
-           ,response="f052b68058b2987aba493857ae1ab002"
-           ,uri="/index.html",username="12345678"
-           ,qop=auth,algorithm=MD5
-
-   B->C
-
-      Code = 1 (Access-Request)
-      Attributes:
-      NAS-IP-Address = c0 0 2 26 (192.0.2.38)
-      NAS-Port-Type = 5 (Virtual)
-      User-Name = 12345678
-      Digest-Response = f052b68058b2987aba493857ae1ab002
-      Digest-Realm = example.com
-      Digest-Nonce = a3086ac8
-      Digest-Method = GET
-      Digest-URI = /index.html
-      Digest-Username =  12345678
-      Digest-Qop = auth
-      Digest-Algorithm = MD5
-      Message-Authenticator =
-          06 e1 65 23 57 94 e6 de 87 5a e8 ce a2 7d 43 6b
-
-   C->B
-
-      Code = 2 (Access-Accept)
-      Attributes:
-      Digest-Response-Auth =
-          e644aa513effbfe1caff67103ff6433c
-      Message-Authenticator =
-          7a 66 73 a3 52 44 dd ca 90 e2 f6 10 61 2d 81 d7
-
-   B->A
-
-      HTTP/1.1 200 OK
-      ...
-
-      <html>
-      ...
-
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 26]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-7.  IANA Considerations
-
-   This document serves as an IANA registration request for a number of
-   values from the RADIUS attribute type number space.  The IANA has
-   assigned the following:
-
-           +-------------------------+------------------------+
-           | placeholder             | value assigned by IANA |
-           +-------------------------+------------------------+
-           | Digest-Response         | 103                    |
-           | Digest-Realm            | 104                    |
-           | Digest-Nonce            | 105                    |
-           | Digest-Nextnonce        | 106                    |
-           | Digest-Response-Auth    | 107                    |
-           | Digest-Method           | 108                    |
-           | Digest-URI              | 109                    |
-           | Digest-Qop              | 110                    |
-           | Digest-Algorithm        | 111                    |
-           | Digest-Entity-Body-Hash | 112                    |
-           | Digest-CNonce           | 113                    |
-           | Digest-Nonce-Count      | 114                    |
-           | Digest-Username         | 115                    |
-           | Digest-Opaque           | 116                    |
-           | Digest-Auth-Param       | 117                    |
-           | Digest-AKA-Auts         | 118                    |
-           | Digest-Domain           | 119                    |
-           | Digest-Stale            | 120                    |
-           | Digest-HA1              | 121                    |
-           | SIP-AOR                 | 122                    |
-           +-------------------------+------------------------+
-
-                                  Table 2
-
-8.  Security Considerations
-
-   The RADIUS extensions described in this document enable RADIUS to
-   transport the data that is required to perform a digest calculation.
-   As a result, RADIUS inherits the vulnerabilities of HTTP Digest (see
-   [RFC2617], section 4) in addition to RADIUS security vulnerabilities
-   described in [RFC2865], section 8, and [RFC3579], section 4.
-
-   An attacker compromising a RADIUS client or proxy can carry out
-   man-in-the-middle attacks even if the paths between A, B and B, C
-   (Figure 2) have been secured with TLS or IPsec.
-
-   The RADIUS server MUST check the Digest-Realm attribute it has
-   received from a client.  If the RADIUS client is not authorized to
-   serve HTTP-style clients of that realm, it might be compromised.
-
-
-
-Sterman, et al.             Standards Track                    [Page 27]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-8.1.  Denial of Service
-
-   RADIUS clients implementing the extension described in this document
-   may authenticate HTTP-style requests received over the Internet.  As
-   compared with the use of RADIUS to authenticate link-layer network
-   access, attackers may find it easier to cover their tracks in such a
-   scenario.
-
-   An attacker can attempt a denial-of-service attack on one or more
-   RADIUS servers by sending a large number of HTTP-style requests.  To
-   make simple denial-of-service attacks more difficult, the RADIUS
-   server MUST check whether it has generated the nonce received from an
-   HTTP-style client.  This SHOULD be done statelessly.  For example, a
-   nonce could consist of a cryptographically random part and some kind
-   of signature provided by the RADIUS client, as described in
-   [RFC2617], section 3.2.1.
-
-8.2.  Confidentiality and Data Integrity
-
-   The attributes described in this document are sent in cleartext.
-   RADIUS servers SHOULD include Digest-Qop and Digest-Algorithm
-   attributes in Access-Challenge messages.  A man in the middle can
-   modify or remove those attributes in a bidding down attack, causing
-   the RADIUS client to use a weaker authentication scheme than
-   intended.
-
-   The Message-Authenticator attribute, described in [RFC3579], section
-   3.2 MUST be included in Access-Request, Access-Challenge,
-   Access-Reject, and Access-Accept messages that contain attributes
-   described in this specification.
-
-   The Digest-HA1 attribute contains no random components if the
-   algorithm is 'MD5' or 'AKAv1-MD5'.  This makes offline dictionary
-   attacks easier and enables replay attacks.
-
-   Some parameter combinations require the protection of RADIUS packets
-   against eavesdropping and tampering.  Implementations SHOULD try to
-   determine automatically whether IPsec is configured to protect
-   traffic between the RADIUS client and the RADIUS server.  If this is
-   not possible, the implementation checks a configuration parameter
-   telling it whether IPsec will protect RADIUS traffic.  The default
-   value of this configuration parameter tells the implementation that
-   RADIUS packets will not be protected.
-
-   HTTP-style clients can use TLS with server side certificates together
-   with HTTP-Digest Authentication.  Instead of TLS, IPsec can be used,
-   too.  TLS or IPsec secure the connection while Digest Authentication
-   authenticates the user.  The RADIUS transaction can be regarded as
-
-
-
-Sterman, et al.             Standards Track                    [Page 28]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   one leg on the path between the HTTP-style client and the HTTP-style
-   server.  To prevent RADIUS from representing the weak link, a RADIUS
-   client receiving an HTTP-style request via TLS or IPsec could use an
-   equally secure connection to the RADIUS server.  There are several
-   ways to achieve this, for example:
-
-   o  The RADIUS client may reject HTTP-style requests received over TLS
-      or IPsec.
-
-   o  The RADIUS client may require that traffic be sent and received
-      over IPsec.
-
-   RADIUS over IPsec, if used, MUST conform to the requirements
-   described in [RFC3579], section 4.2.
-
-9.  Acknowledgements
-
-   We would like to acknowledge Kevin McDermott (Cisco Systems) for
-   providing comments and experimental implementation.
-
-   Many thanks to all reviewers, especially to Miguel Garcia, Jari
-   Arkko, Avi Lior, and Jun Wang.
-
-10.  References
-
-10.1.  Normative References
-
-   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
-              Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-   [RFC2617]  Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S.,
-              Leach, P., Luotonen, A., and L. Stewart, "HTTP
-              Authentication: Basic and Digest Access Authentication",
-              RFC 2617, June 1999.
-
-   [RFC2865]  Rigney, C., Willens, S., Rubens, A., and W. Simpson,
-              "Remote Authentication Dial In User Service (RADIUS)", RFC
-              2865, June 2000.
-
-   [RFC3261]  Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston,
-              A., Peterson, J., Sparks, R., Handley, M., and E.
-              Schooler, "SIP: Session Initiation Protocol", RFC 3261,
-              June 2002.
-
-   [RFC3579]  Aboba, B. and P. Calhoun, "RADIUS (Remote Authentication
-              Dial In User Service) Support For Extensible
-              Authentication Protocol (EAP)", RFC 3579, September 2003.
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 29]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-   [RFC3966]  Schulzrinne, H., "The tel URI for Telephone Numbers", RFC
-              3966, December 2004.
-
-10.2.  Informative References
-
-   [SIP-APP]  Garcia-Martin, M., "Diameter Session Initiation Protocol
-              (SIP) Application", Work in Progress), April 2006.
-
-   [RFC1994]  Simpson, W., "PPP Challenge Handshake Authentication
-              Protocol (CHAP)", RFC 1994, August 1996.
-
-   [RFC2069]  Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
-              Luotonen, A., Sink, E., and L. Stewart, "An Extension to
-              HTTP : Digest Access Authentication", RFC 2069, January
-              1997.
-
-   [RFC4346]  Dierks, T. and E. Rescorla, "The Transport Layer Security
-              (TLS) Protocol Version 1.1", RFC 4346, April 2006.
-
-   [RFC3851]  Ramsdell, B., "Secure/Multipurpose Internet Mail
-              Extensions (S/MIME) Version 3.1 Message Specification",
-              RFC 3851, July 2004.
-
-   [RFC3310]  Niemi, A., Arkko, J., and V. Torvinen, "Hypertext Transfer
-              Protocol (HTTP) Digest Authentication Using Authentication
-              and Key Agreement (AKA)", RFC 3310, September 2002.
-
-   [RFC3588]  Calhoun, P., Loughney, J., Guttman, E., Zorn, G., and J.
-              Arkko, "Diameter Base Protocol", RFC 3588, September 2003.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 30]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-Authors' Addresses
-
-   Baruch Sterman
-   Kayote Networks
-   P.O. Box 1373
-   Efrat  90435
-   Israel
-
-   EMail: baruch@kayote.com
-
-
-   Daniel Sadolevsky
-   SecureOL, Inc.
-   Jerusalem Technology Park
-   P.O. Box 16120
-   Jerusalem  91160
-   Israel
-
-   EMail: dscreat@dscreat.com
-
-
-   David Schwartz
-   Kayote Networks
-   P.O. Box 1373
-   Efrat  90435
-   Israel
-
-   EMail: david@kayote.com
-
-
-   David Williams
-   Cisco Systems
-   7025 Kit Creek Road
-   P.O. Box 14987
-   Research Triangle Park  NC 27709
-   USA
-
-   EMail: dwilli@cisco.com
-
-
-   Wolfgang Beck
-   Deutsche Telekom AG
-   Deutsche Telekom Allee 7
-   Darmstadt  64295
-   Germany
-
-   EMail: beckw@t-systems.com
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 31]
-\f
-RFC 4590              RADIUS Digest Authentication             July 2006
-
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (2006).
-
-   This document is subject to the rights, licenses and restrictions
-   contained in BCP 78, and except as set forth therein, the authors
-   retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
-   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
-   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at
-   ietf-ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is provided by the IETF
-   Administrative Support Activity (IASA).
-
-
-
-
-
-
-
-Sterman, et al.             Standards Track                    [Page 32]
-\f
diff --git a/doc/rfc/rfc4675.txt b/doc/rfc/rfc4675.txt
deleted file mode 100644 (file)
index 41ca11d..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         P. Congdon
-Request for Comments: 4675                                    M. Sanchez
-Category: Standards Track                        Hewlett-Packard Company
-                                                                B. Aboba
-                                                   Microsoft Corporation
-                                                          September 2006
-
-
-         RADIUS Attributes for Virtual LAN and Priority Support
-
-Status of This Memo
-
-   This document specifies an Internet standards track protocol for the
-   Internet community, and requests discussion and suggestions for
-   improvements.  Please refer to the current edition of the "Internet
-   Official Protocol Standards" (STD 1) for the standardization state
-   and status of this protocol.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (2006).
-
-Abstract
-
-   This document proposes additional Remote Authentication Dial-In User
-   Service (RADIUS) attributes for dynamic Virtual LAN assignment and
-   prioritization, for use in provisioning of access to IEEE 802 local
-   area networks.  These attributes are usable within either RADIUS or
-   Diameter.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 1]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-Table of Contents
-
-   1. Introduction ....................................................3
-      1.1. Terminology ................................................3
-      1.2. Requirements Language ......................................3
-      1.3. Attribute Interpretation ...................................3
-   2. Attributes ......................................................4
-      2.1. Egress-VLANID ..............................................4
-      2.2. Ingress-Filters ............................................6
-      2.3. Egress-VLAN-Name ...........................................7
-      2.4. User-Priority-Table ........................................8
-   3. Table of Attributes ............................................10
-   4. Diameter Considerations ........................................10
-   5. IANA Considerations ............................................11
-   6. Security Considerations ........................................11
-   7. References .....................................................12
-      7.1. Normative References ......................................12
-      7.2. Informative References ....................................13
-   8. Acknowledgements ...............................................13
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 2]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-1.  Introduction
-
-   This document describes Virtual LAN (VLAN) and re-prioritization
-   attributes that may prove useful for provisioning of access to IEEE
-   802 local area networks [IEEE-802] with the Remote Authentication
-   Dial-In User Service (RADIUS) or Diameter.
-
-   While [RFC3580] enables support for VLAN assignment based on the
-   tunnel attributes defined in [RFC2868], it does not provide support
-   for a more complete set of VLAN functionality as defined by
-   [IEEE-802.1Q].  The attributes defined in this document provide
-   support within RADIUS and Diameter analogous to the management
-   variables supported in [IEEE-802.1Q] and MIB objects defined in
-   [RFC4363].  In addition, this document enables support for a wider
-   range of [IEEE-802.1X] configurations.
-
-1.1.  Terminology
-
-   This document uses the following terms:
-
-   Network Access Server (NAS)
-        A device that provides an access service for a user to a
-        network.  Also known as a RADIUS client.
-
-   RADIUS server
-        A RADIUS authentication server is an entity that provides an
-        authentication service to a NAS.
-
-   RADIUS proxy
-        A RADIUS proxy acts as an authentication server to the NAS, and
-        a RADIUS client to the RADIUS server.
-
-1.2.  Requirements Language
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in [RFC2119].
-
-1.3.  Attribute Interpretation
-
-   The attributes described in this document apply to a single instance
-   of a NAS port, or more specifically an IEEE 802.1Q bridge port.
-   [IEEE-802.1Q], [IEEE-802.1D], and [IEEE-802.1X] do not recognize
-   finer management granularity than "per port".  In some cases, such as
-   with IEEE 802.11 wireless LANs, the concept of a "virtual port" is
-   used in place of the physical port.  Such virtual ports are typically
-   based on security associations and scoped by station, or Media Access
-   Control (MAC) address.
-
-
-
-Congdon, et al.             Standards Track                     [Page 3]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-   The attributes defined in this document are applied on a per-user
-   basis and it is expected that there is a single user per port;
-   however, in some cases that port may be a "virtual port".  If a NAS
-   implementation conforming to this document supports "virtual ports",
-   it may be possible to provision those "virtual ports" with unique
-   values of the attributes described in this document, allowing
-   multiple users sharing the same physical port to each have a unique
-   set of authorization parameters.
-
-   If a NAS conforming to this specification receives an Access-Accept
-   packet containing an attribute defined in this document that it
-   cannot apply, it MUST act as though it had received an Access-Reject.
-   [RFC3576] requires that a NAS receiving a Change of Authorization
-   Request (CoA-Request) reply with a CoA-NAK if the Request contains an
-   unsupported attribute.  It is recommended that an Error-Cause
-   attribute with the value set to "Unsupported Attribute" (401) be
-   included in the CoA-NAK.  As noted in [RFC3576], authorization
-   changes are atomic so that this situation does not result in session
-   termination and the preexisting configuration remains unchanged.  As
-   a result, no accounting packets should be generated.
-
-2.  Attributes
-
-2.1.  Egress-VLANID
-
-   Description
-
-      The Egress-VLANID attribute represents an allowed IEEE 802 Egress
-      VLANID for this port, indicating if the VLANID is allowed for
-      tagged or untagged frames as well as the VLANID.
-
-      As defined in [RFC3580], the VLAN assigned via tunnel attributes
-      applies both to the ingress VLANID for untagged packets (known as
-      the PVID) and the egress VLANID for untagged packets.  In
-      contrast, the Egress-VLANID attribute configures only the egress
-      VLANID for either tagged or untagged packets.  The Egress-VLANID
-      attribute MAY be included in the same RADIUS packet as [RFC3580]
-      tunnel attributes; however, the Egress-VLANID attribute is not
-      necessary if it is being used to configure the same untagged
-      VLANID included in tunnel attributes.  To configure an untagged
-      VLAN for both ingress and egress, the tunnel attributes of
-      [RFC3580] MUST be used.
-
-      Multiple Egress-VLANID attributes MAY be included in Access-
-      Request, Access-Accept, CoA-Request, or Accounting-Request
-      packets; this attribute MUST NOT be sent within an Access-
-      Challenge, Access-Reject, Disconnect-Request, Disconnect-ACK,
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 4]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-      Disconnect-NAK, CoA-ACK, or CoA-NAK.  Each attribute adds the
-      specified VLAN to the list of allowed egress VLANs for the port.
-
-      The Egress-VLANID attribute is shown below.  The fields are
-      transmitted from left to right:
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |     Type      |    Length     |            Value
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont)            |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      56
-
-   Length
-
-      6
-
-   Value
-
-      The Value field is four octets.  The format is described below:
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |  Tag Indic.   |        Pad            |       VLANID          |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-      The Tag Indication field is one octet in length and indicates
-      whether the frames on the VLAN are tagged (0x31) or untagged
-      (0x32).  The Pad field is 12 bits in length and MUST be 0 (zero).
-      The VLANID is 12 bits in length and contains the [IEEE-802.1Q]
-      VLAN VID value.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 5]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-2.2.  Ingress-Filters
-
-   Description
-
-      The Ingress-Filters attribute corresponds to the Ingress Filter
-      per-port variable defined in [IEEE-802.1Q] clause 8.4.5.  When the
-      attribute has the value "Enabled", the set of VLANs that are
-      allowed to ingress a port must match the set of VLANs that are
-      allowed to egress a port.  Only a single Ingress-Filters attribute
-      MAY be sent within an Access-Request, Access-Accept, CoA-Request,
-      or Accounting-Request packet; this attribute MUST NOT be sent
-      within an Access-Challenge, Access-Reject, Disconnect-Request,
-      Disconnect-ACK, Disconnect-NAK, CoA-ACK, or CoA-NAK.
-
-      The Ingress-Filters attribute is shown below.  The fields are
-      transmitted from left to right:
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |     Type      |    Length     |         Value
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont)            |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      57
-
-   Length
-
-      6
-
-   Value
-
-      The Value field is four octets.  Supported values include:
-
-      1 - Enabled
-      2 - Disabled
-
-
-
-
-
-
-
-
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 6]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-2.3.  Egress-VLAN-Name
-
-   Description
-
-      Clause 12.10.2.1.3 (a) in [IEEE-802.1Q] describes the
-      administratively assigned VLAN Name associated with a VLAN-ID
-      defined within an IEEE 802.1Q bridge.  The Egress-VLAN-Name
-      attribute represents an allowed VLAN for this port.  It is similar
-      to the Egress-VLANID attribute, except that the VLAN-ID itself is
-      not specified or known; rather, the VLAN name is used to identify
-      the VLAN within the system.
-
-      The tunnel attributes described in [RFC3580] and the Egress-VLAN-
-      Name attribute both can be used to configure the egress VLAN for
-      untagged packets.  These attributes can be used concurrently and
-      MAY appear in the same RADIUS packet.  When they do appear
-      concurrently, the list of allowed VLANs is the concatenation of
-      the Egress-VLAN-Name and the Tunnel-Private-Group-ID (81)
-      attributes.  The Egress-VLAN-Name attribute does not alter the
-      ingress VLAN for untagged traffic on a port (also known as the
-      PVID).  The tunnel attributes from [RFC3580] should be relied upon
-      instead to set the PVID.
-
-      The Egress-VLAN-Name attribute contains two parts; the first part
-      indicates if frames on the VLAN for this port are to be
-      represented in tagged or untagged format, the second part is the
-      VLAN name.
-
-      Multiple Egress-VLAN-Name attributes MAY be included within an
-      Access-Request, Access-Accept, CoA-Request, or Accounting-Request
-      packet; this attribute MUST NOT be sent within an Access-
-      Challenge, Access-Reject, Disconnect-Request, Disconnect-ACK,
-      Disconnect-NAK, CoA-ACK, or CoA-NAK.  Each attribute adds the
-      named VLAN to the list of allowed egress VLANs for the port.  The
-      Egress-VLAN-Name attribute is shown below.  The fields are
-      transmitted from left to right:
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |     Type      |    Length     |   Tag Indic.  |   String...
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      58
-
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 7]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-   Length
-
-      >=4
-
-   Tag Indication
-
-      The Tag Indication field is one octet in length and indicates
-      whether the frames on the VLAN are tagged (0x31, ASCII '1') or
-      untagged (0x32, ASCII '2').  These values were chosen so as to
-      make them easier for users to enter.
-
-   String
-
-      The String field is at least one octet in length and contains the
-      VLAN Name as defined in [IEEE-802.1Q] clause 12.10.2.1.3 (a).
-      [RFC3629] UTF-8 encoded 10646 characters are RECOMMENDED, but a
-      robust implementation SHOULD support the field as undistinguished
-      octets.
-
-2.4.  User-Priority-Table
-
-   Description
-
-      [IEEE-802.1D] clause 7.5.1 discusses how to regenerate (or re-map)
-      user priority on frames received at a port.  This per-port
-      configuration enables a bridge to cause the priority of received
-      traffic at a port to be mapped to a particular priority.
-      [IEEE-802.1D] clause 6.3.9 describes the use of remapping:
-
-         The ability to signal user priority in IEEE 802 LANs allows
-         user priority to be carried with end-to-end significance across
-         a Bridged Local Area Network.  This, coupled with a consistent
-         approach to the mapping of user priority to traffic classes and
-         of user priority to access_priority, allows consistent use of
-         priority information, according to the capabilities of the
-         Bridges and MACs in the transmission path...
-
-         Under normal circumstances, user priority is not modified in
-         transit through the relay function of a Bridge; however,
-         network management can control how user priority is propagated.
-         Table 7-1 provides the ability to map incoming user priority
-         values on a per-Port basis.  By default, the regenerated user
-         priority is identical to the incoming user priority.
-
-      This attribute represents the IEEE 802 prioritization that will be
-      applied to frames arriving at this port.  There are eight possible
-      user priorities, according to the [IEEE-802] standard.
-      [IEEE-802.1D] clause 14.6.2.3.3 specifies the regeneration table
-
-
-
-Congdon, et al.             Standards Track                     [Page 8]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-      as 8 values, each an integer in the range 0-7.  The management
-      variables are described in clause 14.6.2.2.
-
-      A single User-Priority-Table attribute MAY be included in an
-      Access-Accept or CoA-Request packet; this attribute MUST NOT be
-      sent within an Access-Request, Access-Challenge, Access-Reject,
-      Disconnect-Request, Disconnect-ACK, Disconnect-NAK, CoA-ACK, CoA-
-      NAK or Accounting-Request.  Since the regeneration table is only
-      maintained by a bridge conforming to [IEEE-802.1D], this attribute
-      should only be sent to a RADIUS client supporting that
-      specification.
-
-      The User-Priority-Table attribute is shown below.  The fields are
-      transmitted from left to right:
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |     Type      |  Length       |          String
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                    String
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                    String            |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      59
-
-   Length
-
-      10
-
-   String
-
-      The String field is 8 octets in length and includes a table that
-      maps the incoming priority (if it is set -- the default is 0) into
-      one of eight regenerated priorities.  The first octet maps to
-      incoming priority 0, the second octet to incoming priority 1, etc.
-      The values in each octet represent the regenerated priority of the
-      frame.
-
-      It is thus possible to either remap incoming priorities to more
-      appropriate values; to honor the incoming priorities; or to
-      override any incoming priorities, forcing them to all map to a
-      single chosen priority.
-
-
-
-
-
-Congdon, et al.             Standards Track                     [Page 9]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-      The [IEEE-802.1D] specification, Annex G, provides a useful
-      description of traffic type - traffic class mappings.
-
-3.  Table of Attributes
-
-   The following table provides a guide to which attributes may be found
-   in which kinds of packets, and in what quantity.
-
-   Access- Access- Access- Access-   CoA-  Acct-
-   Request Accept  Reject  Challenge Req   Req   #   Attribute
-    0+      0+      0       0        0+    0+   56   Egress-VLANID
-    0-1     0-1     0       0        0-1   0-1  57   Ingress-Filters
-    0+      0+      0       0        0+    0+   58   Egress-VLAN-Name
-    0       0-1     0       0        0-1   0    59   User-Priority-Table
-
-   The following table defines the meaning of the above table entries.
-
-     0     This attribute MUST NOT be present in the packet.
-     0+    Zero or more instances of this attribute MAY be
-           present in the packet.
-     0-1   Zero or one instance of this attribute MAY be
-           present in the packet.
-
-4.  Diameter Considerations
-
-   When used in Diameter, the attributes defined in this specification
-   can be used as Diameter attribute-value pair (AVPs) from the Code
-   space 1-255 (RADIUS attribute compatibility space).  No additional
-   Diameter Code values are therefore allocated.  The data types and
-   flag rules for the attributes are as follows:
-
-                                  +---------------------+
-                                  |    AVP Flag rules   |
-                                  |----+-----+----+-----|----+
-                                  |    |     |SHLD| MUST|    |
-   Attribute Name      Value Type |MUST| MAY | NOT|  NOT|Encr|
-   -------------------------------|----+-----+----+-----|----|
-   Egress-VLANID       OctetString| M  |  P  |    |  V  | Y  |
-   Ingress-Filters     Enumerated | M  |  P  |    |  V  | Y  |
-   Egress-VLAN-Name    UTF8String | M  |  P  |    |  V  | Y  |
-   User-Priority-Table OctetString| M  |  P  |    |  V  | Y  |
-   -------------------------------|----+-----+----+-----|----|
-
-   The attributes in this specification have no special translation
-   requirements for Diameter to RADIUS or RADIUS to Diameter gateways;
-   they are copied as is, except for changes relating to headers,
-   alignment, and padding.  See also [RFC3588] Section 4.1 and [RFC4005]
-   Section 9.
-
-
-
-Congdon, et al.             Standards Track                    [Page 10]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-   What this specification says about the applicability of the
-   attributes for RADIUS Access-Request packets applies in Diameter to
-   AA-Request [RFC4005] or Diameter-EAP-Request [RFC4072].  What is said
-   about Access-Challenge applies in Diameter to AA-Answer [RFC4005] or
-   Diameter-EAP-Answer [RFC4072] with Result-Code AVP set to
-   DIAMETER_MULTI_ROUND_AUTH.
-
-   What is said about Access-Accept applies in Diameter to AA-Answer or
-   Diameter-EAP-Answer messages that indicate success.  Similarly, what
-   is said about RADIUS Access-Reject packets applies in Diameter to
-   AA-Answer or Diameter-EAP-Answer messages that indicate failure.
-
-   What is said about COA-Request applies in Diameter to Re-Auth-Request
-   [RFC4005].
-
-   What is said about Accounting-Request applies to Diameter
-   Accounting-Request [RFC4005] as well.
-
-5.  IANA Considerations
-
-   This specification does not create any new registries.
-
-   This document uses the RADIUS [RFC2865] namespace; see
-   <http://www.iana.org/assignments/radius-types>.  Allocation of four
-   updates for the section "RADIUS Attribute Types" has been made by the
-   IANA.  The RADIUS attributes are:
-
-   56 - Egress-VLANID
-   57 - Ingress-Filters
-   58 - Egress-VLAN-Name
-   59 - User-Priority-Table
-
-6.  Security Considerations
-
-   This specification describes the use of RADIUS and Diameter for
-   purposes of authentication, authorization, and accounting in IEEE 802
-   local area networks.  RADIUS threats and security issues for this
-   application are described in [RFC3579] and [RFC3580]; security issues
-   encountered in roaming are described in [RFC2607].  For Diameter, the
-   security issues relating to this application are described in
-   [RFC4005] and [RFC4072].
-
-   This document specifies new attributes that can be included in
-   existing RADIUS packets, which are protected as described in
-   [RFC3579] and [RFC3576].  In Diameter, the attributes are protected
-   as specified in [RFC3588].  See those documents for a more detailed
-   description.
-
-
-
-
-Congdon, et al.             Standards Track                    [Page 11]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-   The security mechanisms supported in RADIUS and Diameter are focused
-   on preventing an attacker from spoofing packets or modifying packets
-   in transit.  They do not prevent an authorized RADIUS/Diameter server
-   or proxy from inserting attributes with malicious intent.
-
-   VLAN attributes sent by a RADIUS/Diameter server or proxy may enable
-   access to unauthorized VLANs.  These vulnerabilities can be limited
-   by performing authorization checks at the NAS.  For example, a NAS
-   can be configured to accept only certain VLANIDs from a given
-   RADIUS/Diameter server/proxy.
-
-   Similarly, an attacker gaining control of a RADIUS/Diameter server or
-   proxy can modify the user priority table, causing either degradation
-   of quality of service (by downgrading user priority of frames
-   arriving at a port), or denial of service (by raising the level of
-   priority of traffic at multiple ports of a device, oversubscribing
-   the switch or link capabilities).
-
-7.  References
-
-7.1.  Normative References
-
-   [RFC2119]     Bradner, S., "Key words for use in RFCs to Indicate
-                 Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-   [RFC2865]     Rigney, C., Willens, S., Rubens, A., and W. Simpson,
-                 "Remote Authentication Dial In User Service (RADIUS)",
-                 RFC 2865, June 2000.
-
-   [RFC3588]     Calhoun, P., Loughney, J., Guttman, E., Zorn, G., and
-                 J. Arkko, "Diameter Base Protocol", RFC 3588, September
-                 2003.
-
-   [RFC3629]     Yergeau, F., "UTF-8, a transformation format of ISO
-                 10646", STD 63, RFC 3629, November 2003.
-
-   [RFC4363]     Levi, D. and D. Harrington, "Definitions of Managed
-                 Objects for Bridges with Traffic Classes, Multicast
-                 Filtering, and Virtual LAN Extensions", RFC 4363,
-                 January 2006.
-
-   [IEEE-802]    IEEE Standards for Local and Metropolitan Area
-                 Networks:  Overview and Architecture, ANSI/IEEE Std
-                 802, 1990.
-
-   [IEEE-802.1D] IEEE Standards for Local and Metropolitan Area
-                 Networks: Media Access Control (MAC) Bridges, IEEE Std
-                 802.1D-2004, June 2004.
-
-
-
-Congdon, et al.             Standards Track                    [Page 12]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-   [IEEE-802.1Q] IEEE Standards for Local and Metropolitan Area
-                 Networks: Draft Standard for Virtual Bridged Local Area
-                 Networks, P802.1Q-2003, January 2003.
-
-7.2.  Informative References
-
-   [IEEE-802.1X] IEEE Standards for Local and Metropolitan Area
-                 Networks: Port based Network Access Control, IEEE Std
-                 802.1X-2004, December 2004.
-
-   [RFC2607]     Aboba, B. and J. Vollbrecht, "Proxy Chaining and Policy
-                 Implementation in Roaming", RFC 2607, June 1999.
-
-   [RFC2868]     Zorn, G., Leifer, D., Rubens, A., Shriver, J.,
-                 Holdrege, M., and I. Goyret, "RADIUS Attributes for
-                 Tunnel Protocol Support", RFC 2868, June 2000.
-
-   [RFC3576]     Chiba, M., Dommety, G., Eklund, M., Mitton, D., and B.
-                 Aboba, "Dynamic Authorization Extensions to Remote
-                 Authentication Dial In User Service (RADIUS)", RFC
-                 3576, July 2003.
-
-   [RFC3579]     Aboba, B. and P. Calhoun, "RADIUS (Remote
-                 Authentication Dial In User Service) Support For
-                 Extensible Authentication Protocol (EAP)", RFC 3579,
-                 September 2003.
-
-   [RFC3580]     Congdon, P., Aboba, B., Smith, A., Zorn, G., and J.
-                 Roese, "IEEE 802.1X Remote Authentication Dial In User
-                 Service (RADIUS) Usage Guidelines", RFC 3580, September
-                 2003.
-
-   [RFC4005]     Calhoun, P., Zorn, G., Spence, D., and D. Mitton,
-                 "Diameter Network Access Server Application", RFC 4005,
-                 August 2005.
-
-   [RFC4072]     Eronen, P., Hiller, T., and G. Zorn, "Diameter
-                 Extensible Authentication Protocol (EAP) Application",
-                 RFC 4072, August 2005.
-
-8.  Acknowledgements
-
-   The authors would like to acknowledge Joseph Salowey of Cisco, David
-   Nelson of Enterasys, Chuck Black of Hewlett-Packard, and Ashwin
-   Palekar of Microsoft.
-
-
-
-
-
-
-Congdon, et al.             Standards Track                    [Page 13]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-Authors' Addresses
-
-   Paul Congdon
-   Hewlett-Packard Company
-   HP ProCurve Networking
-   8000 Foothills Blvd, M/S 5662
-   Roseville, CA  95747
-
-   Phone: +1 916 785 5753
-   Fax:   +1 916 785 8478
-   EMail: paul.congdon@hp.com
-
-
-   Mauricio Sanchez
-   Hewlett-Packard Company
-   HP ProCurve Networking
-   8000 Foothills Blvd, M/S 5559
-   Roseville, CA  95747
-
-   Phone: +1 916 785 1910
-   Fax:   +1 916 785 1815
-   EMail: mauricio.sanchez@hp.com
-
-
-   Bernard Aboba
-   Microsoft Corporation
-   One Microsoft Way
-   Redmond, WA 98052
-
-   Phone: +1 425 706 6605
-   Fax:   +1 425 936 7329
-   EMail: bernarda@microsoft.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Congdon, et al.             Standards Track                    [Page 14]
-\f
-RFC 4675              VLAN and Priority Attributes        September 2006
-
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (2006).
-
-   This document is subject to the rights, licenses and restrictions
-   contained in BCP 78, and except as set forth therein, the authors
-   retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
-   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
-   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at
-   ietf-ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is provided by the IETF
-   Administrative Support Activity (IASA).
-
-
-
-
-
-
-
-Congdon, et al.             Standards Track                    [Page 15]
-\f
diff --git a/doc/rfc/rfc4679.txt b/doc/rfc/rfc4679.txt
deleted file mode 100644 (file)
index 9dfcb59..0000000
+++ /dev/null
@@ -1,1403 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                       V. Mammoliti
-Request for Comments: 4679                                       G. Zorn
-Category: Informational                                    Cisco Systems
-                                                               P. Arberg
-                                                  Redback Networks, Inc.
-                                                             R. Rennison
-                                                             ECI Telecom
-                                                          September 2006
-
-
-              DSL Forum Vendor-Specific RADIUS Attributes
-
-Status of this Memo
-
-   This memo provides information for the Internet community.  It does
-   not specify an Internet standard of any kind.  Distribution of this
-   memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (2006).
-
-IESG Note
-
-   This RFC is not a candidate for any level of Internet Standard.  The
-   IETF disclaims any knowledge of the fitness of this RFC for any
-   purpose and in particular notes that the decision to publish is not
-   based on IETF review for such things as security, congestion control,
-   or inappropriate interaction with deployed protocols.  The RFC Editor
-   has chosen to publish this document at its discretion.  Readers of
-   this document should exercise caution in evaluating its value for
-   implementation and deployment.  See RFC 3932 for more information.
-
-Abstract
-
-   This document describes the set of Remote Authentication Dial-In User
-   Service Vendor-Specific Attributes (RADIUS VSAs) defined by the DSL
-   Forum.
-
-   These attributes are designed to transport Digital Subscriber Line
-   (DSL) information that is not supported by the standard RADIUS
-   attribute set.  It is expected that this document will be updated if
-   and when the DSL Forum defines additional vendor-specific attributes,
-   since its primary purpose is to provide a reference for DSL equipment
-   vendors wishing to interoperate with other vendors' products.
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 1]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-Table of Contents
-
-   1. Introduction ....................................................3
-   2. Terminology .....................................................3
-      2.1. Requirements Language ......................................3
-      2.2. Technical Terms and Acronyms ...............................3
-   3. Attributes ......................................................5
-      3.1. DSL Forum RADIUS VSA Definition ............................5
-      3.2. DSL Forum Vendor Specific Sub-Attribute Encoding ...........6
-      3.3. Sub-attribute Definitions ..................................6
-           3.3.1. Agent-Circuit-Id ....................................6
-           3.3.2. Agent-Remote-Id .....................................8
-           3.3.3. Actual-Data-Rate-Upstream ...........................9
-           3.3.4. Actual-Data-Rate-Downstream .........................9
-           3.3.5. Minimum-Data-Rate-Upstream .........................10
-           3.3.6. Minimum-Data-Rate-Downstream .......................11
-           3.3.7. Attainable-Data-Rate-Upstream ......................11
-           3.3.8. Attainable-Data-Rate-Downstream ....................12
-           3.3.9. Maximum-Data-Rate-Upstream .........................13
-           3.3.10. Maximum-Data-Rate-Downstream ......................13
-           3.3.11. Minimum-Data-Rate-Upstream-Low-Power ..............14
-           3.3.12. Minimum-Data-Rate-Downstream-Low-Power ............15
-           3.3.13. Maximum-Interleaving-Delay-Upstream ...............16
-           3.3.14. Actual-Interleaving-Delay-Upstream ................16
-           3.3.15. Maximum-Interleaving-Delay-Downstream .............17
-           3.3.16. Actual-Interleaving-Delay-Downstream ..............18
-           3.3.17. Access-Loop-Encapsulation .........................19
-           3.3.18. IWF-Session .......................................20
-   4. Table of Attributes ............................................21
-   5. Security Considerations ........................................21
-   6. References .....................................................22
-      6.1. Normative References ......................................22
-      6.2. Informative References ....................................22
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 2]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-1.  Introduction
-
-   The DSL Forum has created additional RADIUS [RFC2865] [RFC2866]
-   vendor-specific attributes to carry DSL line identification and
-   characterization information.  This information is forwarded from the
-   Access Node/DSLAM to the BRAS via Vendor-Specific PPPoE Tags
-   [RFC2516], DHCP Relay Options [RFC3046], and Vendor-Specific
-   Information Suboptions [RFC4243].  This document describes the
-   subscriber line identification and characterization information and
-   its mapping to RADIUS VSAs by the BRAS.
-
-   The information acquired may be used to provide authentication and
-   accounting functionality.  It may also be collected and used for
-   management and troubleshooting purposes.
-
-2.  Terminology
-
-   The following sections define the usage and meaning of certain
-   specialized terms in the context of this document.
-
-2.1.  Requirements Language
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in [RFC2119].
-
-2.2.  Technical Terms and Acronyms
-
-   AAL5
-      ATM Adaption Layer 5 [ITU.I363-5.1996]
-
-   Access Node/DSLAM
-      The Access Node/DSLAM is a DSL signal terminator that contains a
-      minimum of one Ethernet interface that serves as its northbound
-      interface into which it aggregates traffic from several
-      Asynchronous Transfer Mode (ATM)-based (subscriber ports) or
-      Ethernet-based southbound interfaces.
-
-   BNG
-      Broadband Network Gateway.  A BNG is an IP edge router where
-      bandwidth and QoS policies are applied; the functions performed by
-      a BRAS are a superset of those performed by a BNG.
-
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 3]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   BRAS
-      Broadband Remote Access Server.  A BRAS is a BNG and is the
-      aggregation point for the subscriber traffic.  It provides
-      aggregation capabilities (e.g., IP, PPP, Ethernet) between the
-      access network and the core network.  Beyond its aggregation
-      function, the BRAS is also an injection point for policy
-      management and IP QoS in the access network.
-
-   DSL
-      Digital Subscriber Line.  DSL is a technology that allows digital
-      data transmission over wires in the local telephone network.
-
-   DSLAM
-      Digital Subscriber Line Access Multiplexer.  DSLAM is a device
-      that terminates DSL subscriber lines.  The data is aggregated and
-      forwarded to ATM- or Ethernet-based aggregation networks.
-
-   FCS
-      Frame Check Sequence.  The FCS is a checksum added to an Ethernet
-      frame for error detection/correction purposes.
-
-   IPoA
-      IP over ATM
-
-   IWF
-      Interworking Function.  The set of functions required for
-      interconnecting two networks of different technologies (e.g., ATM
-      and Ethernet).  IWF is utilized to enable the carriage of PPP over
-      ATM (PPPoA) traffic over PPPoE.
-
-   LLC
-      Logical Link Control
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 4]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-3.  Attributes
-
-   The following subsections describe the Attributes defined by this
-   document.  These Attributes MAY be transmitted in one or more RADIUS
-   Attributes of type Vendor-Specific [RFC2865].  More than one
-   attribute MAY be transmitted in a single Vendor-Specific Attribute;
-   if this is done, the attributes SHOULD be packed as a sequence of
-   Vendor-Type/Vendor-Length/Value triples following the initial Type,
-   Length, and Vendor-Id fields.
-
-3.1.  DSL Forum RADIUS VSA Definition
-
-   Description
-
-      This Attribute functions as a "container", encapsulating one or
-      more vendor-specific sub-attributes; the encoding follows the
-      recommendations in [RFC2865].
-
-   A summary of the generic DSL Forum VSA format is shown below.  The
-   fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |     Type      |  Length       |           Vendor-Id
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            Vendor-Id (cont)       |       Sub-Attribute(s)...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Type
-
-      26 for Vendor-Specific
-
-   Length
-
-      This field MUST be set equal to the sum of the Vendor-Length
-      fields of the sub-attributes contained in the Vendor-Specific
-      Attribute, plus six (Type + Length + Vendor-Id).
-
-   Vendor-Id
-
-      This field MUST be set to decimal 3561, the enterprise number
-      assigned to the ADSL Forum [IANA].
-
-   Sub-Attributes
-
-      This field MUST contain one or more DSL Forum Vendor-Specific
-      sub-attributes, as specified below.
-
-
-
-Mammoliti, et al.            Informational                      [Page 5]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-3.2.  DSL Forum Vendor Specific Sub-Attribute Encoding
-
-   A summary of the sub-attribute format is shown below.  The fields are
-   transmitted from left to right.
-
-    0                   1                   2
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   | Vendor-Type | Vendor-Length |  Value...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      The Vendor-Type field is one octet in length and contains the
-      sub-attribute type, as assigned by the DSL Forum.
-
-   Vendor-Length
-
-      The Vendor-Length field is one octet and indicates the length of
-      the entire sub-attribute, including the Vendor-Type,
-      Vendor-Length, and Value fields.
-
-   Value
-
-      The Value field is zero or more octets and contains information
-      specific to the sub-attribute.  The format and length of the Value
-      field is determined by the Vendor-Type and Vendor-Length fields.
-      The format of the value field is one of 2 data types, string or
-      integer [RFC2865].
-
-3.3.  Sub-attribute Definitions
-
-   The following sub-sections define the DSL Forum vendor-specific sub-
-   attributes.
-
-3.3.1.  Agent-Circuit-Id
-
-   Description
-
-      This Attribute contains information describing the subscriber
-      agent circuit identifier corresponding to the logical access loop
-      port of the Access Node/DSLAM from which a subscriber's requests
-      are initiated.  It MAY be present in both Access-Request and
-      Accounting-Request packets.
-
-   A summary of the Agent-Circuit-Id Attribute format is shown below.
-   The fields are transmitted from left to right.
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 6]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |           String...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      1 for Agent-Circuit-Id
-
-   Vendor-Length
-
-      <= 65
-
-   String
-
-      The String field contains information about the Access-Node to
-      which the subscriber is attached, along with an identifier for the
-      subscriber's DSL port on that Access-Node.
-
-      The exact syntax of the string is implementation dependent;
-      however, a typical practice is to subdivide it into two or more
-      space-separated components, one to identify the Access-Node and
-      another the subscriber line on that node, with perhaps an
-      indication of whether that line is Ethernet or ATM.  Example
-      formats for this string are shown below.
-
-      "Access-Node-Identifier atm slot/port:vpi.vci"
-         (when ATM/DSL is used)
-
-      "Access-Node-Identifier eth slot/port[:vlan-id]"
-         (when Ethernet/DSL is used)
-
-      An example showing the slot and port field encoding is given
-      below:
-
-      "[Relay-identifier] atm 3/0:100.33"
-         (slot = 3, port = 0, vpi = 100, vci = 33)
-
-      The Access-Node-Identifier is a unique ASCII string that does not
-      include 'space' characters.  The syntax of the slot and port
-      fields reflects typical practices currently in place.  The slot
-      identifier does not exceed 6 characters in length, and the port
-      identifier does not exceed 3 characters in length using a '\' as a
-      delimiter.
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 7]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-      The exact manner in which slots are identified is Access
-      Node/DSLAM implementation dependent.  The vpi, vci, and vlan-id
-      fields (when applicable) are related to a given access loop
-      (U-interface).
-
-3.3.2.  Agent-Remote-Id
-
-   Description
-
-      The Agent-Remote-Id Attribute contains an operator-specific,
-      statically configured string that uniquely identifies the
-      subscriber on the associated access loop of the Access Node/DSLAM.
-
-      In a typical subscriber environment, multiple attributes can be
-      used to identify the user, among others: Username (for example, as
-      defined on a PPP client); Agent-Circuit-Id (a static, pre-defined
-      string sent from the Access Node/DSLAM); Agent-Remote-Id (an
-      operator-defined string configured on and sent by the Access
-      Node/DSLAM).
-
-      This Attribute MAY be included in both Access-Request and
-      Accounting-Request packets.
-
-   A summary of the Agent-Remote-Id Attribute format is shown below.
-   The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |           String...
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      2 for Agent-Remote-Id
-
-   Vendor-Length
-
-      <= 65
-
-   String
-
-      This value of this field is entirely open to the service
-      provider's discretion.  For example, it MAY contain a subscriber
-      billing identifier or telephone number.
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 8]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-3.3.3.  Actual-Data-Rate-Upstream
-
-   Description
-
-      This Attribute contains the actual upstream train rate of a
-      subscriber's synchronized DSL link.  It MAY be included in both
-      Access-Request and Accounting-Request packets.
-
-   A summary of the Actual-Data-Rate-Upstream Attribute format is shown
-   below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      129 (0x81) for Actual-Data-Rate-Upstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field contains a 4-byte unsigned integer, indicating the
-      subscriber's actual data rate upstream of a synchronized DSL link.
-      The rate is coded in bits per second.
-
-3.3.4.  Actual-Data-Rate-Downstream
-
-   Description
-
-      This Attribute contains the actual downstream train rate of a
-      subscriber's synchronized DSL link.  It MAY be included in both
-      Access-Request and Accounting-Request packets.
-
-   A summary of the Actual-Data-Rate-Downstream Attribute format is
-   shown below.  The fields are transmitted from left to right.
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                      [Page 9]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      130 (0x82) for Actual-Data-Rate-Downstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field contains a 4-byte unsigned integer, indicating the
-      subscriber's actual data rate downstream of a synchronized DSL
-      link.  The rate is coded in bits per second.
-
-3.3.5.  Minimum-Data-Rate-Upstream
-
-   Description
-
-      This Attribute contains the subscriber's operator-configured
-      minimum upstream data rate.  It MAY be included in Accounting-
-      Request packets.
-
-   A summary of the Minimum-Data-Rate-Upstream Attribute format is shown
-   below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      131 (0x83) for Minimum-Data-Rate-Upstream
-
-   Vendor-Length
-
-      6
-
-
-
-Mammoliti, et al.            Informational                     [Page 10]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   Value
-
-      This field contains a 4-byte unsigned integer, indicating the
-      subscriber's minimum upstream data rate (as configured by the
-      operator).  The rate is coded in bits per second.
-
-3.3.6.  Minimum-Data-Rate-Downstream
-
-   Description
-
-      This Attribute contains the subscriber's operator-configured
-      minimum downstream data rate.  It MAY be included in Accounting-
-      Request packets.
-
-   A summary of the Minimum-Data-Rate-Downstream Attribute format is
-   shown below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      132 (0x84) for Minimum-Data-Rate-Downstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field contains a 4-byte unsigned integer, indicating the
-      subscriber's minimum downstream data rate (as configured by the
-      operator).  The rate is coded in bits per second.
-
-3.3.7.  Attainable-Data-Rate-Upstream
-
-   Description
-
-      This Attribute contains the subscriber's attainable upstream data
-      rate.  It MAY be included in Accounting-Request packets.
-
-   A summary of the Attainable-Data-Rate-Upstream Attribute format is
-   shown below.  The fields are transmitted from left to right.
-
-
-
-Mammoliti, et al.            Informational                     [Page 11]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      133 (0x85) for Attainable-Data-Rate-Upstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field contains a 4-byte unsigned integer, indicating the
-      subscriber's actual DSL attainable upstream data rate.  The rate
-      is coded in bits per second.
-
-3.3.8.  Attainable-Data-Rate-Downstream
-
-   Description
-
-      This Attribute contains the subscriber's attainable downstream
-      data rate.  It MAY be included in Accounting-Request packets.
-
-   A summary of the Attainable-Data-Rate-Downstream Attribute format is
-   shown below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      134 (0x86) for Attainable-Data-Rate-Downstream
-
-   Vendor-Length
-
-      6
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 12]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   Value
-
-      This field contains a 4-byte unsigned integer, indicating the
-      subscriber's actual DSL attainable downstream data rate.  The rate
-      is coded in bits per second.
-
-3.3.9.  Maximum-Data-Rate-Upstream
-
-   Description
-
-      This Attribute contains the subscriber's maximum upstream data
-      rate, as configured by the operator.  It MAY be included in
-      Accounting-Request packets.
-
-   A summary of the Maximum-Data-Rate-Upstream Attribute format is shown
-   below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      135 (0x87) for Maximum-Data-Rate-Upstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value of the subscriber's DSL maximum upstream data rate.  The
-      rate is coded in bits per second.
-
-3.3.10.  Maximum-Data-Rate-Downstream
-
-   Description
-
-      This Attribute contains the subscriber's maximum downstream data
-      rate, as configured by the operator.  It MAY be included in
-      Accounting-Request packets.
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 13]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   A summary of the Maximum-Data-Rate-Downstream Attribute format is
-   shown below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      136 (0x88) for Maximum-Data-Rate-Downstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value of the subscriber's DSL maximum downstream data rate.  The
-      rate is coded in bits per second.
-
-3.3.11.  Minimum-Data-Rate-Upstream-Low-Power
-
-   Description
-
-      This Attribute contains the subscriber's minimum upstream data
-      rate in low power state, as configured by the operator.  It MAY be
-      included in Accounting-Request packets.
-
-   A summary of the Minimum-Data-Rate-Upstream-Low-Power Attribute
-   format is shown below.  The fields are transmitted from left to
-   right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      137 (0x89) for Minimum-Data-Rate-Upstream-Low-Power
-
-
-
-Mammoliti, et al.            Informational                     [Page 14]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value of the subscriber's DSL minimum upstream data rate when in
-      low power state (L1/L2).  The rate is coded in bits per second.
-
-3.3.12.  Minimum-Data-Rate-Downstream-Low-Power
-
-   Description
-
-      This Attribute contains the subscriber's minimum downstream data
-      rate in low power state, as configured by the operator.  It MAY be
-      included in Accounting-Request packets.
-
-   A summary of the Minimum-Data-Rate-Downstream-Low-Power Attribute
-   format is shown below.  The fields are transmitted from left to
-   right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      138 (0x8A) for Minimum-Data-Rate-Downstream-Low-Power
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value of the subscriber's DSL minimum downstream data rate.  The
-      rate is coded in bits per second.
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 15]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-3.3.13.  Maximum-Interleaving-Delay-Upstream
-
-   Description
-
-      This Attribute contains the subscriber's maximum one-way upstream
-      interleaving delay, as configured by the operator.  It MAY be
-      included in Accounting-Request packets.
-
-   A summary of the Maximum-Interleaving-Delay-Upstream Attribute format
-   is shown below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      139 (0x8B) for Maximum-Interleaving-Delay-Upstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value in milliseconds of the subscriber's DSL maximum one-way
-      upstream interleaving delay.
-
-3.3.14.  Actual-Interleaving-Delay-Upstream
-
-   Description
-
-      This Attribute contains the subscriber's actual one-way upstream
-      interleaving delay.  It MAY be included in Accounting-Request
-      packets.
-
-   A summary of the Actual-Interleaving-Delay-Upstream Attribute format
-   is shown below.  The fields are transmitted from left to right.
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 16]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      140 (0x8C) for Actual-Interleaving-Delay-Upstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value in milliseconds of the subscriber's DSL actual upstream
-      interleaving delay.
-
-3.3.15.  Maximum-Interleaving-Delay-Downstream
-
-   Description
-
-      This Attribute contains the subscriber's maximum one-way
-      downstream interleaving delay, as configured by the operator.  It
-      MAY be included in Accounting-Request packets.
-
-   A summary of the Maximum-Interleaving-Delay-Downstream Attribute
-   format is shown below.  The fields are transmitted from left to
-   right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      141 (0x8D) for Maximum-Interleaving-Delay-Downstream
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 17]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value in milliseconds of the subscriber's DSL maximum one-way
-      downstream interleaving delay.
-
-3.3.16.  Actual-Interleaving-Delay-Downstream
-
-   Description
-
-      This Attribute contains the subscriber's actual one-way downstream
-      interleaving delay.  It MAY be included in Accounting-Request
-      packets.
-
-   A summary of the Actual-Interleaving-Delay-Downstream Attribute
-   format is shown below.  The fields are transmitted from left to
-   right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |            Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-              Value (cont'd.)      |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      142 (0x8E) for Actual-Interleaving-Delay-Downstream
-
-   Vendor-Length
-
-      6
-
-   Value
-
-      This field is a 4-byte unsigned integer, indicating the numeric
-      value in milliseconds of the subscriber's DSL actual downstream
-      interleaving delay.
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 18]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-3.3.17.  Access-Loop-Encapsulation
-
-   Description
-
-      This Attribute describes the encapsulation(s) used by the
-      subscriber on the DSL access loop.  It MAY be present in both
-      Access-Request and Accounting-Request packets.
-
-   A summary of the Access-Loop-Encapsulation Attribute format is shown
-   below.  The fields are transmitted from left to right.
-
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |                    Value
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    Value (cont'd) |
-   +-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      144 (0x90) for Access-Loop-Encapsulation
-
-   Vendor-Length
-
-      5
-
-   Value
-
-      This field is a string 3 bytes in length, logically divided into
-      three 1-byte sub-fields as shown in the following diagram:
-
-       0                   1                   2
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |   Data Link   |    Encaps 1   |    Encaps 2   |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Valid values for the sub-fields are as follows:
-
-      Data Link
-
-         0x01 AAL5
-         0x02 Ethernet
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 19]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-      Encaps 1
-
-         0x00 NA - Not Available
-         0x01 Untagged Ethernet
-         0x02 Single-Tagged Ethernet
-
-      Encaps 2
-
-         0x00 NA - Not Available
-         0x01 PPPoA LLC
-         0x02 PPPoA Null
-         0x03 IPoA LLC
-         0x04 IPoA Null
-         0x05 Ethernet over AAL5 LLC with FCS
-         0x06 Ethernet over AAL5 LLC without FCS
-         0x07 Ethernet over AAL5 Null with FCS
-         0x08 Ethernet over AAL5 Null without FCS
-
-3.3.18.  IWF-Session
-
-   Description
-
-      The presence of this Attribute indicates that the IWF has been
-      performed with respect to the subscriber's session; note that no
-      data field is necessary.  It MAY be included in both Access-
-      Request and Accounting-Request packets.
-
-   A summary of the IWF-Session Attribute format is shown below.  The
-   fields are transmitted from left to right.
-
-    0                   1
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   |  Vendor-Type  | Vendor-Length |
-   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-   Vendor-Type
-
-      254 (0xFE) for IWF-Session
-
-   Vendor-Length
-
-      2
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 20]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-4.  Table of Attributes
-
-   The following table provides a guide to which attributes may be found
-   in which kinds of packets, and in what quantity; note that since none
-   of the DSL Forum VSAs may be present in the Access-Accept, Access-
-   Reject or Access-Challenge packets, those columns have been omitted
-   from the table.
-
-   Request   Acct-Request  #   Attribute
-   0-1       0-1            1  Agent-Circuit-Id
-   0-1       0-1            2  Agent-Remote-Id
-   0-1       0-1          129  Actual-Data-Rate-Upstream
-   0-1       0-1          130  Actual-Data-Rate-Downstream
-   0         0-1          131  Minimum-Data-Rate-Upstream
-   0         0-1          132  Minimum-Data-Rate-Downstream
-   0         0-1          133  Attainable-Data-Rate-Upstream
-   0         0-1          134  Attainable-Data-Rate-Downstream
-   0         0-1          135  Maximum-Data-Rate-Upstream
-   0         0-1          136  Maximum-Data-Rate-Downstream
-   0         0-1          137  Minimum-Data-Rate-Upstream-Low-Power
-   0         0-1          138  Minimum-Data-Rate-Downstream-Low-Power
-   0         0-1          139  Maximum-Interleaving-Delay-Upstream
-   0         0-1          140  Actual-Interleaving-Delay-Upstream
-   0         0-1          141  Maximum-Interleaving-Delay-Downstream
-   0         0-1          142  Actual-Interleaving-Delay-Downstream
-   0-1       0-1          144  Access-Loop-Encapsulation
-   0-1       0-1          254  IWF-Session
-
-   The following table defines the meaning of the above table entries.
-
-   0      This Attribute MUST NOT be present in packet.
-
-   0-1    Zero or one instances of this Attribute MAY be present in
-          packet.
-
-5.  Security Considerations
-
-   The security of these Attributes relies on an implied trust
-   relationship between the Access Node/DSLAM and the BRAS.  The
-   identifiers that are inserted by the Access Node/DSLAM are
-   unconditionally trusted; the BRAS does not perform any validity check
-   on the information received.  These Attributes are intended to be
-   used in environments in which the network infrastructure (the Access
-   Node/DSLAM, the BRAS, and the entire network in which those two
-   devices reside) is trusted and secure.
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 21]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   As used in this document, the word "trusted" implies that
-   unauthorized traffic cannot enter the network except through secured
-   and trusted devices and that all devices internal to the network are
-   secure and trusted.  Careful consideration should be given to the
-   potential security vulnerabilities that are present in this model
-   before deploying this option in actual networks.
-
-   The Attributes described in this document neither increase nor
-   decrease the security of the RADIUS protocol.  For discussions of
-   various RADIUS vulnerabilities, see [RFC2607], [RFC3579], [RFC3162],
-   and [RFC3580].
-
-6.  References
-
-6.1.  Normative References
-
-   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
-              Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-   [RFC2865]  Rigney, C., Willens, S., Rubens, A., and W. Simpson,
-              "Remote Authentication Dial In User Service (RADIUS)",
-              RFC 2865, June 2000.
-
-   [RFC2866]  Rigney, C., "RADIUS Accounting", RFC 2866, June 2000.
-
-6.2.  Informative References
-
-   [IANA]     Internet Assigned Numbers Authority, "PRIVATE ENTERPRISE
-              NUMBERS", January 2006,
-              <http://www.iana.org/assignments/enterprise-numbers>.
-
-   [ITU.I363-5.1996]
-              International Telecommunications Union, "B-ISDN ATM
-              Adaptation Layer Specification: Type 5 AAL", ITU-T
-              Recommendation I.363.5, August 1996.
-
-   [RFC2516]  Mamakos, L., Lidl, K., Evarts, J., Carrel, D., Simone, D.,
-              and R. Wheeler, "A Method for Transmitting PPP Over
-              Ethernet (PPPoE)", RFC 2516, February 1999.
-
-   [RFC2607]  Aboba, B. and J. Vollbrecht, "Proxy Chaining and Policy
-              Implementation in Roaming", RFC 2607, June 1999.
-
-   [RFC3046]  Patrick, M., "DHCP Relay Agent Information Option",
-              RFC 3046, January 2001.
-
-   [RFC3162]  Aboba, B., Zorn, G., and D. Mitton, "RADIUS and IPv6",
-              RFC 3162, August 2001.
-
-
-
-Mammoliti, et al.            Informational                     [Page 22]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-   [RFC3579]  Aboba, B. and P. Calhoun, "RADIUS (Remote Authentication
-              Dial In User Service) Support For Extensible
-              Authentication Protocol (EAP)", RFC 3579, September 2003.
-
-   [RFC3580]  Congdon, P., Aboba, B., Smith, A., Zorn, G., and J. Roese,
-              "IEEE 802.1X Remote Authentication Dial In User Service
-              (RADIUS) Usage Guidelines", RFC 3580, September 2003.
-
-   [RFC4243]  Stapp, M., Johnson, R., and T. Palaniappan, "Vendor-
-              Specific Information Suboption for the Dynamic Host
-              Configuration Protocol (DHCP) Relay Agent Option",
-              RFC 4243, December 2005.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 23]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-Authors' Addresses
-
-   Vince Mammoliti
-   Cisco Systems
-   181 Bay Street, Suite 3400
-   Toronto, ON  M5J 2T3
-   Canada
-
-   EMail: vince@cisco.com
-
-
-   Glen Zorn
-   Cisco Systems
-   2901 Third Avenue, Suite 600
-   SEA1/5/
-   Seattle, WA  98121
-   USA
-
-   Phone: +1 (425) 344 8113
-   EMail: gwz@cisco.com
-
-
-   Peter Arberg
-   Redback Networks, Inc.
-   300 Holger Way
-   San Jose, CA  95134
-   USA
-
-   EMail: parberg@redback.com
-
-
-   Robert Rennison
-   ECI Telecom
-   Omega Corporate Center
-   1300 Omega Drive
-   Pittsburgh, PA  15205
-   USA
-
-   EMail: robert.rennison@ecitele.com
-
-
-
-
-
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 24]
-\f
-RFC 4679                  DSL Forum RADIUS VSA            September 2006
-
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (2006).
-
-   This document is subject to the rights, licenses and restrictions
-   contained in BCP 78 and at www.rfc-editor.org/copyright.html, and
-   except as set forth therein, the authors retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
-   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
-   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at
-   ietf-ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is provided by the IETF
-   Administrative Support Activity (IASA).
-
-
-
-
-
-
-
-Mammoliti, et al.            Informational                     [Page 25]
-\f
diff --git a/doc/rfc/rfc4818.txt b/doc/rfc/rfc4818.txt
deleted file mode 100644 (file)
index 8a7d969..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         J. Salowey
-Request for Comments: 4818                                      R. Droms
-Category: Standards Track                            Cisco Systems, Inc.
-                                                              April 2007
-
-
-                 RADIUS Delegated-IPv6-Prefix Attribute
-
-Status of This Memo
-
-   This document specifies an Internet standards track protocol for the
-   Internet community, and requests discussion and suggestions for
-   improvements.  Please refer to the current edition of the "Internet
-   Official Protocol Standards" (STD 1) for the standardization state
-   and status of this protocol.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The IETF Trust (2007).
-
-Abstract
-
-   This document defines a RADIUS (Remote Authentication Dial In User
-   Service) attribute that carries an IPv6 prefix that is to be
-   delegated to the user.  This attribute is usable within either RADIUS
-   or Diameter.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Salowey & Droms             Standards Track                     [Page 1]
-\f
-RFC 4818            Delegated-IPv6-Prefix Attribute           April 2007
-
-
-1.  Introduction
-
-   This document defines the Delegated-IPv6-Prefix attribute as a RADIUS
-   [1] attribute that carries an IPv6 prefix to be delegated to the
-   user, for use in the user's network.  For example, the prefix in a
-   Delegated-IPv6-Prefix attribute can be delegated to another node
-   through DHCP Prefix Delegation [2].
-
-   The Delegated-IPv6-Prefix attribute can be used in DHCP Prefix
-   Delegation between the delegating router and a RADIUS server, as
-   illustrated in the following message sequence.
-
-
-   Requesting Router   Delegating Router                   RADIUS Server
-         |                     |                                 |
-         |-Solicit------------>|                                 |
-         |                     |-Request------------------------>|
-         |                     |<--Accept(Delegated-IPv6-Prefix)-|
-         |<--Advertise(Prefix)-|                                 |
-         |-Request(Prefix)---->|                                 |
-         |<--Reply(Prefix)-----|                                 |
-         |                     |                                 |
-                DHCP PD                      RADIUS
-
-
-   The Framed-IPv6-Prefix attribute [4] is not designed to support
-   delegation of IPv6 prefixes to be used in the user's network, and
-   therefore Framed-IPv6-Prefix and Delegated-IPv6-Prefix attributes may
-   be included in the same RADIUS packet.
-
-2.  Terminology
-
-   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in RFC 2119 [3].
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Salowey & Droms             Standards Track                     [Page 2]
-\f
-RFC 4818            Delegated-IPv6-Prefix Attribute           April 2007
-
-
-3.  Attribute Format
-
-   The format of the Delegated-IPv6-Prefix is:
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |     Type      |    Length     |  Reserved     | Prefix-Length |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                   Prefix
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                   Prefix
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                   Prefix
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                   Prefix                             |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-      Type
-
-           123 for Delegated-IPv6-Prefix
-
-      Length
-
-           The length of the entire attribute, in bytes.  At least 4 (to
-           hold Type/Length/Reserved/Prefix-Length for a 0-bit prefix),
-           and no larger than 20 (to hold Type/Length/ Reserved/Prefix-
-           Length for a 128-bit prefix)
-
-      Reserved
-
-           Always set to zero by sender; ignored by receiver
-
-      Prefix-Length
-
-           The length of the prefix being delegated, in bits.  At least
-           0 and no larger than 128 bits (identifying a single IPv6
-           address)
-
-   Note that the prefix field is only required to be long enough to hold
-   the prefix bits and can be shorter than 16 bytes.  Any bits in the
-   prefix field that are not part of the prefix MUST be zero.
-
-   The Delegated-IPv6-Prefix MAY appear in an Access-Accept packet, and
-   can appear multiple times.  It MAY appear in an Access-Request packet
-   as a hint by the NAS to the server that it would prefer these
-   prefix(es), but the server is not required to honor the hint.
-
-
-
-
-Salowey & Droms             Standards Track                     [Page 3]
-\f
-RFC 4818            Delegated-IPv6-Prefix Attribute           April 2007
-
-
-   The Delegated-IPv6-Prefix attribute MAY appear in an Accounting-
-   Request packet.
-
-   The Delegated-IPv6-Prefix MUST NOT appear in any other RADIUS
-   packets.
-
-4.  Table of Attributes
-
-   The following table provides a guide to which attributes may be found
-   in which kinds of packets, and in what quantity.
-
-   +-------------------------------------------------------------------+
-   | Request Accept Reject Challenge Accounting  #   Attribute         |
-   |                                 Request                           |
-   | 0+      0+     0      0         0+          123 Delegated-IPv6-   |
-   |                                                 Prefix            |
-   +-------------------------------------------------------------------+
-
-   The meaning of the above table entries is as follows:
-      0   This attribute MUST NOT be present.
-      0+  Zero or more instances of this attribute MAY be present.
-      0-1 Zero or one instance of this attribute MAY be present.
-      1   Exactly one instance of this attribute MUST be present.
-      1+  One or more of these attributes MUST be present.
-
-5.  Diameter Considerations
-
-   When used in Diameter, the attribute defined in this specification
-   can be used as a Diameter AVP from the Code space 1-255, i.e., RADIUS
-   attribute compatibility space.  No additional Diameter Code values
-   are therefore allocated.  The data types of the attributes are as
-   follows:
-
-        Delegated-IPv6-Prefix             OctetString
-
-   The attribute in this specification has no special translation
-   requirements for Diameter to RADIUS or RADIUS to Diameter gateways,
-   i.e., the attribute is copied as is, except for changes relating to
-   headers, alignment, and padding.  See also RFC 3588 [5], Section 4.1,
-   and RFC 4005 [6], Section 9.
-
-   The text in this specification describing the applicability of the
-   Delegated-IPv6-Prefix attribute for RADIUS Access-Request applies in
-   Diameter to AA-Request [6] or Diameter-EAP-Request [7].
-
-   The text in this specification describing the applicability of the
-   Delegated-IPv6-Prefix attribute for RADIUS Access-Accept applies in
-   Diameter to AA-Answer or Diameter-EAP-Answer that indicates success.
-
-
-
-Salowey & Droms             Standards Track                     [Page 4]
-\f
-RFC 4818            Delegated-IPv6-Prefix Attribute           April 2007
-
-
-   The text in this specification describing the applicability of the
-   Delegated-IPv6-Prefix attribute for RADIUS Accounting-Request applies
-   to Diameter Accounting-Request [6] as well.
-
-   The AVP flag rules [5] for the Delegated-IPv6-Prefix attribute are:
-
-                                      +---------------------+
-                                      |    AVP Flag rules   |
-                                      |----+-----+----+-----|----+
-                     AVP              |    |     |SHLD| MUST|    |
-     Attribute Name  Code  Value Type |MUST| MAY | NOT|  NOT|Encr|
-     ---------------------------------|----+-----+----+-----|----|
-     Delegated-IPv6- 123   OctetString| M  |  P  |    |  V  | Y  |
-       Prefix                         |    |     |    |     |    |
-     ---------------------------------|----+-----+----+-----|----|
-
-6.  IANA Considerations
-
-   IANA assigned a Type value, 123, for this attribute from the RADIUS
-   Attribute Types registry.
-
-7.  Security Considerations
-
-   Known security vulnerabilities of the RADIUS protocol are discussed
-   in RFC 2607 [8], RFC 2865 [1], and RFC 2869 [9].  Use of IPsec [10]
-   for providing security when RADIUS is carried in IPv6 is discussed in
-   RFC 3162.
-
-   Security considerations for the Diameter protocol are discussed in
-   RFC 3588 [5].
-
-8.  References
-
-8.1.  Normative References
-
-   [1]  Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote
-        Authentication Dial In User Service (RADIUS)", RFC 2865, June
-        2000.
-
-   [2]  Troan, O. and R. Droms, "IPv6 Prefix Options for Dynamic Host
-        Configuration Protocol (DHCP) version 6", RFC 3633, December
-        2003.
-
-   [3]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
-        Levels", BCP 14, RFC 2119, March 1997.
-
-
-
-
-
-
-Salowey & Droms             Standards Track                     [Page 5]
-\f
-RFC 4818            Delegated-IPv6-Prefix Attribute           April 2007
-
-
-9.2.  Informative References
-
-   [4]  Aboba, B., Zorn, G., and D. Mitton, "RADIUS and IPv6", RFC 3162,
-        August 2001.
-
-   [5]  Calhoun, P., Loughney, J., Guttman, E., Zorn, G., and J. Arkko,
-        "Diameter Base Protocol", RFC 3588, September 2003.
-
-   [6]  Calhoun, P., Zorn, G., Spence, D., and D. Mitton, "Diameter
-        Network Access Server Application", RFC 4005, August 2005.
-
-   [7]  Eronen, P., Hiller, T., and G. Zorn, "Diameter Extensible
-        Authentication Protocol (EAP) Application", RFC 4072, August
-        2005.
-
-   [8]  Aboba, B. and J. Vollbrecht, "Proxy Chaining and Policy
-        Implementation in Roaming", RFC 2607, June 1999.
-
-   [9]  Rigney, C., Willats, W., and P. Calhoun, "RADIUS Extensions",
-        RFC 2869, June 2000.
-
-   [10] Kent, S. and K. Seo, "Security Architecture for the Internet
-        Protocol", RFC 4301, December 2005.
-
-Authors' Addresses
-
-   Joe Salowey
-   Cisco Systems, Inc.
-   2901 Third Avenue
-   Seattle, WA  98121
-   USA
-
-   Phone: +1 206.310.0596
-   EMail: jsalowey@cisco.com
-
-
-   Ralph Droms
-   Cisco Systems, Inc.
-   1414 Massachusetts Avenue
-   Boxborough, MA  01719
-   USA
-
-   Phone: +1 978.936.1674
-   EMail: rdroms@cisco.com
-
-
-
-
-
-
-
-Salowey & Droms             Standards Track                     [Page 6]
-\f
-RFC 4818            Delegated-IPv6-Prefix Attribute           April 2007
-
-
-Full Copyright Statement
-
-   Copyright (C) The IETF Trust (2007).
-
-   This document is subject to the rights, licenses and restrictions
-   contained in BCP 78, and except as set forth therein, the authors
-   retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
-   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
-   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at
-   ietf-ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is currently provided by the
-   Internet Society.
-
-
-
-
-
-
-
-Salowey & Droms             Standards Track                     [Page 7]
-\f
diff --git a/doc/rfc/update.sh b/doc/rfc/update.sh
deleted file mode 100755 (executable)
index e61909f..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/sh
-#
-#  This script makes an HTML page from a simple directory listing
-#
-#
-cat >index.html <<EOF
-<HTML>
-<TITLE>Index of FreeRADIUS.org's RFC site</TITLE>
-<BODY>
-
-<H1>Index of FreeRADIUS.org's RFC site</H1>
-
-List of <A HREF="attributes.html">RADIUS attributes</A>
-<P>
-
-EOF
-
-#
-#  include the message, if any exists
-#
-if [ -e message ]; then
-  echo "<PRE>" >> index.html
-  cat .message >> index.html
-  echo "</PRE>" >> index.html
-fi
-
-#
-#  for all of the text files, do this
-#
-cat >>index.html <<EOF
-<h2>RFC's</h2>
-EOF
-
-for x in rfc*.html;do
-  y=`echo $x | sed 's/rfc//;s/\.html//'`
-  echo "<A HREF=\"$x\">RFC $y</A>" >> index.html
-  if [ -e $x.gz ]; then
-    echo "<A HREF=\"$x.gz\">(gzipped)</A>" >> index.html
-  fi
-  y="attributes-rfc$y.html";
-  if [ -f $y ];then
-    echo "<A HREF=\"$y\">(attributes)</A>" >> index.html
-  fi
-  echo "<BR />" >> index.html
-done
-
-cat >>index.html <<EOF
-<h2>Other files</h2>
-EOF
-
-#
-#  for all of the text files, do this
-#
-for x in *.txt;do
-  y=`echo $x | sed ';s/\.txt/.html/'`
-  if [ ! -f $y ];then
-    echo "<A HREF=\"$x\">$x</A>" >> index.html
-    if [ -e $x.gz ]; then
-      echo "<A HREF=\"$x.gz\">(gzipped)</A>" >> index.html
-    fi
-    echo "<BR />" >> index.html
-  fi
-done
-echo "</BODY></HTML>" >> index.html
diff --git a/doc/rlm_attr_filter b/doc/rlm_attr_filter
new file mode 100644 (file)
index 0000000..b460ca1
--- /dev/null
@@ -0,0 +1,129 @@
+
+
+       Attribute Filtering Module
+
+
+-1. CAVEAT
+
+
+RLM_ATTR_FILTER
+
+0.  INTRODUCTION
+
+  This module exists for filtering certain attributes and values in received
+  radius packets from remote proxy servers.  It gives the proxier (us) a very
+  flexible framework to filter the attributes that proxy servers send us in
+  their replies.  This makes sense in an out-sourced dialup situation for
+  example, where the client proxy is permitted only certain values for setting
+  the Idle-Timeout.
+
+  Filter rules are defined and applied on a per-realm basis, where the realm
+  can be anything you have defined via the rlm_realm module.
+
+1.  MODULE CONFIGURATION
+
+  The module configuration section is very simple.  There is only one attribute
+  that needs to be set, the file to read the filter rules from.
+
+  As an example, here is the default configuration from radiusd.conf:
+
+       modules {
+           ...
+           attr_filter {
+               attrsfile = ${confdir}/attrs
+          }
+           ...
+       }
+
+  If attrsfile is not specified, it defaults to the above configuration.
+
+  This module supports multiple named instances per the normal method.
+
+  Once defined in the modules section of the config file, you must add the
+  module instance name ( the name of the module itself by default ) into the  
+  'authorize{}' section.  It should be placed *before* the realm modules.
+
+  As an example:
+  
+       authorize {
+           preprocess
+           attr_filter
+           realm
+          files
+       }
+
+  If the incoming packet is not a proxy reply, the module returns a NOOP,
+  so that the rest of the 'authorize{}' is called normally.
+
+3.  MODULE OPTIONS
+
+  The file that defines the attribute filter rules is layed out and parsed
+  very similar to the users file.  There are a couple main differences:
+
+     o  There are no "check items" on the first line of the profile other
+        than the "realm".
+
+     o  There is only one DEFAULT entry.  This is due to the fact that there
+        are no "check items" beyond the realm name.  Fall-Through does work
+        though, allowing you to put the commonly allowed attribute rules into
+        the DEFAULT entry and only put realm specific rules in the specific
+        realm entry.
+
+     o  The operators used for specifying the attributes are as follows:
+
+           =    -  NOT ALLOWED.  If used, it becomes "=="
+
+           :=   -  Set ( used to ensure a specific a/v is present )
+           ==   -  Equal  ( exact )
+          =*   -  Always Equal ( will allow all values for attribute )
+           !*   -  Always Not Equal ( will block all values for attribute )
+           !=   -  Not equal
+           >=   -  Greater than or equal to
+           <=   -  Less than or equal to
+           >    -  Greater than
+           <    -  Less than
+
+           If you have regular expressions enabled you also have:
+
+           =~   -  Regular expression equal
+           !~   -  Regular expression not equal
+
+
+  See the comments in the default 'attrs' file for examples and additional
+  explanation.
+
+4.  MODULE FUNCTION
+
+  The way the module works is as follows:
+
+     o  Build a list of a/v pair rules from the 'attrs' file at module
+        instantiation.
+
+     o  When a proxy reply packet is received and passed to the module, it
+        checks for a Realm attribute in the original request a/v pairs.
+        ( The Realm attribute is added there by the proxy code ).
+
+     o  The module walks the list of a/v pair rules until it finds a
+        match for the Realm value or it reaches the DEFAULT entry.
+
+     o  If there are any rules with SET operators, those attributes are 
+       added to the top of a temporary reply list.
+     o  Each a/v pair in the proxy reply is compared to the list of 
+       rules.
+   
+     o  If an a/v pair in the proxy reply passes *ALL* of the rules that
+       relate to the attribute, the a/v is added to a temporary list.  
+        ( Note, if it fails 1 or more rules, or is not matched, then the
+          a/v pair will *NOT* be transferred to the temporary list. )
+
+     o  When all the reply vps have been checked, the original proxy reply
+        vps are freed and the temporary list ( containing only those a/v
+        that passed the rules ) becomes the new proxy reply vps.
+
+     o  The module then returns UPDATED and the rest of the authorize block
+        is called as usual.
+
+---
+Please send corrections/input/comments/flames to <cparker@starnetusa.net>
+
diff --git a/doc/rlm_digest b/doc/rlm_digest
new file mode 100644 (file)
index 0000000..56c51d6
--- /dev/null
@@ -0,0 +1,43 @@
+       Digest module configuration
+
+0. INTRODUCTION
+
+  The digest module performs HTTP digest authentication, as per
+  the IETF draft rfc/draft-sterman-aaa-sip-00.txt.  It has been
+  successfully tested against a Cisco SIP server.
+
+  However, the draft has been expired by the IETF, so it's unlikely to
+  become an "official" standard.
+
+1. USAGE
+
+  To use this module, uncomment the lines relating to 'digest' from
+raddb/radiusd.conf.  Once that is done, any RADIUS request containing
+the digest attributes will automatically be authenticated using the
+'digest' module.
+
+  Note tha the 'digest' module REQUIRES access to the clear-text
+password for the user, in order to perform digest authentication.
+
+2. TESTING
+
+  Add the following lines to the top of your 'raddb/users' file:
+
+#---
+test   Auth-Type := Digest, User-Password = "test"
+       Reply-Message = "Hello, test with digest"
+#---
+
+
+  Once the server has been re-started (debugging mode is recommended),
+  use 'radclient' to send the following packet to the server:
+
+  $  radclient -f digest localhost auth testing123
+
+  Where 'digest' is a file containing:
+
+User-Name = "test", Digest-Response = "631d6d73147add2f9e437f59bbc3aeb7", Digest-Realm = "testrealm", Digest-Nonce = "1234abcd", Digest-Method = "INVITE", Digest-URI = "sip:5555551212@example.com", Digest-Algorithm = "MD5", Digest-User-Name = "test"
+
+  You should see the authentication succeed.
+
+$Id$
index 8e340e8..f68ca46 100644 (file)
@@ -89,8 +89,6 @@ EAP CODE ORGANIZATION
   rlm_eap/types -- contains all the supported EAP-Types
   rlm_eap/types/rlm_eap_md5  -- EAP-MD5 authentication.
   rlm_eap/types/rlm_eap_tls  -- EAP-TLS based authentication.
-  rlm_eap/types/rlm_eap_ttls -- TTLS based authentication.
-  rlm_eap/types/rlm_eap_peap -- Windows PEAP based authentication.
   rlm_eap/types/rlm_eap_leap -- Cisco LEAP authentication.
   rlm_eap/types/rlm_eap_sim  -- EAP-SIM (GSM) based authentication
    
@@ -126,8 +124,9 @@ CONFIGURATION
   to determine which EAP type to choose for authentication.
 
   NOTE: EAP cannot authorize a user. It can only authenticate.
-  Other Freeradius modules authorize the user.
+  Other Freeradius modules authorize the user and lets EAP to authenticate.
 
+  NOTE: There can only be one instance of the EAP module.
 
 EAP SIM server
 
@@ -231,17 +230,13 @@ HOW DO I USE IT (FAQ/Examples)
        # ldap gets the Configured password.
        # eap sets the authenticate type as EAP
        authorize {
-               ...
                ldap
                eap
-               ...
        }
 
        # eap authentication takes place.
        authenticate {
-               ...
                eap
-               ...
        }
 
   3. How can I Proxy EAP messages, with/without User-Name attribute
@@ -281,7 +276,7 @@ HOW DO I USE IT (FAQ/Examples)
    With the above configuration, RADIUS server immediately responds with
    EAP-Identity request.
        
-   NOTE: EAP does not check for any Identity or maintains any state in case
+   NOTE: EAP doesnot check for any Identity or maintains any state in case
    of EAP-START. It blindly responds with EAP-Identity request.
    Proxying is handled only after EAP-Identity response is received.
 
@@ -325,13 +320,17 @@ INSTALLATION
   EAP, EAP-MD5, and Cisco LEAP do not require any additional packages.
   Freeradius contains all the required packages.
 
-  For EAP-TLS, EAP-TTLS, and PEAP, OPENSSL, <http://www.openssl.org/>,
-  is required to be installed.
+  For EAP-TLS, OPENSSL, <http://www.openssl.org/>, is required to be installed.
   Any version from 0.9.7, should fairly work with this module.
 
   EAP-SIM should not require any additional packages.
 
 
+CAVEATS
+    It probably still has bugs.  Most notably, there is a small memory
+    leak somewhere in the eap_tls code.  I suspect it's because of my 
+    misuse of OPENSSL libraries, but I have no proof yet.
+
 IMPLEMENTATION (For Developers)
 
   The rlm_eap module only deals with EAP specific authentication mechanism
diff --git a/doc/rlm_expiration b/doc/rlm_expiration
deleted file mode 100644 (file)
index f9279de..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Module to expire user accounts.
-
-This module can be used to expire user accounts. Expired users receive
-an Access-Reject on every authentication attempt. Expiration is based
-on the Expiration attribute which should be present in the check item
-list for the user we wish to perform expiration checks.
-
-
-
-Expiration attribute format:
-
-You can use Expiration := "23 Sep 2004" and the user will 
-no longer be able to connect at 00:00 (midnight) on September 23rd, 
-2004.  If you want a certain time (other than midnight) you can do 
-use  Expiration := "23 Sep 2004 12:00".
-The nas will receive a Session-Timeout attribute calculated to kick
-the user off when the Expiration time occurs.
-
-
-
-Example entry (users files):
-
-user1  Expiration := "23 Sep 2004"
index 59d3c1f..2552689 100644 (file)
@@ -9,6 +9,7 @@ See also: http://www.tldp.org/HOWTO/LDAP-Implementation-HOWTO/radius.html
 It's not up to date, though.  For example, you do NOT have to edit
 the "dictionary" file.
 
+
 2. LDAP ATTRIBUTES
 
 The mapping between radius and ldap attributes is in raddb/ldap.attrmap. You
@@ -26,8 +27,167 @@ ie radiusReplyItem: Cisco-AVPair := "ip:addr-pool=dialin_pool"
 
 3. CONFIGURATION
 
-Add following subsection to the modules{} section of radiusd.conf to control
-the rlm_ldap module:
+See the "modules" section of "radiusd.conf", and look for the "ldap"
+section.  It lists and documents the common configuration items.
+
+Note that LDAP is a database, NOT an authentication server.
+FreeRADIUS is an authentication server, NOT a database.  What this
+means is that LDAP "bind as user" is almost always a bad idea.  Using
+"Auth-Type = LDAP" is almost always a bad idea.  We STRONGLY recommend
+that you do NOT list "ldap" in the "authenticate" section of
+radiusd.conf.  Doing so can cause all sorts of problems for people who
+are unfamiliar with RADIUS and LDAP.
+
+The normal configuration is to configure the "ldap" section in
+radiusd.conf, and list "ldap" in the "authorize" section.  FreeRADIUS
+should then be able to use LDAP to find the "known good" password for
+the user.  FreeRADIUS will then use this password to perform PAP,
+CHAP, MS-CHAP, or any other kind of authentication that the user has
+requested.
+
+If you use "Auth-Type := LDAP", then the ONLY authentication protocol
+that will work is PAP.  EAP will not work (i.e. all wireless
+authentication).  CHAP will not work, and MS-CHAP will not work.
+
+
+4. USAGE
+
+MODULE MESSAGES: On user rejection rlm_ldap will return the following module
+messages:
+
+"rlm_ldap: User not found" "rlm_ldap: Access Attribute denies access"
+"rlm_ldap: Bind as user failed"
+
+These messages will be visible in radius.log as aditional information in
+"Login incorrect" and "Invalid user" log messages.
+
+LDAP XLAT: The ldap module now supports LDAP URLs in xlat strings. That is you
+can now add LDAP URLs in the configuration options and hopefully shortly also
+in the users file. The strings will be of the following form:
+
+%{ldap:ldap:///dc=company,dc=com?uid?sub?uid=%u}
+
+The requested attributes list MUST contain only ONE attribute. In case this
+attribute is multi valued which value is returned is considered UNDEFINED.
+Also, adding the host:port information SHOULD be avoided unless there are more
+than one ldap module instances in which case the host,port information can be
+used to distinguish which module will actually return the information (the
+xlat function will return NULL if the host,port information does not
+correspond to the configured attributes).  If there are more than one
+instances the module instance name can be used instead of the string 'ldap'
+before the ldap url to decide which instance will return the information.
+That is the xlat string will be of the form:
+
+%{$instance_name:ldap:///dc=comapny,dc=com?uid?sub?uid=%u}
+
+i.e.: ${ldap_company1:ldap:///dc=company1,dc=com?uid?sub?uid=%u}
+
+
+USER PROFILE ATTRIBUTE: The module can use the User-Profile attribute. If it
+is set, it will assume that it contains the DN of a profile entry containing
+radius attributes. This entry will _replace_ the default profile directive.
+That way we can use different profiles based on checks on the radius
+attributes contained in the Access-Request packets. For example (users file):
+
+DEFAULT        Service-Type == Outbound-User, User-Profile := "uid=outbound-dialup,dc=company,dc=com"
+
+GROUP SUPPORT: The module supports searching for ldap groups by use of the
+Ldap-Group attribute. As long as the module has been instanciated it can be
+used to do group membership checks through other modules. For example in the
+users file:
+
+DEFAULT        Ldap-Group == "disabled", Auth-Type := Reject 
+       Reply-Message = "Sorry, you are not allowed to have dialup access"
+
+DNs are also accepted as Ldap-Group values, i.e.:
+
+DEFAULT        Ldap-Group == "cn=disabled,dc=company,dc=com", Auth-Type := Reject
+       Reply-Message = "Sorry, you are not allowed to have dialup access"
+
+
+
+Also if you are using multiple ldap module instances a per instance
+Ldap-Group attribute is registered and can be used. It is of the form
+<instance_name>-Ldap-Group. In other words if in radiusd.conf we
+configure an ldap module instance like:
+
+ldap myname { [...] }
+
+we can then use the myname-Ldap-Group attribute to match user
+groups. Make sure though that the ldap module is instantiated *before*
+the files module so that it will have time to register the
+corresponding attribute. One solution would be to add the ldap module
+in the instantiate{} block in radiusd.conf
+
+
+USERDN Attribute:
+When rlm_ldap has found the DN corresponding to the username provided
+in the access-request (all this happens in the authorize section) it
+will add an Ldap-UserDN attribute in the request items list containing
+that DN. The attribute will be searched for in the authenticate
+section and if present will be used for authentication (ldap bind with
+the user DN/password). Otherwise a search will be performed to find
+the user dn. If the administrator wishes to use rlm_ldap only for
+authentication or does not wish to populate the identity,password
+configuration attributes he can set this attribute by other means and
+avoid the ldap search completely. For instance it can be set through
+the hints file in the authorize section:
+
+DEFAULT        Ldap-UserDN := `uid=%{User-Name},ou=people,dc=company,dc=com`
+
+The "users" file won't work, because it can't add items to the request.
+
+
+DIRECTORY COMPATIBILITY NOTE: If you use LDAP only for authorization and
+authentication (e.g. you can not afford schema extension), we suggest you set
+all necessary attributes in raddb/users file with following authorize section
+of radiusd.conf :
+
+authorize { ldap { notfound = return } files  }
+
+
+5. LDAP and Active Directory
+
+Active directory does not return anything in the userPassword
+attribute, unlike other LDAP servers.  As a result, you cannot use
+Active Directory as an LDAP server to perform CHAP, MS-CHAP, or
+EAP-MD5 authentication.  You can only use PAP, and then only if you
+list "ldap" in the "authenticate" section.  As noted above, we do not
+recommend this unless you have no other choice.
+
+To do MS-CHAP against an Active Directory domain, see the comments in
+radiusd.conf, in the "mschap" section, about "ntlm_auth".  You will
+need to install Samba.  The MS-CHAP module will then run ntlm_auth
+when it receives an MS-CHAP request.  The ntlm_auth program will
+communicate with winbindd, which will then talk to Active Directory.
+
+This will only work for one Active Directory domain.  If you need to
+authenticate against two or more domains, the solution becomes
+extremely difficult.
+
+
+If you see "Operations error" returned from an LDAP query, you may
+need to set dsHeuristics to 0000002 in Active Directory.  This allows
+searches to function similar to how they did in Active Directory
+2k2. You can update dsHeuristics by launching ldp.exe, going to
+'connection' and create a new connection. Then goto bind and bind to
+your ldap server. Next select the 'Browse' menu and choose
+'modify'. The DN *might* look like this:
+
+CN=Directory Service,CN=Windows
+NT,CN=Services,CN=Configuration,DC=mycompany,DC=com
+
+Attribute is: dsHeuristics
+Value is: 0000002
+
+Set the operation to replace and you should be set.  This should solve
+the 'Operations error' error that happens when attempting to search
+without specifying an OU.
+
+
+
+6. Detailed documentation for the module configuration
 
   modules { ...
        
@@ -262,127 +422,3 @@ yes" and "lower_time = before" in main section of radiusd.conf, to get limits
 on simultaneous logins working correctly. Otherwise, users will be able get
 large number of sessions, capitalizing parts of their login names.
 
-MODULE MESSAGES: On user rejection rlm_ldap will return the following module
-messages:
-
-"rlm_ldap: User not found" "rlm_ldap: Access Attribute denies access"
-"rlm_ldap: Bind as user failed"
-
-These messages will be visible in radius.log as aditional information in
-"Login incorrect" and "Invalid user" log messages.
-
-LDAP XLAT: The ldap module now supports LDAP URLs in xlat strings. That is you
-can now add LDAP URLs in the configuration options and hopefully shortly also
-in the users file. The strings will be of the following form:
-
-%{ldap:ldap:///dc=company,dc=com?uid?sub?uid=%u}
-
-The requested attributes list MUST contain only ONE attribute. In case this
-attribute is multi valued which value is returned is considered UNDEFINED.
-Also, adding the host:port information SHOULD be avoided unless there are more
-than one ldap module instances in which case the host,port information can be
-used to distinguish which module will actually return the information (the
-xlat function will return NULL if the host,port information does not
-correspond to the configured attributes).  If there are more than one
-instances the module instance name can be used instead of the string 'ldap'
-before the ldap url to decide which instance will return the information.
-That is the xlat string will be of the form:
-
-%{$instance_name:ldap:///dc=comapny,dc=com?uid?sub?uid=%u}
-
-i.e.: ${ldap_company1:ldap:///dc=company1,dc=com?uid?sub?uid=%u}
-
-
-USER PROFILE ATTRIBUTE: The module can use the User-Profile attribute. If it
-is set, it will assume that it contains the DN of a profile entry containing
-radius attributes. This entry will _replace_ the default profile directive.
-That way we can use different profiles based on checks on the radius
-attributes contained in the Access-Request packets. For example (users file):
-
-DEFAULT        Service-Type == Outbound-User, User-Profile := "uid=outbound-dialup,dc=company,dc=com"
-
-GROUP SUPPORT: The module supports searching for ldap groups by use of the
-Ldap-Group attribute. As long as the module has been instanciated it can be
-used to do group membership checks through other modules. For example in the
-users file:
-
-DEFAULT        Ldap-Group == "disabled", Auth-Type := Reject 
-       Reply-Message = "Sorry, you are not allowed to have dialup access"
-
-DNs are also accepted as Ldap-Group values, i.e.:
-
-DEFAULT        Ldap-Group == "cn=disabled,dc=company,dc=com", Auth-Type := Reject
-       Reply-Message = "Sorry, you are not allowed to have dialup access"
-
-
-
-Also if you are using multiple ldap module instances a per instance
-Ldap-Group attribute is registered and can be used. It is of the form
-<instance_name>-Ldap-Group. In other words if in radiusd.conf we
-configure an ldap module instance like:
-
-ldap myname { [...] }
-
-we can then use the myname-Ldap-Group attribute to match user
-groups. Make sure though that the ldap module is instantiated *before*
-the files module so that it will have time to register the
-corresponding attribute. One solution would be to add the ldap module
-in the instantiate{} block in radiusd.conf
-
-
-USERDN Attribute:
-When rlm_ldap has found the DN corresponding to the username provided
-in the access-request (all this happens in the authorize section) it
-will add an Ldap-UserDN attribute in the request items list containing
-that DN. The attribute will be searched for in the authenticate
-section and if present will be used for authentication (ldap bind with
-the user DN/password). Otherwise a search will be performed to find
-the user dn. If the administrator wishes to use rlm_ldap only for
-authentication or does not wish to populate the identity,password
-configuration attributes he can set this attribute by other means and
-avoid the ldap search completely. For instance it can be set through
-the hints file in the authorize section:
-
-DEFAULT        Ldap-UserDN := `uid=%{User-Name},ou=people,dc=company,dc=com`
-
-The "users" file won't work, because it can't add items to the request.
-
-
-DIRECTORY COMPATIBILITY NOTE: If you use LDAP only for authorization and
-authentication (e.g. you can not afford schema extension), we suggest you set
-all necessary attributes in raddb/users file with following authorize section
-of radiusd.conf :
-
-authorize { ldap { notfound = return } files  }
-
-LDAP and Active Directory
--------------------------
-
-Active directory does not return anything in the userPassword
-attribute, unlike other LDAP servers.  As a result, you cannot use
-Active Directory to perform CHAP, MS-CHAP, or EAP-MD5 authentication.
-You can only use PAP, and then only if you list "ldap" in the
-"authenticate" section.
-
-To do MS-CHAP against an Active Directory domain, see the comments in
-radiusd.conf, about "ntlm_auth".  You will need to install Samba.
-
-
-If you see "Operations error" returned from an LDAp query, you may
-need to set dsHeuristics to 0000002 in Active Directory.  This allows
-searches to function similar to how they did in Active Directory
-2k2. You can update dsHeuristics by launching ldp.exe, going to
-'connection' and create a new connection. Then goto bind and bind to
-your ldap server. Next select the 'Browse' menu and choose
-'modify'. The DN *might* look like this:
-
-CN=Directory Service,CN=Windows
-NT,CN=Services,CN=Configuration,DC=mycompany,DC=com
-
-Attribute is: dsHeuristics
-Value is: 0000002
-
-Set the operation to replace and you should be set.  This should solve
-the 'Operations error' error that happens when attempting to search
-without specifying an OU.
index ee32edb..c3e39db 100644 (file)
@@ -39,8 +39,6 @@
      a. The user IS NOT found in radcheck
      b. The user IS found in radcheck, but the check items don't match
      c. The user IS found in radcheck, the check items DO match AND
-        Fall-Through is set in the radreply table
-     d. The user IS found in radcheck, the check items DO match AND
        the read_groups directive is set to 'yes'
   4. If groups are to be processed for this user, the first thing that is
      done is the list of groups this user is a member of is pulled from the
      there is a match, the reply items for this group are pulled from the
      radgroupreply table and applied.
   6. Processing continues to the next group IF:
-     a. There was not a match for the last group's check items OR
-     b. Fall-Through was set in the last group's reply items
+     a. There was not a match for the last group's check items
      (The above is exactly the same as in the users file)
   7. Finally, if the user has a User-Profile attribute set or the Default
      Profile option is set in the sql.conf, then steps 4-6 are repeated for
      the groups that the profile is a member of.
 
-  For any fairly complex setup, it is likely that most of the actual
-  processing will be done in the groups.  In these cases, the user entry in
-  radcheck will be of limited use except for things like setting the user's
-  password.  So, one might have the following setup:
-
-  radcheck table:
-  joeuser        User-Password      ==       somepassword
-
-  radreply table:
-  joeuser        Fall-Through       =        Yes
-
-  radgroupcheck table:
-  Check items for various connection scenarios
-
-  radgroupreply table:
-  reply items for the groups
-
-  usergroup table:
-  joeuser      WLANgroup    1(this is the priority)
-  joeuser      PPPgroup     2
-
   A web page with some helpful documentation is:
 
        http://www.frontios.com/freeradius.html
index b170e89..fd8b74f 100644 (file)
@@ -2,26 +2,17 @@ rlm_sqlcounter installation and running guide
 by Ram Narula ram@princess1.net
 Internet for Education (Thailand)
 
-*) Pre-requisites:
-Make sure to have configured radiusd with rlm_sqlcounter
-installed
-
-> make clean
-> ./configure --with-experimental-modules
-> make
-> make install
-
 Make sure to have radiusd running properly under sql
 and there must be a "sql" entry under accounting{ } section
 of radiusd.conf
 
 *) Configuration:
 
-[1] Create a text file called sqlcounter.conf in the same
-directory where radiusd.conf resides (usually /usr/local/etc/raddb)
-with the following content (for mysql):
+The server has an example "dailycounter" in radiusd.conf.  It can be
+used for initial testing.  Other examples are given below.
 
-#-----#
+---------------------------------------------------------------------
+# Never reset
 sqlcounter noresetcounter {
                 counter-name = Max-All-Session-Time
                 check-name = Max-All-Session
@@ -34,13 +25,13 @@ sqlcounter noresetcounter {
 
         }
 
-
+# Reset daily
+# This is used to limit users per day, e.g. 3 hours/day
 sqlcounter dailycounter {
-                driver = "rlm_sqlcounter"
                 counter-name = Daily-Session-Time
                 check-name = Max-Daily-Session
-                reply-name = Session-Timeout
-                sqlmod-inst = sqlcca3
+               reply-name = Session-Timeout
+                sqlmod-inst = sql
                 key = User-Name
                 reset = daily
 
@@ -48,21 +39,22 @@ sqlcounter dailycounter {
 
         }
 
+# Reset monthly
+# This is used to limit users per month, e.g. 10 hours/month
 sqlcounter monthlycounter {
                 counter-name = Monthly-Session-Time
                 check-name = Max-Monthly-Session
-                reply-name = Session-Timeout
-                sqlmod-inst = sqlcca3
+               reply-name = Session-Timeout
+                sqlmod-inst = sql
                 key = User-Name
                 reset = monthly
 
                 query = "SELECT SUM(AcctSessionTime - GREATEST((%b - UNIX_TIMESTAMP(AcctStartTime)), 0)) FROM radacct WHERE UserName='%{%k}' AND UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'"
 
        }
+----------------------------------------------------------------------
 
-#-----#
-
-The respective lines for postgresql are:
+The respective queries for postgresql are:
 
 query = "SELECT SUM(AcctSessionTime) FROM radacct WHERE UserName='%{%k}'"
 query = "SELECT SUM(AcctSessionTime - GREATER((%b - AcctStartTime::ABSTIME::INT4), 0)) FROM radacct WHERE UserName='%{%k}' AND AcctStartTime::ABSTIME::INT4 + AcctSessionTime > '%b'"
@@ -95,14 +87,8 @@ BEGIN
 END;
 ' LANGUAGE 'plpgsql';
 
-[2] Include the above file to radiusd.conf by adding a line in
-modules{ } section
-
-modules {
-
-$INCLUDE  ${confdir}/sqlcounter.conf
-
-...some other entries here...
+[2] Add the appropriate module configuration (as above) to radiusd.conf,
+in the "modules" section.
 
 [3] Make sure to have the sqlcounter names under authorize section
 like the followings:
@@ -113,24 +99,16 @@ authorize {
 ...some entries here...
 ...some entries here...
 
-noresetcounter
-dailycounter
-monthlycounter
+# You probably only want only one of these
+       noresetcounter
+       dailycounter
+       monthlycounter
+... other entries here ...
 }
 
-noresetcounter: the counter that never resets, can be used
-for real session-time cumulation 
-
-dailycounter: the counter that resets everyday, can be used
-for limiting daily access time (eg. 3 hours a day)
-
-monthlycounter: the counter that resets monthly, can be used for
-limiting monthly access time (eg. 50 hours per month)
-
 You can make your own names and directives for resetting the counter
 by reading the sample sqlcounter configuration in
-raddb/experimental.conf
-
+raddb/radiusd.conf
 
 
 *) Implementation:
@@ -176,7 +154,7 @@ in sql:
 
 
 Note that Max-All-Session, Max-Daily-Session and Max-Monthly-Session are
-definied in sqlcounter.conf
+defined in sqlcounter.conf
 
 VERY IMPORTANT:
 Accounting must be done via sql or this will not work. 
index 166fcea..4a88861 100644 (file)
@@ -1,19 +1,8 @@
-Welcome to the SQL Based IP Pool module.
-
-**********************************************************************
-As of September 2006 this module is still under some development and
-currently is only tested by the developers on PostgreSQL (Version 8.1)
-                         Use it at your own risk!
-If plan to attempt to use a DB other than PostgreSQL please expect to
-have to do extra work which is not for SQL newbies. 
-Having said that it works great for us in production and should (with
-some work) function correctly with other SQL server types.
-**********************************************************************
-
+Welcome to the new SQL Based IP Pool module.
 
 To use the sqlipool module you simply need to have an IP-Pool Attribute
 (Keep in mind that its a **CHECK** item, not reply) in the required
-configuration file, which is either in files(users), sql or any other
+configuration file, which is either in files(users),sql or any other
 type of configuration schema.
 
 The initialization of the radippool table is left to the user instead of
@@ -23,18 +12,17 @@ resized, deleted at run time without radiusd needing to be restarted.
 
 The only required fields are, pool_name and ip_address. A pool consists
 of one or more rows in the table with the same pool_name and a different
-ip_address. There is no restriction on which ip addresses/ranges may be in
+ip_address. The is no restriction on which ip addresses/ranges may be in
 the same pool, and addresses do not need to be concurrent.
 
 We are currently using the variable definitions of the xlat module, so
 before editing the sqlippool.conf file, please go and read the
 variables.txt in the freeradius/doc directory. It will help you alot!..
 
-As you may noticed, there is a pool-key variable in the config file which
-allows you to select which attribute is unique according to your NAS setup.
-On a standard dialup NAS this is going to be "NAS-Port" but on an ethernet
-or wireless network it will probably be "Calling-Station-Id". Other more
-exotic options like "3GPP-IMSI" may also exist depending on your NAS.
-The only requirement is that the pool-key must be unique and must be
-received in both Access-Request and Accounting packages so that we know to
-clear the lease on the ip when the session disconnects.
+On the other hand, there is a "key", which is really the key for the
+pool modules in freeradius. As you may noticed, there is a pool-key
+variable on the config file to have a unique connection identifier for
+the requests.So, it should be set to the unique attribute of the
+packages that we are receiving. Also this unique identifier must be
+received in accounting-stop packages so that we release the used ip,
+from the pool and put it to the free-ips list.
diff --git a/doc/snmp b/doc/snmp
deleted file mode 100644 (file)
index a5add6b..0000000
--- a/doc/snmp
+++ /dev/null
@@ -1,30 +0,0 @@
-In 2.0, the RFC 2619 and RFC 2621 MIBs are more fully supported
-than in 1.x.
-
-Note that re-transmitted responses to duplicate
-requests do not increment these counters.
-
- total responses = Access-Accepts
-                  + Access-Challenges
-                  + Access-Rejects
-
-Pending requests mean "live" requests that the server is currently
-processing.
- pending requests = total requests
-                   - duplicate requests
-                   - bad authenticators
-                   - malformed requests
-                   - unknown types
-                   - packets dropped
-                   - total responses
-
-The IPv6-aware MIBS, (RFC 4669 and RFC 4671) are not currently
-supported.  Perhaps in 2.1.
-
-The client table for the server is also more fully supported than in
-1.x.
-
-However, the RADIUS client MIBs (RFC 2618, RFC 2620, RFC 4668, and RFC
-2670) are not supported.  Perhaps in 2.1.
-
index 3cdf8c7..5bb2f12 100644 (file)
      %{proxy-reply:Attribute-Name}   The value of the given Attribute-Name
                                      in the proxy reply packet (if it exists)
 
-  The above variable expansions also support the following
-meta-attributes.  These are not normal RADIUS attributes, but are
-created by the server to be used like them, for ease of use.  They can
-only be queried, and cannot be assigned.
-
-       Packet-Type             RADIUS packet type (Access-Request, etc.)
-
-       Packet-Src-IP-Address   IP address from which the packet was sent
-
-       Packet-Dst-IP-Address   IP address to which the packet was sent
-                               This may be "0.0.0.0", if the server
-                               was configured with "bind_address = *".
-
-       Packet-Src-Port         UDP port from which the packet was sent
-
-       Packet-Dst-Port         UDP port to which the packet was sent.
-
-        
+  The above variable expansions also support the meta-attribute
+Packet-Type as well. See the RADIUS dictionary for details on its
+values.
      %{check:Attribute-Name}         Corresponding value for Attribute-Name
                                      in check items for request
        
@@ -106,18 +92,8 @@ defined in 'sh'.  For example:
     When attribute Bar is unset:  returns literal string 'baz'
 
 
-  String Lengths
-  --------------
-
-  The dynamic translations support a few additional operatons, too.
-
-     %{#string}
-       The number of characters in %{string}.  If %{string} is not
-       set, then the length is not set.  This will NOT work for the
-       one-character variables defined below.
-
-       e.g. %{#Junk-junk:-foo} will yeild the string "foo".
-
+  Multiple-valued attributes
+  --------------------------
 
      %{Attribute-Name[index]}
        Reference the N'th occurance of the given attribute.  The
@@ -129,20 +105,6 @@ defined in 'sh'.  For example:
             Cisco-AVPair attribute (if it exists) in the request
             packet,
 
-     %{Attribute-Name[#]}
-       Returns the total number of attributes of that name in
-       the relevant attribute list.  The number will usually
-       be between 0 and 200.
-
-       e.g. For most requests, %{request:User-Name[#]} == 1
-
-     %{Attribute-Name[*]}
-       Expands to a single string, with the value of each array
-       member separated by a newline.
-
-     %{#Attribute-Name[index]}
-       Expands to the length of the string %{Attribute-Name[index]}.
-
 
   Attributes as environment variables in executed programs
   --------------------------------------------------------
index b6a33c7..889f05d 100644 (file)
@@ -3502,10 +3502,6 @@ lt_dlopenext (filename)
     LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
     return 0;  /* leaks tmp and handle */
   }
-  if (handle && errors) {
-    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
-    return 0;  /* leaks tmp and handle */
-  }
 
   /* If we found FILENAME, stop searching -- whether we were able to
      load the file as a module or not.  If the file exists but loading
@@ -3532,10 +3528,6 @@ lt_dlopenext (filename)
   else
     {
       tmp[len] = LT_EOS_CHAR;
-  if (handle && errors) {
-    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FR_DEPLIB));
-    return 0;  /* leaks tmp and handle */
-  }
     }
 
   strcat(tmp, shlib_ext);
diff --git a/ltconfig b/ltconfig
new file mode 100755 (executable)
index 0000000..cb0f4de
--- /dev/null
+++ b/ltconfig
@@ -0,0 +1,3074 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+  # find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.4
+TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}"   = Xset; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4* | osf5*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       can_build_shared=no
+       pic_flag=
+      else
+       echo "$ac_t"yes 1>&6
+       pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_o_lo=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_rtti_exceptions=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:991: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1015: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1018: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def  $objdir/$soname-ltdll.$objext $libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols'
+
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      for symbol in `cat $export_symbols`; do
+       echo "  \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def;
+       _lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+        whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+        whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+        strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+       # We have reworked collect2
+       hardcode_direct=yes
+      else
+       # We have old collect2
+       hardcode_direct=unsupported
+       # It fails to find uninstalled libraries when the uninstalled
+       # path is not listed in the libpath.  Setting hardcode_minus_L
+       # to unsupported forces relinking
+       hardcode_minus_L=yes
+       hardcode_libdir_flag_spec='-L$libdir'
+       hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    case "$host_os" in aix4.[01]|aix4.[01].*)
+      # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+      always_export_symbols=yes ;;
+    esac
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)  # As osf3* with the addition of the -msym flag
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  unixware7*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -B"
+         break
+       elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -p"
+         break
+       else
+         NM=${NM="$ac_dir/nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[        ]\($symcode\)[  ][      ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1635: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1636: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1639: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+         cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+         cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$objext conftstm.$objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if { (eval echo $progname:1691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+           pipe_works=yes
+         else
+           echo "$progname: failed program was:" >&5
+           cat conftest.c >&5
+         fi
+         LIBS="$save_LIBS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      deplibs_check_method=unknown
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    dynamic_linker='Linux ld.so'
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2212: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2220 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2252: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2257 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2299: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2307 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2339: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2344 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2387: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2395 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2452: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2457 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2490: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2498 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+              if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2563: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2571 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  esac
+
+  case "$lt_cv_dlopen_self" in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case "$lt_cv_dlopen_self_static" in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
index 258acc1..bd77498 100644 (file)
@@ -23,7 +23,7 @@ radclient - send packets to a RADIUS server, show reply
 .RB [ \-t
 .IR timeout ]
 .RB [ \-qvx ]
-\fIserver {acct|auth|status|disconnect|auto} secret\fP
+\fIserver {acct|auth|status|disconnect} secret\fP
 .SH DESCRIPTION
 \fBradclient\fP is a radius client program. It can send arbitrary radius
 packets to a radius server, then shows the reply. It can be used to
@@ -92,21 +92,7 @@ accounting packets, and \fBradius\fP for all other requests. If a
 service is not found in \fI/etc/services\fP, 1813 and 1812 are used
 respectively.
 
-The RADIUS attributes read by \fIradclient\fP can contain the special
-attribute \fBPacket-Dst-IP-Address\fP.  If this attribute exists, then
-that IP address is where the packet is sent, and the \fBserver\fP
-specified on the command-line is ignored.
-
-If the RADIUS attribute list always contains the
-\fBPacket-Dst-IP-Address\fP attribute, then the \fBserver\fP parameter
-can be given as \fB-\fP.
-
-The RADIUS attributes read by \fIradclient\fP can contain the special
-attribute \fBPacket-Dst-Port\fP.  If this attribute exists, then that
-UDP port is where the packet is sent, and the \fB:port\fP specified
-on the command-line is ignored.
-
-.IP acct\ |\ auth\ |\ status\ |\ disconnect\ |\ auto
+.IP acct\ |\ auth\ |\ status\ |\ disconnect
 Use \fBauth\fP to send an authentication packet (Access-Request),
 \fBacct\fP to send an accounting packet (Accounting-Request),
 \fBstatus\fP to send an status packet (Status-Server), or
@@ -114,15 +100,6 @@ Use \fBauth\fP to send an authentication packet (Access-Request),
 values, you can also use a decimal code here. For example, code 12 is
 also \fBStatus-Server\fP.
 
-The RADIUS attributes read by \fIradclient\fP can contain the special
-attribute \fBPacket-Type\fP.  If this attribute exists, then that type
-of packet is sent, and the \fItype\fP specified on the command-line
-is ignored.
-
-If the RADIUS attribute list always contains the
-\fBPacket-Type\fP attribute, then the \fBtype\fP parameter can be
-given as \fBauto\fP.
-
 .IP secret
 The shared secret for this client.  It needs to be defined on the
 radius server side too, for the IP address you are sending the radius
index ed75468..bbb7db5 100644 (file)
@@ -1,98 +1,63 @@
-.TH RADWHO 1 "7 April 2005" "" "FreeRADIUS Daemon"
+.TH RADWHO 1 "23 February 2001" "" "FreeRADIUS Daemon"
 .SH NAME
 radwho - show online users
 .SH SYNOPSIS
 .B radwho
-.RB [ \-c ]
 .RB [ \-d
 .IR raddb_directory ]
+.RB [ \-l ]
+.RB [ \-h ]
 .RB [ \-f ]
-.RB [ \-i ]
 .RB [ \-n ]
-.RB [ \-N
-.IR nas_ip_address ]
+.RB [ \-s ]
+.RB [ \-i ]
 .RB [ \-p ]
-.RB [ \-P
-.IR nas_port ]
+.RB [ \-c ]
 .RB [ \-r ]
-.RB [ \-R ]
-.RB [ \-s ]
-.RB [ \-S ]
-.RB [ \-u
-.IR user ]
-.RB [ \-U
-.IR user ]
-.RB [ \-Z ]
 .SH DESCRIPTION
 The FreeRADIUS server can be configured to maintain an active session
 database in a file called \fIradutmp\fP. This utility shows the
 content of that session database.
 .SH OPTIONS
-.IP \-c
-Shows caller ID (if available) instead of the full name.
 .IP \-d\ \fIraddb_directory\fP
 The directory that contains the RADIUS configuration files. Defaults to
 \fI/etc/raddb\fP.
+.IP \-l
+Show local shell users too. In this case, \fBradwho\fP reads the
+local "session database" aka the systems \fIutmp\fP file as well
+and shows the contents of that file before the contents of the
+radius "session database" aka the \fIradutmp\fP file, in the
+same format.
+.IP \-h
+Hide shell users. Doesn't show the entries for users that do not
+have a SLIP or PPP session.
 .IP \-f
 Behave as the 'fingerd' daemon - waits for one line of input, then
 prints the output with lines \\r\\n terminated.
-.IP \-i
-Shows the session ID instead of the full name.
 .IP \-n
 Normally radwho looks up the username in the systems password file,
 and shows the full username as well. The \fB-n\fP flags prevents this.
-.IP \-N\ \fInas_ip_address\fP
-Show only those entries which match the given NAS IP address.
+.IP \-s
+Show full name.
+.IP \-i
+Shows the session ID instead of the full name.
 .IP \-p
 Adds an extra column for the port type - I for ISDN, A for Analog.
-.IP \-P\ \fInas_port\fP
-Show only those entries which match the given NAS port.
+.IP \-c
+Shows caller ID (if available) instead of the full name.
 .IP \-r
 Outputs all data in \fIraw\fP format - no headers, no formatting,
-fields are comma-separated.
-.IP \-R
-Output all data in RADIUS attribute format.  All fields are printed.
-.IP \-s
-Show full name.
-.IP \-S
-Hide shell users. Doesn't show the entries for users that do not
-have a SLIP or PPP session.
-.IP \-u\ \fIuser\fP
-Show only those entries which match the given username (case insensitive).
-.IP \-U\ \fIuser\fP
-Show only those entries which match the given username (case sensitive).
-.IP \-Z
-When combined with \fI-R\fP, prints out the contents of an
-Accounting-Request packet which can be passed to \fIradclient\fP, in
-order to "zap" that users session from \fIradutmp\fP.
-.PP
-For example,
-.RS
-.sp
-.nf
-.ne 3
-$ radwho -ZRN 10.0.0.1 | radclient -f - radius.example.net acct testing123
-.fi
-.sp
-.RE
-will result in all an Accounting-Request packet being sent to the
-RADIUS server, which tells the server that the NAS rebooted.  i.e. It
-"zaps" all of the users on that NAS.
+fields are comma-seperated.
 
-To "zap" one user, specifiy NAS, username, and NAS port:
-.RS
-.sp
-.nf
-.ne 3
-$ radwho -ZRN 10.0.0.1 -u user -P 10 | radclient -f - radius.example.net acct testing123
-.fi
-.sp
-.RE
-Other combinations are also possible.
+.SH SEE ALSO
+radiusd(8).
+.SH AUTHOR
+Miquel van Smoorenburg, miquels@cistron.nl.
 
 .SH SEE ALSO
 radiusd(8),
-radclient(1),
-radiusd.conf(5).
+radiusd.conf(5),
+wtmp(5),
+last(1).
 .SH AUTHOR
 Miquel van Smoorenburg, miquels@cistron.nl.
index a87bf60..3403cb0 100644 (file)
@@ -1,62 +1,47 @@
-.TH RADZAP 1 "8 April 2005" "" "FreeRadius Daemon"
+.TH RADZAP 1 "16 May 2002" "" "FreeRadius Daemon"
 .SH NAME
 radzap - remove rogue entries from the active sessions database
 .SH SYNOPSIS
 .B radzap
 .RB [ \-d
 .IR raddb_directory ]
-.RB [ \-N
-.IR nas_ip_address ]
-.RB [ \-P
-.IR nas_port ]
-.RB [ \-u
-.IR user ]
-.RB [ \-U
-.IR user ]
-\fIserver[:port] secret\fP
+.RB [ \-r
+.IR radius_server ]
+.RB [ \-p
+.IR accounting_port ]
+.RB [ \-v ]
+.I nas
+.RB [ port ]
+.RB [ username ]
 .SH DESCRIPTION
 The FreeRadius server can be configured to maintain an active session
 database in a file called \fIradutmp\fP. Commands like \fBradwho\fP(1)
 use this database. Sometimes that database can get out of sync, and
 then it might contain rogue entries. \fBradzap\fP can clean up this
 database.
-
-As of FreeRADIUS 1.1.0, \fBradzap\fP is a simple shell-script wrapper
-around \fBradwho\fP(1) and \fBradclient\fP(1).
-
-The sessions are "zapped" by sending an Accounting-Request packet
-which contains the information necessary for the server to delete the
-session record.  \fBradzap\fP sends a packet to the server, rather
-than writing to \fIradutmp\fP directly, because session records may
-also be maintained in SQL.
 .SH OPTIONS
 .IP \-d\ \fIraddb_directory\fP
 The directory that contains the RADIUS configuration files.
-\fBradzap\fP reads \fIradiusd.conf\fP to determine the location of the
-\fIradutmp\fP file.
-.IP \-N\ \fInas_ip_address\fP
-Zap the entries which match the given NAS IP address.
-.IP \-P\ \fInas_port\fP
-Zap the entries which match the given NAS port.
-.IP \-u\ \fIuser\fP
-Zap the entries which match the given username (case insensitive).
-.IP \-U\ \fIuser\fP
-Zap the entries which match the given username (case sensitive).
-.IP server[:port]
-The hostname or IP address of the remote server. Optionally a UDP port
-can be specified. If no UDP port is specified, it is looked up in
-\fI/etc/services\fP. The service name looked for is \fBradacct\fP for
-accounting packets, and \fBradius\fP for all other requests. If a
-service is not found in \fI/etc/services\fP, 1813 and 1812 are used
-respectively.
-.IP secret
-The shared secret for this client.  It needs to be defined on the
-radius server side too, for the IP address you are sending the radius
-packets from.
+.IP \-r\ \fIradius_server\fP
+Host name or IP address of the RADIUS server.
+.IP \-p\ \fIaccounting_port\fP
+The port to which accounting packets are sent.  See "/etc/services",
+port "radacct" for the default on your system (usually 1646 or 1813).
+.IP \-v
+Verbose. Shows you what it is doing.
+.IP nas
+Hostname or IP address of the NAS (Network Access Server, sometimes
+called "terminal server") of the session you want to remove.
+.IP port
+Port of the session you want to remove. This is the NAS-Port
+radius attribute, it doesn't have anything to do with UDP port
+numbers. Must be an integer. \fB-1\fP means "any", and is the
+default if this option is not specified.
+.IP username
+Optional: the username of the session you want to remove.
 .SH SEE ALSO
 radwho(1),
-radclient(1),
 radiusd(8),
 radiusd.conf(5).
 .SH AUTHOR
-Alan DeKok <aland@ox.org>
+Miquel van Smoorenburg, miquels@cistron.nl., and others.
index fdaf1df..c186e6e 100644 (file)
@@ -1,9 +1,31 @@
-.TH CLIENTS 5 "22 August 2002"
+.TH CLIENTS 5 "16 March 2001"
 .SH NAME
-clients \- FreeRADIUS configuration file.
+clients \- RADIUS clients file
 .SH DESCRIPTION
-This configuration file is no longer used by the server, and will not
-be read by the server. See the "scripts/clients.pl" program for a way
-to migrate this file to the new format.
+The \fIclients\fP file resides in the radius database directory,
+by default \fI/etc/raddb\fP. Its use is depreciated in favour of 
+\fIclients.conf\fP.
+
+Every line starting with a hash sign
+.RB (' # ')
+is treated as comment and ignored.
+.PP
+Each line of the file contains two white-space delimited fields.
+.IP client\ hostname
+The RADIUS clients hostname.  This may be a plain hostname, or a
+dotted-quad IP address.
+.IP secret
+This is the so-called "shared secret" that is held between a RADIUS
+server and client. It is used to encrypt passwords in RADIUS packets,
+and also for authentication. You need to configure the same secret
+on the client (terminal server) as in this file.
+.PP
+The
+.I clients
+file is read by \fBradiusd\fP on startup only.
+.SH FILES
+.I /etc/raddb/clients
 .SH "SEE ALSO"
+.BR radiusd (8),
 .BR clients.conf (5)
+.BR naslist (5)
diff --git a/man/man5/clients.conf.5 b/man/man5/clients.conf.5
deleted file mode 100644 (file)
index 428646b..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-.TH clients.conf 5 "13 June 2005" "" "FreeRADIUS client configuration"
-.SH NAME
-clients.conf \- FreeRADIUS client configuration
-.SH DESCRIPTION
-The 
-.I clients.conf
-file contains definitions of RADIUS clients.
-.PP
-The information in this file overrides any information provided in
-the deprecated 
-.BR clients (5)
-and 
-.BR naslist (5)
-files.
-.PP
-The file format is the same as that used for
-.I radiusd.conf.
-See 
-.BR radiusd.conf (5)
-for more details.
-.PP
-Each RADIUS client entry has the following basic form:
-.IP
-.nf
-client <hostname|ip-address|ip-network> {
-       <attribute> = <value>
- }
-.fi
-.LP
-ip-network is used to specify a network of clients. Networks are
-specified in CIDR notation. If multiple overlapping networks are
-defined, the best match (smallest possible network) will be chosen for
-a packet.
-.SH ATTRIBUTES
-The attributes that can appear in a 
-.B client
-section are listed below. Required attributes are labelled as
-such. All other attributes are optional.
-.PP
-.TP 0.5i
-.B secret [Required]
-The RADIUS shared secret used for communication between the client/NAS
-and the RADIUS server.
-.TP 0.5i
-.B shortname [Required]
-A short alias that can be used in place of the IP address or fully
-qualified hostname provided in the first line of the section.
-.TP 0.5i
-.B nastype
-The nastype attribute is used to tell the 
-.BR checkrad.pl
-script which NAS-specific method it should use when checking
-simultaneous use.
-
-The following values are currently recognized:
-.nf
-cisco
-computone
-livingston
-max40xx
-multitech
-netserver
-pathras
-patton
-portslave
-tc
-usrhiper
-other
-.fi
-.TP 0.5i
-.B login
-Reserved for future use.
-.TP 0.5i
-.B password
-Reserved for future use.
-.SH EXAMPLES
-.IP
-.nf
-client 127.0.0.1 {
-        secret          = testing123
-        shortname       = localhost
-        nastype         = other     
-}
-.fi
-.LP
-This adds a client for the loopback address. This is useful in testing
-the 
-server locally, for example with 
-.BR radclient (1).
-.IP
-.nf
-client 192.168.0.0/24 {
-       secret          = testing123-1
-       shortname       = private-network-1
-}
-.fi
-.LP
-This entry represents any client from the 192.168.0.0/24 network. 
-.SH FILES
-.I /etc/raddb/clients.conf
-
-.I /etc/raddb/radiusd.conf
-.SH "SEE ALSO"
-.BR radiusd (8),
-.BR radiusd.conf (5),
-.BR clients (5),
-.BR naslist (5)
-
-.SH AUTHOR
-This manual page was authored by Shawn K. O'Shea <shawn@eth0.net>.
-
-FreeRADIUS is authored by the FreeRADIUS team. 
-http://freeradius.org/
index 893d199..a88e633 100644 (file)
@@ -1,11 +1,30 @@
-.TH NASLIST 5 "12 August 2005"
+.TH NASLIST 5 "15 September 1997"
 .SH NAME
 naslist \- RADIUS naslist file
 .SH DESCRIPTION
-naslist \- FreeRADIUS configuration file.
-.SH DESCRIPTION
-This configuration file is no longer used by the server, and will not
-be read by the server. See the "scripts/clients.pl" program for a way
-to migrate this file to the new format.
+The \fInaslist\fP file resides in the radius database directory,
+by default \fI/etc/raddb\fP. It contains a list of RADIUS network access
+servers (NASes).
+Every line starting with a hash sign
+.RB (' # ')
+is treated as comment and ignored.
+.PP
+Each line of the file contains three white-space delimited fields.
+.IP client\ hostname
+The NAS hostname. This may be a plain hostname, or a
+dotted-quad IP address.
+.IP shortname
+This field is optional, and declares a short alias for the NAS.
+.IP NAStype
+Type of NAS (terminalserver). This can be \fIlivingston\fP, \fIcisco\fP,
+\fIportslave\fP or \fIother\fP. This is passed to the external \fBchecklogin\fP
+program when it is called to detect double logins.
+.PP
+The
+.I naslist
+file is read by \fBradiusd\fP on startup only.
+.SH FILES
+.I /etc/raddb/naslist
 .SH "SEE ALSO"
-.BR clients.conf (5)
+.BR radiusd (8),
+.BR clients (5)
diff --git a/man/man5/radrelay.conf.5 b/man/man5/radrelay.conf.5
deleted file mode 100644 (file)
index 9dc12bd..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-.TH radrelay.conf 5 "27 May 2005" "" "FreeRADIUS configuration file"
-.SH NAME
-radrelay.conf \- configuration file for the FreeRADIUS server "radrelay" personality
-.SH DESCRIPTION
-The \fBradrelay.conf\fP file resides in the radius database directory,
-by default \fB/etc/raddb\fP.  It defines the global configuration for
-the FreeRADIUS server, when the server is operating as "radrelay".
-.SH "FILE FORMAT"
-For a detailed description of the file format, see "man radiusd.conf".
-The configuration entries are much the same for radrelay.conf, with a
-few differences as noted here.
-.SH "REPLICATION FOR BACKUPS"
-Many sites run multiple radius servers; at least one primary and one
-backup server. When the primary goes down, most NASes detect that and
-switch to the backup server.
-
-That will cause your accounting packets to go the the backup server -
-and some NASes don't even switch back to the primary server when it
-comes back up.
-
-The result is that accounting records are missed, and/or the
-administrator must jump through hoops in order to combine the
-different detail files from multiple servers. It also means that the
-session database ("radutmp", used for radwho and simultaneous use
-detection) gets out of sync.
-
-radrelay solves this issue by "relaying" packets from one server to
-another, so they both have the same set of accounting data.
-.SH "BUFFERING FOR HIGH-LOAD SERVERS"
-If the RADIUS server suddenly receives a many accounting packets,
-there may be insufficient CPU power to process them all in a timely
-manner.  This problem is especially noticable when the accounting
-packets are going to a back-end database.
-
-Similarly, you may have one database that tracks "live" sessions, and
-another that tracks historical accounting data.  In that case,
-accessing the first database is fast, as it is small.  Accessing the
-second database many be slower, as it may contain multiple gigabytes
-of data.  In addition, writing to the first database in a timely
-manner is important, while data may be written to the second database
-with a few minutes delay, without any harm being done.
-.SH "RELAYING OF ACCOUNTING PACKETS"
-The \fBradrelay.conf\fP file controls the "radrelay" personality of
-the server, which can perform both of the functions above at the same
-time.
-.SH USAGE
-First, you should configure the main radius server to log to an extra,
-single detail file.  This may be done by adding an extra instance of
-the detail module to \fBradiusd.conf\fP:
-
-For example:
-
-.DS
-       detail radrelay-detail {
-.br
-               detailfile = ${radacctdir}/radrelay/detail
-.br
-               detailperm = 0600
-.br
-               dirperm = 0755
-.br
-               locking = yes
-.br
-       }
-.br
-       ...
-.br
-       accounting {
-.br
-               ...
-.br
-               radrelay-detail
-.br
-               ...
-.br
-       }
-.br
-.DE
-This configuration will cause accounting packets to be logged to the
-\fI${radacctdir}/radrelay/detail\fP file.  This file should not be
-rotated by standard log rotation scripts, as the \fBradrelay\fP
-program will read and rotate it.
-.SH RADRELAY.CONF EXAMPLE
-See the \fBradrelay.conf\fP file for detailed instructions on
-configuration entries, what they mean, and how to use them.
-
-To have the "radrelay" portion of the server read the above detail
-file, configure \fBradrelay.conf\fP with the following section:
-
-.DS
-.br
-       listen {
-.br
-               type = detail
-.br
-               detail = ${radacctdir}/radrelay/detail
-.br
-               max_outstanding = 100
-.br
-               identity = radrelay
-.br
-       }
-.br
-.DE
-
-The server will read the accounting packets from the detail file, and
-process them just as if it had received them from the NAS.  Therefore,
-you should configure the "accounting" section of \fBradrelay.conf\fP
-to write the accounting records to an "sql" module, or to proxy them
-to another RADIUS server.
-
-Then, start the server via the following command:
-
-$ radiusd -n radrelay
-
-The server should start up, read the detail file, and process
-accounting packets from it.
-.SH NOTES
-The \fBradiusd.conf\fP file is not read at all when the server is
-running as radrelay.  Please edit \fBradrelay.conf\fP.
-.SH CREDITS
-The original "radrelay" program was written by Miquel van Smoorenburg
-for the Cistron radius project, and ported to FreeRADIUS by Simon
-Ekstrand.  The "radsqlrelay" was written by Kostas Kalavras.  It was
-never released as part of an offical FreeRADIUS release, but served as
-a basis for the design of this implementation.
-.PP
-.SH FILES
-/etc/raddb/radrelay.conf
-.SH "SEE ALSO"
-.BR radiusd (8),
-.BR radiusd.conf (5)
-.SH AUTHOR
-Alan DeKok <aland@ox.org>
index 6f79c07..0db2cc2 100644 (file)
@@ -3,24 +3,23 @@
 rlm_attr_filter \- FreeRADIUS Module
 .SH DESCRIPTION
 The \fIrlm_attr_filter\fP module exists for filtering certain
-attributes and values in received ( or transmitted ) radius packets.
-It gives the server a flexible framework to filter the attributes we
-send to or receive from home servers or NASes.  This makes sense, for
-example, in an out-sourced dialup situation to various policy
-decisions, such as restricting a client to certain ranges of
-Idle-Timeout or Session-Timeout.
+attributes and values in received ( or transmitted ) radius packets
+from ( or to ) remote proxy servers.  It gives the proxier ( us ) a
+flexible framework to filter the attributes we send to or receive
+from these remote proxies.  This makes sense, for example, in an
+out-sourced dialup situation to various policy decisions, such as
+restricting a client to certain ranges of Idle-Timeout or
+Session-Timeout.
 .PP
-Filter rules are normally defined and applied on a per-realm basis,
-where the realm is anything that is defined and matched based on the
-configuration of the \fIrlm_realm\fP module.  Filter rules can
-optionally be applied using another attribute, by editing the
-\fIkey\fP configuration for this module.
+Filter rules are defined and applied on a per-realm basis, where the
+realm is anything that is defined and matched based on the
+configuration of the \fIrlm_realm\fP module.
 .PP
 The file that defines the attribute filtering rules follows a similar
 syntax to the \fIusers\fP file.  There are a few differences however:
 .PP
 .DS
-    There are no check-items allowed other than the name of the key.
+    There are no check-items allowed other than the realm.
 .PP
     There can only be a single DEFAULT entry.
 .PP
@@ -59,7 +58,7 @@ Greater Than or Equal
 Less Than or Equal
 .TP
 .B    >   
-Greater Than
+Greather Than
 .TP
 .B    <   
 Less Than
@@ -80,22 +79,15 @@ See the default \fI/etc/raddb/attrs\fP for working examples of
 sample rule ordering and how to use the different operators.
 .DE
 .PP
-The configuration items are:
+The main configuration item is:
 .IP attrsfile
 This specifies the location of the file used to load the filter rules.
-This file is used to filter the accounting response, packet before it
-is proxied, proxy response from the home server, or our response to
-the NAS.
-.IP key
-Usually %{Realm} (the default).  Can also be %{User-Name}, or other
-attribute that exists in the request.  Note that the module always
-keys off of attributes in the request, and NOT in any other packet.
 .PP
 .SH SECTIONS
+.BR authorization,
 .BR accounting,
-.BR pre-proxy,
-.BR post-proxy,
-.BR post-auth
+.BR preproxy,
+.BR postproxy
 .PP
 .SH FILES
 .I /etc/raddb/radiusd.conf
index 2936b05..f6274f8 100644 (file)
@@ -44,10 +44,6 @@ syntax in the Users file to set a cap of 3600 seconds ( 8 hours ):
 DEFAULT Max-Daily-Session := 3600
 .DE
 .PP
-.IP reply-name
-This is the name of the attribute which will contain the remaining value for
-the counter in the reply packet when the user is successfully authorized. The
-default attribute name is "Session-Timeout".
 .IP allowed-servicetype
 This can be used to only apply the limitations to specific service types of
 sessions.  For example, setting this to Framed-User will only apply the counter
diff --git a/man/man5/rlm_digest.5 b/man/man5/rlm_digest.5
deleted file mode 100644 (file)
index af97ee8..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-.TH rlm_digest 5 "31 March 2005" "" "FreeRADIUS Module"
-.SH NAME
-rlm_digest \- FreeRADIUS Module
-.SH DESCRIPTION
-The \fIrlm_digest\fP module authenticates RADIUS Access-Request
-packets that contain Cisco SIP digest authentication attributes.  The
-module should be listed in the \fIauthorize\fP and \fIauthenticate\fP
-sections of \fIradiusd.conf\fP.
-.SH CONFIGURATION
-The digest module requires no additional configuration items.  When it
-is being used to authenticate requests, however, it does require
-access to the clear-text password for the user.  Hashed passwords are
-not acceptable, and will not work.
-.SH EXAMPLES
-Add the following lines to the top of your 'raddb/users' file:
-.PP
-.DS
-#---
-.br
-test   Auth-Type := Digest, User-Password = "test"
-.br
-       Reply-Message = "Hello, test with digest"
-.br
-#---
-.DE
-
-Once the server has been started (debugging mode is recommended),
-use '\fIradclient\fP to send the following packet to the server:
-.PP
-.DS
-$  radclient -f digest localhost auth testing123
-.DE
-
-Where 'digest' is a file containing:
-.PP
-.DS
-  User-Name = "test",
-.br
-  Digest-Response = "631d6d73147add2f9e437f59bbc3aeb7",
-.br
-  Digest-Realm = "testrealm",
-.br
-  Digest-Nonce = "1234abcd",
-.br
-  Digest-Method = "INVITE",
-.br
-  Digest-URI = "sip:5555551212@example.com",
-.br
-  Digest-Algorithm = "MD5",
-.br
-  Digest-User-Name = "test",
-.br
-  Message-Authenticator = ""
-.DE
-
-You should see the authentication succeed.
-
-.SH SECTIONS
-.BR authorize,
-.BR authenticate
-.PP
-.SH FILES
-.I /etc/raddb/radiusd.conf,
-.I draft-sterman-aaa-sip-00.txt
-.PP
-.SH AUTHOR
-Alan DeKok <aland@ox.org>
index 65ea8e1..70d5cb5 100644 (file)
@@ -21,24 +21,6 @@ pre_proxy stage of this module.
 This option allows FreeRADIUS to parse an old style Cistron syntax.
 The default is 'no'.  If you need to parse an old style Cistron
 file, set this option to 'cistron'.
-.IP key
-This option lets you set the attribute to use as a key to find
-entries.  The default is "%{Stripped-User-Name:-%{User-Name}}".  Note
-that the key MUST supply real data.  Dynamic attributes like "Group"
-will not work, because the "Group" attribute can only be used as a
-comparison, to see if a user is in a Unix group.  It will not return
-the name of the Unix group that a user is in.
-.PP
-If you want to use groups as a key, see the \fIrlm_passed\fP, which
-will create a real attribute that contains the group name.
-.PP
-This configuration entry enables you to have configurations that
-perform per-group checks, and return per-group attributes, where the
-group membership is dynamically defined by a previous module.  It also
-lets you do things like key off of attributes in the reply, and
-express policies like like "when I send replies containing attribute
-FOO with value BAR, do more checks, and maybe send additional
-attributes".
 .SH CONFIGURATION
 .PP
 .DS
@@ -55,8 +37,6 @@ modules {
 .br
     compat = no
 .br
-    key = %{Stripped-User-Name:-%{User-Name}}
-.br
   }
 .br
   ... stuff here ...
index 2aedda1..9e8572b 100644 (file)
@@ -1,32 +1,29 @@
-.TH rlm_mschap 5 "13 March 2004" "" "FreeRADIUS Module"
+.TH rlm_mschap 5 "19 May 2006" "" "FreeRADIUS Module"
 .SH NAME
 rlm_mschap \- FreeRADIUS Module
 .SH DESCRIPTION
 The \fIrlm_mschap\fP module provides MS-CHAP and MS-CHAPv2
 authentication support. 
 .PP
-This module validates a user with MS-CHAP or MS-CHAPv2 
-authentication.
-If called in Authorize, it will look for MS-CHAP Challenge/Response
-attributes in the Acess-Request and adds an Auth-Type
-attribute set to MS-CHAP in the Config-Items list unless 
-Auth-Type has already set.
+This module validates a user with MS-CHAP or MS-CHAPv2 authentication.
+It should be listed in both the \fIauthorize\fP and \fIauthenticate\fP
+sections.  In \fIauthorize\fP, it will look for MS-CHAP
+Challenge/Response attributes in the Acess-Request, and configure
+itself to be the module called for the \fIauthenticate\fP section.
 .PP
 The module can authenticate the MS-CHAP session via plain-text
 passwords (User-Password attribute), or NT passwords (NT-Password
-attribute).  The module cannot perform authentication against an NT
-domain.
-.PP
+attribute).  The module can perform authentication against an NT
+domain by using the \fIntlm_auth\fP program.
+.SH SMB Integration
 The module also enforces the SMB-Account-Ctrl attribute.  See the
 Samba documentation for the meaning of SMB account control.  The
-module does not read Samba password files.  Instead, the fIrlm_passwd\fP
-module can be used to read a Samba password file, and supply an
-NT-Password attribute which this module can use.
-.PP
+module does not read Samba password files.  Instead, the
+\fIrlm_passwd\fP module should be used to read a Samba password file,
+and to supply an NT-Password attribute which this module can use.  See
+the \fIetc_smbpasswd\fP module in \fIradiusd.conf\fP for more details.
+.SH MODULE CONFIGURATION
 The main configuration items to be aware of are:
-.IP authtype
-This is the string used to set the authtype.  Normally it should be
-left to the default value of MS-CHAP.
 .IP use_mppe
 Unless this is set to 'no', FreeRADIUS will add MS-CHAP-MPPE-Keys for
 MS-CHAPv1 and MS-MPPE-Recv-Key/MS-MPPE-Send-Key for MS-CHAPv2.  The
@@ -43,45 +40,20 @@ The default is 'no'.
 Windows clients send User-Name in the form of "DOMAIN\\User", but send the
 challenge/response based only on the User portion.  Setting this value
 to yes, enables a work-around for this error.  The default is 'no'.
-.PP
-.SH CONFIGURATION
+.IP ntlm_auth
+Use the \fIntlm_auth\fP program for authentication against Samba, or a
+Windows NT or Active Directory Domain Controller.  For machine
+authentication, the following configuration should be used:
+.DS
+ntlm_auth = "/path/to/ntlm_auth --username=%{mschap:User-Name:-None} --challenge=%{mschap:Challenge:-00} --nt-response=%{mschap:NT-Response:-00} --domain=%{mschap:NT-Domain:-YOUR_DEFAULT_DOMAIN}
+.DE
+If configured, \fIntlm_auth\fP will always be called, even if there is
+a clear-text or NT-Password available for the user.  You can force
+\fIntlm_auth\fP to not be used by setting
 .DS
-modules {
-  ...
-.br
-  mschap {
-.br
-       authtype = MS-CHAP
-.br
-       use_mppe = yes  
-.br
-  }
-.br
-  ...
-.br
-}
-.br
- ...
-.br
-authorize {
-  ...
-.br
-  mschap
-.br
-  ...
-.br
-}
- ...
-.br
-authenticate {
-  ...
-.br
-  mschap
-.br
-  ...
-.br
-}
+MS-CHAP-Use-NTLM-Auth := No
 .DE
+in the \fIusers\fP file, or in a database such as SQL.
 .PP
 .SH SECTIONS
 .BR authorization,
index 4223daa..b4dbfac 100644 (file)
-.TH rlm_pap 5 "8 February 2005" "" "FreeRADIUS Module"
+.TH rlm_pap 5 "3 February 2004" "" "FreeRADIUS Module"
 .SH NAME
 rlm_pap \- FreeRADIUS Module
 .SH DESCRIPTION
-The \fIrlm_pap\fP module authenticates RADIUS Access-Request packets
-that contain a User-Password attribute.  The module should also be
-listed last in the \fIauthorize\fP section, so that it can set the
-Auth-Type attribute as appropriate.
+The \fIrlm_pap\fP module performs PAP authentication.
 .PP
-When a RADIUS packet contains a clear-text password in the form of a
-User-Password attribute, the \fIrlm_pap\fP module may be used for
-authentication.  The module requires a "known good" password, which it
-uses to validate the password given in the RADIUS packet.  That "known
-good" password must be supplied by another module
-(e.g. \fIrlm_files\fP, \fIrlm_ldap\fP, etc.), and is usually taken
-from a database.
-.SH CONFIGURATION
+This module performs authentication when the Access-Request contains a
+User-Password attribute AND when a "known good" password has been
+configured for the user.  In addition, it takes care of decoding the
+"known good" password from hex or Base64 encoding to a form it can use
+for authentication.
 .PP
-The only relevant configuration item is:
+As a result, as of 1.1.4, the "encryption_scheme" configuration item
+SHOULD NOT BE USED, and the rlm_ldap configuration
+item "password_header" SHOULD NOT BE USED.  Those items will continue to work
+in 1.1.4, and existing systems will work un-changed after upgrading to
+1.1.4.  We recommend, though, that sites using multiple instances of
+rlm_pap see if they can replace those multiple instances with one instance,
+using the new "auto_header" configuration, and remove the "password_header"
+configuration from rlm_ldap.
+.PP
+The configuration item(s):
 .IP auto_header
-If set to "yes", the module will look inside of the User-Password
-attribute for the headers {crypt}, {clear}, etc., and will
-automatically create the appropriate attribute, with the correct
-value.
+Automatically discover password headers.  Permitted values are "yes"
+and "no".  For backwards compatibility, the default is "no".
+.IP
+The recommended value is "yes".
+.IP encryption_scheme
+No longer used, and therefore no longer documented.
 .PP
-This module understands many kinds of password hashing methods, as
-given by the following table.
+When "auto_header" is set to "yes", the module will look in the
+configuration list for the User-Password attribute or the new
+Password-With-Header attribute.  If found, it will then look at the
+string value of those attributes, for one of the following headers:
 .PP
 .DS
+.br    
+       {clear}
 .br
-Header       Attribute          Description
-.br
-------       ---------          -----------
-.br
-{clear}      User-Password      clear-text passwords
-.br
-{cleartext}  User-Password      clear-text passwords
+       {cleartext}
 .br
-{crypt}      Crypt-Password     Unix-style "crypt"ed passwords
+       {crypt}
 .br
-{md5}        MD5-Password       MD5 hashed passwords
+       {md5}
 .br
-{smd5}       SMD5-Password      MD5 hashed passwords, with a salt
+       {smd5}
 .br
-{sha}        SHA-Password       SHA1 hashed passwords
+       {sha1}
 .br
-{ssha}       SSHA-Password      SHA1 hashed passwords, with a salt
+       {ssha1}
 .br
-{nt}         NT-Password        Windows NT hashed passwords
+       {nt}
 .br
-{x-nthash}   NT-Password        Windows NT hashed passwords
+       {x-nthash}
 .br
-{lm}         LM-Password        Windows Lan Manager (LM) passwords.
+       {ns-mta-md5}
 .DE
-
-The module tries to be flexible when handling the various password
-formats.  It will automatically handle Base-64 encoded data, hex
-strings, and binary data, and convert them to a format that the server
-can use.
 .PP
-For backwards compatibility, there are old configuration parameters
-which may be work, although we do not recommend using them.
+The text following the header is taken as the "known good" password,
+either cleartext, crypted, hashed, or hashed with a salt.  If the text
+is hex or Base64 encoded, it will be decoded to obtain the correct
+form of the "known good" password.  The User-Password in the
+Access-Request will then be crypted, or hashed as appropriate, and
+compared to the "known good" password.  If they match, the user is
+authenticated, otherwise the module returns reject.
+.SH CAVEATS
+In order for the "auto_header = yes" functionality to work, the
+\fIpap\fP module MUST be listed LAST in the \fIauthorize\fP section of
+\fIradiusd.conf\fP.  This lets other modules such as LDAP blindly add
+a "known good" password to the configuration items, and the PAP module
+will just figure it out.  In most cases, multiple instances of the PAP
+module, along with complex logic to determine which one to call when,
+can be replaced with one instance of the module, with it listed last
+in the \fIauthorize\fP section.
+.PP
+Note that the \fIns_mta_md5\fP module is no longer necessary, and can
+be removed.
+.PP
+Also, setting "Auth-Type = Local" or "Auth-Type = Crypt-Local" is no
+longer necessary.  Any such settings SHOULD BE DELETED.  Simply list
+\fIpap\fP LAST in the \fIauthorize\fP section, and the module will
+take care of figuring out what to do.  (Have we emphasized that enough?)
+.PP
+Another reason to list the module last is that it will take care of
+normalizing any crypt'd or hashed password retrieved from a database.
+So it is now safe to have clear-text passwords as "{clear}...",
+because the PAP module will take care of removing the "{clear}" prefix
+from the password.  Any other modules that need access to the
+cleartext password will
+.PP
+The module uses a number of new attributes.
+.IP Password-With-Header
+This attribute should contain a "known good" password, with a header
+such as "{crypt}, or "{md5}", etc.  It should be used when the
+passwords retrieved from a DB may have different headers.  When
+\fIpap\fP is listed in the \fIauthorize\fP section, the module will
+examine this attribute, and use it to create one of the other
+attributes listed below.  That other attribute is then used for
+authentication.
+.IP
+If the passwords in a DB do not have a header, and are always in one
+particular form, then the attributes listed below can be used
+directly.  In that case, the PAP module will do hex or Base64 decoding
+of the attribute contents, if necessary.  So \fIpap\fP should still be
+listed in the \fIauthorize\fP section, because it will enable the
+maximum flexibility for the server, and minimize configuration for the
+administrator.
+.IP Cleartext-Password
+This attribute should contain the cleartext for a "known good"
+password.  Previously, the User-Password attribute was overloaded to
+contain this, both in the FAQ and in databases in many sites.  Any
+configuration that sets a cleartext form of the password using
+User-Password SHOULD UPDATE to using Cleartext-Password.  Doing so
+will simplify a number of debugging issues.
+.IP Crypt-Password
+This attribute has been around for a while, but is documented here for
+completeness.  It contains the crypt'd form of the password.
+.IP MD5-Password
+This attribute contains the MD5 hashed form of the password.
+.IP SMD5-Password
+This attribute contains the MD5 hashed form of the password, with a salt.
+.IP SHA1-Password
+This attribute contains the SHA1 hashed form of the password.
+.IP SSHA1-Password
+This attribute contains the SHA1 hashed form of the password, with a salt.
+.IP NT-Password
+This attribute has been around for a while, but is documented here for
+completeness.  It contains the NT hash form of the password, as used
+by Active Directory and Samba.
 .SH SECTIONS
 .BR authorize
 .BR authenticate
@@ -72,4 +139,3 @@ which may be work, although we do not recommend using them.
 .BR radiusd.conf (5)
 .SH AUTHOR
 Alan DeKok <aland@freeradius.org>
-
index 5f01538..bdbd394 100644 (file)
@@ -35,6 +35,9 @@ default) the module will warn about duplicated records.
 .IP ignorenislike
 If set to 'yes', then all records from the file beginning with the '+'
 sign will be ignored.  The default is 'no'.
+.IP authtype
+If an entry matches, the Auth-Type for the request will be set to the
+one specified here.
 .IP format
 The format of the fields in the file, given as an example line from
 the file, with the content of the fields as the RADIUS attributes
@@ -54,11 +57,6 @@ prefix the attribute name in the "format" string with the '~' character.
 .PP
 To add an attribute to the reply (to be sent back to the NAS) prefix
 the attribute name in the "format" string with the '=' character.
-.IP ignoreempty
-This configuration item defaults to "yes".  If there is no value for
-the attribute, then the attribute is not added.  By setting this value
-to "no", you can force the attribute to be added, even if there is no
-value.
 
 .SH EXAMPLES
 .DS
diff --git a/man/man5/rlm_policy.5 b/man/man5/rlm_policy.5
deleted file mode 100644 (file)
index b664580..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-.TH rlm_policy 5 "7 December 2004" "" "FreeRADIUS Module"
-.SH NAME
-rlm_policy \- FreeRADIUS Module
-.SH DESCRIPTION
-The \fBrlm_policy\fP module implements a simple "policy" language.
-.PP
-The policy language implemented by this module is simple, and specific
-to RADIUS.  It does not implement variables, arrays, loops, goto's, or
-any other feature of a real language.  If those features are needed
-for your system, we suggest using \fBrlm_perl\fP.
-.PP
-What the policy module implements is a simple way to look for
-attributes in the request packet (or other places), and to add
-attributes to the reply packet (or other places) based on those
-decisions.  Where the module shines is that it is significantly more
-flexible than the old-style \fBusers\fP file.
-.PP
-The module has one configuration item:
-.IP filename
-The file where the policy is stored.
-
-.SH POLICY LANGUAGE
-.SS Named policies
-The policy is composed of a series of named policies.  The following
-example defines a policy named "foo".
-.PP
-.DS
-       policy foo {
-.br
-               ...
-.br
-       }
-.DE
-.PP
-Policy names MAY NOT be the same as attributes in the dictionary.
-Defining a policy with the same name as a dictionary attribute will
-cause an error message to be printed, and the policy will not be
-loaded.
-.PP
-When the policy module is listed in a module section like "authorize",
-the module calls a policy named "authorize".  The "post-auth",
-etc. sections behave the same.  These names cannot be changed.
-.PP
-.DS
-       include "policy.txt"
-.DE
-.PP
-The filename must be in a double-quoted string, and is assumed to be
-relative to the location of the current file.  If the filename ends
-with a '/', then it is assumed to be a directory, and all files in
-that directory will be read.
-.PP
-.DS
-       include "dir/"
-.DE
-.PP
-All file in "dir/" will be read and included into the policy
-definition.  Any dot files (".", "..", etc.) will not be included,
-however.
-.PP
-.SS Including multiple files
-The main file referred to from the \fIradiusd.conf\fP may include one
-or more other files, as in the following example.
-.PP
-.SS Referencing a named policy
-The following example references a named policy
-.DS
-       foo()
-.DE
-While the brackets are required, no arguments may be passed.
-.PP
-.SS Conditions
-"if" statements are supported.
-.PP
-       if (expression) {
-.br
-               ...
-.br
-       }
-.DE
-.PP
-and "else"
-.PP
-       if (expression) {
-.br
-               ...
-.br
-       } else {
-.br
-               ...
-.br
-       }
-.DE
-.PP
-also, "else if"
-.PP
-       if (expression) {
-.br
-               ...
-.br
-       } else if (expression) {
-.br
-               ...
-.br
-       }
-.DE
-.PP
-.SS Expressions within "if" statements
-Always have to have brackets around them.  Sorry.
-.PP
-The following kinds of expressions may be used, with their meanings.
-.IP (attribute-reference)
-TRUE if the referenced attribute exists, FALSE otherwise.  See below
-for details on attribute references.
-.IP (!(expression))
-FALSE if the expression returned TRUE, and TRUE if the nested expression
-returned FALSE.
-.IP "(attribute-reference == value)"
-Compares the attribute to the value.  The operators here can be "==",
-"!=", "=~", "!~", "<", "<=", ">", and ">=".
-.IP "(string1 == string2)"
-A special case of the above.  The "string1" is dynamically expanded at
-run time, while "string2" is not.  The operators here can be "==",
-"!=", "=~",and "!~".  Of these, the most useful is "=~', which lets
-you do things like ("%{ldap:query...}" =~ "foo=(.*) ").  The results
-of the regular expression match are put into %{1}, and can be used
-later.  See "doc/variables.txt" for more information.
-.IP "((expression1) || (expression2))"
-Short-circuit "or".  If expression1 is TRUE, expression2 is not
-evaluated.
-.IP "((expression1) && (expression2))"
-Short-circuit "and".  If expression1 is FALSE, expression2 is not
-evaluated.
-.IP Limitations.
-The && and || operators have equal precedence. You can't call a
-function as a expression.
-.PP
-.PP
-.SS Attribute references
-Attribute references are:
-.IP Attribute-Name
-Refers to an attribute of that name in the Access-Request or
-Accounting-Request packet.  May also refer to "server-side"
-attributes, which are not documented anywhere.
-.IP request:Attribute-Name
-An alternate way of referencing an attribute in the request packet.
-.PP
-.IP reply:Attribute-Name
-An attribute in the reply packet
-.PP
-.IP proxy-request:Attribute-Name
-An attribute in the Access-Request or Accounting-Request packet which
-will be proxied to the home server.
-.PP
-.IP proxy-reply:Attribute-Name
-An attribute in the Access-Accept or other packet which was received
-from a home server.
-.PP
-.IP control:Attribute-Name
-An attribute in the per-request configuration and control attributes.
-Also known as "check" attributes (doc/variables.txt).
-.PP
-.PP
-.SS Adding attributes to reply packet (or other location)
-       reply .= {
-.br
-               attribute-name = value
-.br
-               ...
-.br
-               attribute-name = value
-.br
-       }
-.DE
-.PP
-The first name can be "request", "reply", "control", "proxy-request",
-or "proxy-reply".
-.PP
-The operator can be
-.PP
- .= - appends attributes to end of the list
-.PP
- := - replaces existing list with the attributes in the list (bad idea)
-.PP
- = - use operators from "attribute = value" to decide what to do. (see "users")
-.PP
-The block must contain only attributes and values.  Nothing else is permitted.
-
-.SH SECTIONS
-.BR authorize
-.BR post-auth
-.BR pre-proxy
-.BR post-proxy
-.PP
-.SH FILES
-.I /etc/raddb/radiusd.conf
-.PP
-.SH "SEE ALSO"
-.BR radiusd (8),
-.BR users (5),
-.BR radiusd.conf (5)
-.SH AUTHOR
-Alan DeKok <aland@ox.org>
-
index 2c4e76e..243ceff 100644 (file)
@@ -1,4 +1,4 @@
-.TH rlm_realm 5 "14 March 2004" "" "FreeRADIUS Module"
+.TH rlm_realm 5 "19 May 2006" "" "FreeRADIUS Module"
 .SH NAME
 rlm_realm \- FreeRADIUS Module
 .SH DESCRIPTION
@@ -32,6 +32,12 @@ configuration of the Realm as matched in the file, the username may
 be rewritten in a 'stripped' format, or with the Realm portion
 removed.  In either case, a Realm attribute is created and added to
 the packet on a match, which can be used by other modules.
+.PP
+In order to force proxying for a request, set the
+.DS
+Proxy-To-Realm := "realm-name"
+.DE
+in the \fIusers\fP file, or in a database such as SQL.
 .SH CONFIGURATION
 .PP
 .DS
index 29cf77d..c38bc62 100644 (file)
@@ -13,7 +13,7 @@ of "radiusd.conf"), then this module allows you to log SQL queries to
 a file, and then process them at your leisure.
 .PP
 The benefit of this approach is that for a busy server, the overhead
-of performing SQL qeuries may be significant.  Also, if the SQL
+of performing SQL queries may be significant.  Also, if the SQL
 databases are large (as is typical for ones storing months of data),
 the INSERTs and UPDATEs may take a relatively long time.  Rather than
 slowing down the RADIUS server by having it interact with a database,
index ff8ea55..efd6675 100644 (file)
@@ -1,27 +1,43 @@
-.TH rlm_unix 5 "17 February 2005" "" "FreeRADIUS Module"
+.TH rlm_unix 5 "5 February 2004" "" "FreeRADIUS Module"
 .SH NAME
 rlm_unix \- FreeRADIUS Module
 .SH DESCRIPTION
-The \fIrlm_unix\fP module reads crypt(3) passwords from the system
-password file, and allows the server to use them for authentication.
-The module also provides FreeRADIUS an interface into a radwtmp file
-(used by "radlast") when added to the accounting section.
+The \fIrlm_unix\fP module allows authentication against the system
+password, shadow, and group files.  It also provides FreeRADIUS an
+interface into a radwtmp file (used by "radlast") when added to the
+accounting section.
 .PP
-The \fIrlm_unix\fP module does provides the functionality for
-"Auth-Type = System".  The module should be listed in the
-"authenticate" section.  Please see the default \fIradiusd.conf\fP
-shipped with the server for an example of the correct usage of this
-module.
-.PP
-As of FreeRADIUS 1.1.0, the module no longer reads, or caches
-/etc/passwd, /etc/shadow, or /etc/group.  If you wish to cache those
-files, see \fIrlm_passwd\fP.  Most, if not all, configurations should
-not need those files to be cached.
+The \fIrlm_unix\fP module provides the functionality for "Auth-Type =
+System", rather than "Auth-Type = Unix".  The "System" name is used
+for historical reasons.
 .PP
 The main configuration items to be aware of are:
+.IP cache
+This is a 'yes' or 'no' option.  If set to yes, FreeRADIUS will read
+the system files into memory, rather than perform a system call to
+lookup the information.  On *BSD systems, you should set this value to
+no.  On other systems, if you have a very large passwd and shadow
+files, you can try setting this to yes, which may increase the servers
+performance.  The default is no.
+.IP cache_reload
+This is the number of seconds to wait between refreshing the cached 
+files from the system.  It has no effect unless you enable caching.
+.IP passwd
+The path to the system passwd file.  Usually /etc/passwd.  If
+commented out, or not set, the server will retrieve the information
+via systemcalls.
+.IP shadow
+The path to the system shadow file.  Usually /etc/shadow.  This is not
+set by default.
+.IP group
+The path to the system group file.  Usually /etc/group.  This is not
+set by default.
 .IP radwtmp
 The path to the system wtmp file to be used for keeping the database
 of online users as read by the 'radlast' program.
+.IP usegroup
+This is a 'yes' or 'no' option.  If set to 'yes' this allows the Group
+attribute to be used as a check item.  Default is 'no'.
 .SH CONFIGURATION
 .PP
 .DS
@@ -30,6 +46,18 @@ modules {
 .br
   unix {
 .br
+    cache = no
+.br
+    cache_reload = 600
+.br
+    #passwd = /etc/passwd
+.br
+    #shadow = /etc/shadow
+.br
+    #group = /etc/group
+.br
+    usegroup = no
+.br
     radwtmp = ${logdir}/radwtmp
 .br
   }
@@ -49,7 +77,6 @@ modules {
 .SH "SEE ALSO"
 .BR radiusd (8),
 .BR radiusd.conf (5),
-.BR rlm_passwd (5),
 .BR radlast (1)
 .SH AUTHORS
 Chris Parker, cparker@segv.org
index 2bdde47..373b3ea 100644 (file)
@@ -27,6 +27,12 @@ radiusd - Authentication, Authorization and Accounting server
 .RB [ \-y ]
 .RB [ \-z ]
 .SH DESCRIPTION
+This is the FreeRADIUS implementation of the well known
+.B radius
+server program.  Even though this program is largely compatible with
+\fILivingston's\fP radius version 2.0, it is \fBnot\fP based on any
+part of that code.
+.PP
 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
@@ -122,11 +128,11 @@ 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.
+Defines which IP addres to bind to for sending and receiving packets-
+useful for multi-homed hosts.
 
-If this command-line option is given, then the "bind_address" and all
-"listen{}" entries in \fIradiusd.conf\fP are ignored.
+This command line option is deprecated.  See the \fIbind_address\fP
+configuration item in the \fIradiusd.conf\fP file.
 
 .IP \-b
 If the \fBradius\fP server binary was compiled with \fIdbm\fP support,
@@ -154,12 +160,12 @@ 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
-the specified port for authentication requests and on the specified
-port +1 for accounting requests.
+(radius and radacct). With this option radiusd listens on the specified
+port for authentication requests and on the specified port +1 for
+accounting requests.
 
-If this command-line option is given, then the "port" directive in
-\fIradiusd.conf\fP is ignored.
+This command line option is deprecated.  See the \fIport\fP
+configuration item in the \fIradiusd.conf\fP file.
 
 .IP \-s
 Run in "single server" mode.  The server normally runs with multiple
@@ -172,13 +178,14 @@ single server mode, the server will also not "daemonize"
 .IP \-v
 Print server version information and exit.
 
-.IP \-X
-Debugging mode.  Equivalent to -sfxx.
-
 .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.
+Debug mode. In this mode the server will print details of every request
+on it's \fBstderr\fP output. Most useful in combination with \fB-s\fP.
+You can specify this option 2 times (-x -x or -xx) to get a bit more
+debugging output.
+
+.IP \-X
+Extended debug mode.  Equivalent to -sfxx, but simpler to explain.
 
 .IP \-y
 Write details about every authentication request in the
index 1f423ec..51dcaed 100644 (file)
@@ -1,16 +1,77 @@
-.TH RADRELAY 8 "19 July 2005" "" "FreeRADIUS Daemon"
+.TH RADRELAY 1 "09 June 2002" "" "FreeRADIUS Daemon"
 .SH NAME
-radrelay -- Deprecated command.
+radrelay -- replicate accounting data to another RADIUS server
+.SH SYNOPSIS
+.B radrelay
+.RB [ \-a
+.IR accounting_dir ]
+.RB [ \-d
+.IR radius_dir ]
+.RB [ \-f ]
+.RB [ \-i
+.IR source_ip ]
+.RB [ \-n
+.IR shortname ]
+.RB [ \-r
+.IR remote-server[:port] ]
+.RB [ \-s
+.IR secret ]
+.RB [ \-S
+.IR secret_file ]
+.RB [ \-x ]
+\fIdetailfile\fP
 .SH DESCRIPTION
-The functions of \fIradrelay\fP have been added to \fIradiusd\fP.  One
-benefit is that one instance of \fIradiusd\fP can read multiple detail
-files, among others.
+\fBRadrelay\fP reads a file in the \fIdetail\fP file format,
+reconstructs radius packets from it and sends them to a remote
+radius server. When end-of-file is reached, the file is truncated.
+\fBRadrelay\fP then waits for additional data to be written to
+the file, and starts over again.
 .PP
-The \fIrlm_sql_log\fP module does something similar, but for SQL
-queries.  See it's man page for details.
+
+.SH OPTIONS
+
+.IP "\-a \fIaccounting_directory\fP"
+The base directory to use to read the detail file from.
+
+.IP "\-d \fIradius_directory\fP"
+The base radius (raddb) directory, where the config files live.
+
+.IP \-f
+Do \fInot\fP fork and run in the background as a daemon.
+
+.IP "\-i \fIsource_ip\fP"
+The source IP address to use for sending radius packets.
+
+.IP "\-n \fIshortname\fP"
+The radius configuration files (most probably clients.conf), will be
+searched for a client section with 'shortname' set to the used argument.
+Both the server secret and the remote-server address are obtained in
+this way. Do not use the -r, -s or -S parameters in combination with -n.
+
+.IP "\-r \fIremote-server\fP"
+The hostname or IP address of the remote server. Optionally a UDP port
+can be specified. If no UDP port is specified, it is looked up in
+\fI/etc/services\fP. The service name looked for is \fBradacct\fP for
+accounting packets. If a service is not found in \fI/etc/services\fP,
+1813 is used. The -r parameter can't be used in combination with -n.
+
+.IP "\-s \fIsecret\fP"
+Remote server secret.
+
+.IP "\-S \fIsecret_file\fP"
+Read remote server secret from file, the file should contain
+nothing other then the plain-text secret.
+
+.IP \-x
+Enable debug mode, -x will activate radrelay internal debugging, -xx will
+also activate librad debugging.
+
+.IP "detailfile"
+The detail file to use, this will be appended to the base accounting
+directory.
+
 .SH SEE ALSO
-.BR radiusd(8),
-.BR radrelay.conf(5),
-.BR rlm_sql_log(5)
+radiusd(8),
+doc/radrelay.
 .SH AUTHOR
-The FreeRADIUS Server Project
+Miquel van Smoorenburg, miquels@cistron.nl.
index 1ba3888..e2cd82f 100644 (file)
@@ -7,7 +7,7 @@ radwatch - wrapper for radiusd
 .SH DESCRIPTION
 This is a wrapper for \fIradiusd\fP. It starts the radius server, then
 waits for it to terminate, which should never happen. If it does
-happen, \fBradwatch\fP sends a notification email to \fIroot\fP about
+happen, \fBradwatch\fP sends mail to \fIroot\fP informing her of
 the event, waits 10 seconds, then restarts the server.
 .PP
 This script \fBSHOULD NOT BE USED\fP!  It's only here for historical
diff --git a/mibs/FREERADIUS-SMI.txt b/mibs/FREERADIUS-SMI.txt
deleted file mode 100644 (file)
index d947478..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-FREERADIUS-SMI DEFINITIONS ::= BEGIN
-
-IMPORTS
-       MODULE-IDENTITY,
-       OBJECT-IDENTITY,
-       enterprises
-               FROM SNMPv2-SMI;
-
-freeRadius MODULE-IDENTITY
-       LAST-UPDATED "9809010000Z"
-       ORGANIZATION "FREERADIUS project"
-       CONTACT-INFO
-               "FreeRADIUS Network Object Model Environment project
-               
-               see http://www.freeradius.org for contact persons of a particular
-               area or subproject of FREERADIUS.
-
-               Administrative contact for MIB module:
-
-               Alan DeKok
-
-               email: aland@freeradius.org"
-       DESCRIPTION
-               "The Structure of FREERADIUS."
-       ::= { enterprises 11344 }       -- assigned by IANA
-
-freeRadiusProducts OBJECT-IDENTITY
-       STATUS  current
-       DESCRIPTION
-               "freeRadiusProducts is the root OBJECT IDENTIFIER from
-               which sysObjectID values are assigned."
-       ::= { freeRadius 1 }
-
-freeRadiusMgmt OBJECT-IDENTITY
-       STATUS  current
-       DESCRIPTION
-               "freeRadiusMgmt defines the subtree for production FREERADIUS related
-               MIB registrations."
-       ::= { freeRadius 2 }
-
-freeRadiusTest OBJECT-IDENTITY
-       STATUS  current
-       DESCRIPTION
-               "freeRadiusTest defines the subtree for testing FREERADIUS related
-               MIB registrations."
-       ::= { freeRadius 3 }
-
--- more to come if necessary.
-
-END
similarity index 55%
rename from mibs/FREERADIUS-PRODUCT-RADIUSD-MIB.txt
rename to mibs/GNOME-PRODUCT-RADIUSD-MIB
index 4d1e67d..fa55691 100644 (file)
@@ -1,37 +1,40 @@
-FREERADIUS-PRODUCT-RADIUSD-MIB DEFINITIONS ::= BEGIN
+GNOME-PRODUCT-RADIUSD-MIB DEFINITIONS ::= BEGIN
 
 IMPORTS
        MODULE-IDENTITY,
        OBJECT-IDENTITY
                FROM SNMPv2-SMI
        gnomeProducts
-               FROM FREERADIUS-SMI;
+               FROM GNOME-SMI;
 
 freeradius MODULE-IDENTITY
-       LAST-UPDATED "200703090000Z"
-       ORGANIZATION "FreeRADIUS Project"
+       LAST-UPDATED "200009260000Z"
+       ORGANIZATION "GNOME project"
        CONTACT-INFO
-               "FreeRADIUS Network Object Model Environment project
+               "GNU Network Object Model Environment project
                
-               see http://www.freeradius.org for contact persons of a particular
-               area or subproject of FREERADIUS.
+               see http://www.gnome.org for contact persons of a particular
+               area or subproject of GNOME.
 
                Administrative contact for MIB module:
 
-               Alan DeKok
+               Jochen Friedrich
+               Wingertstr. 70/1
+               68809 Neulussheim
+               Germany 
 
-               email: aland@freeradius.org"
+               email: snmp@gnome.org"
        DESCRIPTION
                "The product registrations for the FreeRADIUS SNMP subagent.
                These registrations are guaranteed to be unique and are used
                for SMUX registration by default (if not overridden manually)."
-       ::= { freeradiusProducts 1 }
+       ::= { gnomeProducts 3 }
 
 radiusd OBJECT-IDENTITY
        STATUS  current
        DESCRIPTION
                "radiusd is the RADIUS protocol deamon of the FreeRADIUS
                project."
-       ::= { radiusd 1 }
+       ::= { freeradius 1 }
 
 END
index 52af00d..664d614 100644 (file)
@@ -9,12 +9,11 @@ include ../Make.inc
 #
 #  The list of files to install.
 #
-FILES = acct_users attrs attrs.access_reject attrs.accounting_response \
-       attrs.pre-proxy clients.conf dictionary \
-       eap.conf experimental.conf hints huntgroups ldap.attrmap        \
-        naspasswd otp.conf     \
-       preproxy_users proxy.conf radiusd.conf radrelay.conf            \
-       realms snmp.conf sql.conf sqlippool.conf users
+FILES  = acct_users attrs clients clients.conf dictionary eap.conf \
+         experimental.conf hints huntgroups ldap.attrmap \
+         mssql.conf naslist naspasswd oraclesql.conf postgresql.conf \
+         preproxy_users proxy.conf radiusd.conf realms snmp.conf \
+         sql.conf sqlippool.conf users otp.conf
 
 all:
 
@@ -41,17 +40,13 @@ install:
                echo "** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING **";\
                echo "** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING ** WARNING **";\
        fi
-       chmod 640 $(R)$(raddbdir)/naspasswd $(R)$(raddbdir)/clients.conf
+       chmod 640 $(R)$(raddbdir)/naspasswd $(R)$(raddbdir)/clients $(R)$(raddbdir)/clients.conf
        if [ ! -d $(R)$(raddbdir)/certs ]; then \
-               $(INSTALL) -d -m 750    $(R)$(raddbdir)/certs; \
-               $(INSTALL) -m 750 certs/bootstrap $(R)$(raddbdir)/certs; \
-               for i in Makefile README xpextensions ca.cnf server.cnf client.cnf; do \
-                       $(INSTALL) -m 640 certs/$$i $(R)$(raddbdir)/certs; \
-               done; \
-       fi
-       if [ ! -d $(R)$(raddbdir)/sql ]; then \
-               mkdir $(R)$(raddbdir)/sql; \
-               cp sql/*conf $(R)$(raddbdir)/sql 2>/dev/null || true; \
+               mkdir $(R)$(raddbdir)/certs; \
+               mkdir $(R)$(raddbdir)/certs/demoCA; \
+               cp certs/demoCA/* $(R)$(raddbdir)/certs/demoCA || true; \
+               cp certs/* $(R)$(raddbdir)/certs 2>/dev/null || true; \
        fi
 
 clean:
+
index fafac84..8e15d01 100644 (file)
@@ -4,20 +4,13 @@
 #      This is like the 'users' file, but it is processed only for
 #      accounting packets.
 #
-
-#  Select between different accounting methods based for example on the
-#  Realm, the Huntgroup-Name or any combinaison of the attribute/value
-#  pairs contained in an accounting packet.
+#DEFAULT Acct-Status-Type == Start
+#      Exec-Program = "/path/to/exec/acct/start"
 #
-#DEFAULT Realm == "foo.net", Acct-Type := sql_log.foo
+#DEFAULT Acct-Status-Type == Stop
+#      Exec-Program = "/path/to/exec/acct/stop"
 #
-#DEFAULT Huntgroup-Name == "wifi", Acct-Type := sql_log.wifi
+#  For information on how the attributes from the request are passed
+#  to the program, see 'doc/variables.txt'
 #
-#DEFAULT Client-IP-Address == 10.0.0.1, Acct-Type := sql_log.other
 #
-#DEFAULT Acct-Status-Type == Start, Acct-Type := sql_log.start
-
-#  Replace the User-Name with the Stripped-User-Name, if it exists.
-#
-#DEFAULT
-#      User-Name := "%{Stripped-User-Name:-%{User-Name}}"
index 5737b7f..59b5a63 100644 (file)
@@ -117,9 +117,6 @@ DEFAULT
        Reply-Message =* ANY,
        Proxy-State =* ANY,
        EAP-Message =* ANY,
-       MS-MPPE-Recv-Key =* ANY,
-       MS-MPPE-Send-Key =* ANY,
-       MS-CHAP-MPPE-Keys =* ANY,
        State =* ANY,
        Session-Timeout <= 28800,
        Idle-Timeout <= 600,
diff --git a/raddb/attrs.access_reject b/raddb/attrs.access_reject
deleted file mode 100644 (file)
index 8ecfe2d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-#      Configuration file for the rlm_attr_filter module.
-#      Please see rlm_attr_filter(5) manpage for more information.
-#
-#      $Id$
-#
-#      This configuration file is used to remove almost all of the attributes
-#      From an Access-Reject message.  The RFC's say that an Access-Reject
-#      packet can contain only a few attributes.  We enforce that here.
-#
-DEFAULT
-       EAP-Message =* ANY,
-       State =* ANY,
-       Message-Authenticator =* ANY,
-       Reply-Message =* ANY,
-       Proxy-State =* ANY
diff --git a/raddb/attrs.accounting_response b/raddb/attrs.accounting_response
deleted file mode 100644 (file)
index 3746ce4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-#      Configuration file for the rlm_attr_filter module.
-#      Please see rlm_attr_filter(5) manpage for more information.
-#
-#      $Id$
-#
-#      This configuration file is used to remove almost all of the attributes
-#      From an Accounting-Response message.  The RFC's say that an
-#      Accounting-Response packet can contain only a few attributes.
-#      We enforce that here.
-#
-DEFAULT
-       Vendor-Specific =* ANY,
-       Message-Authenticator =* ANY,
-       Proxy-State =* ANY
diff --git a/raddb/attrs.pre-proxy b/raddb/attrs.pre-proxy
deleted file mode 100644 (file)
index fdfb650..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-#      Configuration file for the rlm_attr_filter module.
-#      Please see rlm_attr_filter(5) manpage for more information.
-#
-#      $Id$
-#
-#      This file contains security and configuration information
-#      for each realm. It can be used be an rlm_attr_filter module
-#      instance to filter attributes before sending packets to the
-#      home server of a realm.
-#
-#      When a packet is sent to a home server, these attributes
-#      and values are tested. Only the first match is used unless
-#      the "Fall-Through" variable is set to "Yes". In that case
-#      the rules defined in the DEFAULT case are processed as well.
-#
-#      A special realm named "DEFAULT" matches on all realm names.
-#      You can have only one DEFAULT entry. All entries are processed
-#      in the order they appear in this file. The first entry that
-#      matches the login-request will stop processing unless you use
-#      the Fall-Through variable.
-#
-#      The first line indicates the realm to which the rules apply.
-#      Indented (with the tab character) lines following the first
-#      line indicate the filter rules.
-#
-
-# This is a complete entry for 'nochap' realm. It allows to send very
-# basic attributes to the home server. Note that there is no Fall-Through
-# entry so that no DEFAULT entry will be used. Only the listed attributes
-# will be sent in the packet, all other attributes will be filtered out.
-#
-#nochap
-#      User-Name =* ANY,
-#      User-Password =* ANY,
-#      NAS-Ip-Address =* ANY,
-#      NAS-Identifier =* ANY
-
-# The entry for the 'brokenas' realm removes the attribute NAS-Port-Type
-# if its value is different from 'Ethernet'. Then the default rules are
-# applied.
-#
-#brokenas
-#      NAS-Port-Type == Ethernet
-#      Fall-Through = Yes
-
-# The rest of this file contains the DEFAULT entry.
-# DEFAULT matches with all realm names.
-
-DEFAULT
-       User-Name =* ANY,
-       User-Password =* ANY,
-       CHAP-Password =* ANY,
-       CHAP-Challenge =* ANY,
-       State =* ANY,
-       NAS-Ip-Address =* ANY,
-       NAS-Identifier =* ANY,
-       Proxy-State =* ANY
diff --git a/raddb/certs/Makefile b/raddb/certs/Makefile
deleted file mode 100644 (file)
index a9fa070..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-######################################################################
-#
-#      Make file to be installed in /etc/raddb/certs to enable
-#      the easy creation of certificates.
-#
-#      See the README file in this directory for more information.
-#      
-#      $Id$
-#
-######################################################################
-
-DH_KEY_SIZE    = 1024
-
-#
-#  Set the passwords
-#
-PASSWORD_SERVER        = $(shell grep output_password server.cnf | sed 's/.*=//;s/^ *//')
-PASSWORD_CA    = $(shell grep output_password ca.cnf | sed 's/.*=//;s/^ *//')
-PASSWORD_CLIENT        = $(shell grep output_password client.cnf | sed 's/.*=//;s/^ *//')
-
-USER_NAME      = $(shell grep emailAddress client.cnf | grep '@' | sed 's/.*=//;s/^ *//')
-
-######################################################################
-#
-#  Make the necessary files, but not client certificates.
-#
-######################################################################
-.PHONY: all
-all: dh random server ca
-
-.PHONY: client
-client: client.pem
-
-.PHONY: ca
-ca: ca.pem
-
-.PHONY: server
-server: server.pem
-
-######################################################################
-#
-#  Diffie-Hellman parameters
-#
-######################################################################
-dh:
-       openssl dhparam -out dh $(DH_KEY_SIZE)
-
-######################################################################
-#
-#  Create a new self-signed CA certificate
-#
-######################################################################
-ca.key ca.pem:
-       openssl req -new -x509 -keyout ca.key -out ca.pem -config ./ca.cnf 
-
-######################################################################
-#
-#  Create a new server certificate, signed by the above CA.
-#
-######################################################################
-server.csr server.key: 
-       openssl req -new  -out server.csr -keyout server.key -config ./server.cnf
-
-server.crt: server.csr ca.key ca.pem index.txt serial
-       openssl ca -batch -keyfile ca.key -cert ca.pem -in server.csr  -key $(PASSWORD_CA) -out server.crt -extensions xpserver_ext -extfile xpextensions -config ./server.cnf
-
-server.p12: server.crt
-       openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12  -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_SERVER)
-
-server.pem: server.p12
-       openssl pkcs12 -in server.p12 -out server.pem -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_SERVER)
-
-######################################################################
-#
-#  Create a new client certificate, signed by the the above server
-#  certificate.
-#
-######################################################################
-client.csr client.key: client.cnf
-       openssl req -new  -out client.csr -keyout client.key -config ./client.cnf
-
-client.crt: client.csr server.crt server.key index.txt serial
-       openssl ca -batch -keyfile server.key -cert server.crt -in client.csr  -key $(PASSWORD_SERVER) -out client.crt -extensions xpclient_ext -extfile xpextensions -config ./client.cnf
-
-client.p12: client.crt
-       openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12  -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
-
-client.pem: client.p12
-       openssl pkcs12 -in client.p12 -out client.pem -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_CLIENT)
-       cp client.pem $(USER_NAME).pem
-
-######################################################################
-#
-#  Miscellaneous rules.
-#
-######################################################################
-index.txt:
-       @touch index.txt
-
-serial:
-       @echo '01' > serial
-
-random:
-       @if [ -e /dev/urandom ] ; then \
-               dd if=/dev/urandom of=./random count=10 >/dev/null 2>&1; \
-       else \
-               date > ./random; \
-       fi
-
-print:
-       openssl x509 -text -in server.crt
-
-clean:
-       @rm -f *~ *old client.csr client.key client.crt client.p12 client.pem
-
-#
-#  Run distclean ONLY if there's a CVS directory, AND it points to
-#  cvs.freeradius.org.  Otherwise, it would be easy for administrators
-#  to type "make distclean", and destroy their CA and server certificates.
-#
-distclean:
-       @if [ -d CVS -a `grep -i 'cvs\.freeradius\.org' CVS/Root` ] ; then \
-               rm -f *~ dh *.csr *.crt *.p12 *.der *.pem *.key index.txt* \
-                       serial* random; \
-       fi
index 2173e42..8be01b2 100644 (file)
-  This directory contains scripts to create the server certificates.
-To make a set of default (i.e. test) certificates, simply type:
+This directory contains a number of sample certificates for
+use by the rlm_eap_tls module.  These certificates should be used
+ONLY for testing purposes.
 
-$ ./bootstrap
+If you're not using EAP-TLS, EAP-TTLS, or EAP-PEAP, then you may delete
+this entire directory.
 
-  The "openssl" command will be run against the sample configuration
-files included here, and will make certificates for a certificate
-authority (i.e. root CA), and a server certificate.
+If you are using one or more of those authentication protocols, then
+the certificates included here should be replaced with ones signed
+by a real Certificate Authority.
 
-  The Microsoft "XP Extensions" will be automatically included in the
-server certificate.  Without those extensions Windows clients will
-refuse to authenticate to FreeRADIUS.
-
-  If FreeRADIUS was configured to use OpenSSL, then simply starting
-the server in root in debugging mode will also create test
-certificates, i.e.:
-
-$ radiusd -X
-
-  That will cause the EAP-TLS module to run the "bootstrap" script in
-this directory.  The script will be executed only once, the first time
-the server has been installed on a particular machine.
-
-  If you already have CA and server certificates, rename (or delete)
-this directory, and create a new "certs" directory containing your
-certificates.  Note that the "make install" command will NOT
-over-write your existing "raddb/certs" directory, which means that the
-"bootstrap" command will not be run.
-
-
-               NEW INSTALLATIONS OF FREERADIUS
-
-
-  We suggest that new installations use the test certificates for
-initial tests, and then create real certificates to use for normal
-user authentication.  See the instructions below for how to create the
-various certificates.  The old test certificates can be deleted by
-running the following command:
-
-$ rm -f *.pem *.der *.csr *.crt *.key *.p12 serial* index.txt*
-
-  Then, follow the instructions below for creating real certificates.
-
-  Once the final certificates have been created, you can delete the
-"bootstrap" command from this directory, and delete the
-"make_cert_command" configuration from the "tls" sub-section of
-eap.conf.
-
-  If you do not want to enable EAP-TLS, PEAP, or EAP-TTLS, then delete
-the relevant sub-sections from the "eap.conf" file.
-
-
-               MAKING A ROOT CERTIFICATE
-
-
-$ vi ca.cnf
-
-  Edit the "input_password" and "output_password" fields to be the
-  password for the CA certificate.
-
-  Edit the [certificate_authority] section to have the correct values
-  for your country, state, etc.
-
-$ make ca.pem
-
-  This step creates the CA certificate.
-
-
-
-               MAKING A SERVER CERTIFICATE
-
-
-$ vi server.cnf
-
-  Edit the "input_password" and "output_password" fields to be the
-  password for the server certificate.
-
-  Edit the [server] section to have the correct values for your
-  country, state, etc.  Be sure that the commonName field here is
-  different from the commonName for the CA certificate.
-
-$ make server.pem
-
-  This step creates the server certificate.
-
-  If you have an existing certificate authority, and wish to create a
-  certificate signing request for the server certificate, edit
-  server.cnf as above, and type the following command.
-
-$ make server.csr
-
-  You will have to ensure that the certificate contains the XP
-  extensions needed by Microsoft clients.
-
-
-               MAKING A CLIENT CERTIFICATE
-
-
-  Client certificates are used by EAP-TLS, and optionally by EAP-TTLS
-and PEAP.  The following steps outline how to create a client
-certificate that is signed by the server certificate created above.
-You will have to have the password for the server certificate in the
-"input_password" and "output_password" fields of the server.cnf file.
-
-
-$ vi client.cnf
-
-  Edit the "input_password" and "output_password" fields to be the
-  password for the client certificate.  You will have to give these
-  passwords to the end user who will be using the certificates.
-
-  Edit the [client] section to have the correct values for your
-  country, state, etc.  Be sure that the commonName field here is
-  the User-Name that will be used for logins!
-
-$ make client.pem
-
-  The users certificate will be in "commonName.pem",
-  i.e. "user@example.com.pem".
-
-  To create another client certificate, just repeat the steps for
-  making a client certificate, being sure to enter a different login
-  name for "commonName", and a different password.
+2004-01-25
diff --git a/raddb/certs/bootstrap b/raddb/certs/bootstrap
deleted file mode 100755 (executable)
index 97951a1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-#
-#  This is a wrapper script to create default certificates when the
-#  server first starts in debugging mode.  Once the certificates have been
-#  created, this file should be deleted.
-#
-#  $Id$
-#
-cd `dirname $0`
-make ca server dh random
diff --git a/raddb/certs/ca.cnf b/raddb/certs/ca.cnf
deleted file mode 100644 (file)
index 4f66e47..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-[ ca ]
-default_ca             = CA_default
-
-[ CA_default ]
-dir                    = ./
-certs                  = $dir
-crl_dir                        = $dir/crl
-database               = $dir/index.txt
-new_certs_dir          = $dir
-certificate            = $dir/server.pem
-serial                 = $dir/serial
-crl                    = $dir/crl.pem
-private_key            = $dir/server.key
-RANDFILE               = $dir/.rand
-name_opt               = ca_default
-cert_opt               = ca_default
-default_days           = 365
-default_crl_days       = 30
-default_md             = md5
-preserve               = no
-policy                 = policy_match
-
-[ policy_match ]
-countryName            = match
-stateOrProvinceName    = match
-organizationName       = match
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-[ policy_anything ]
-countryName            = optional
-stateOrProvinceName    = optional
-localityName           = optional
-organizationName       = optional
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-[ req ]
-prompt                 = no
-distinguished_name     = certificate_authority
-default_bits           = 2048
-input_password         = whatever
-output_password                = whatever
-
-[certificate_authority]
-countryName            = FR
-stateOrProvinceName    = Radius
-localityName           = Somewhere
-organizationName       = Example Inc.
-emailAddress           = admin@example.com
-commonName             = "Example Certificate Authority"
diff --git a/raddb/certs/cert-clt.der b/raddb/certs/cert-clt.der
new file mode 100644 (file)
index 0000000..f1f94ce
Binary files /dev/null and b/raddb/certs/cert-clt.der differ
diff --git a/raddb/certs/cert-clt.p12 b/raddb/certs/cert-clt.p12
new file mode 100644 (file)
index 0000000..980461b
Binary files /dev/null and b/raddb/certs/cert-clt.p12 differ
diff --git a/raddb/certs/cert-clt.pem b/raddb/certs/cert-clt.pem
new file mode 100644 (file)
index 0000000..188da28
--- /dev/null
@@ -0,0 +1,43 @@
+Bag Attributes
+    localKeyID: C6 0F 30 C2 37 91 4A 39 EF 2F 5C 76 FE C1 4C E1 26 A9 89 03 
+subject=/C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Server certificate/emailAddress=server@example.com
+issuer=/C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Client certificate/emailAddress=client@example.com
+-----BEGIN CERTIFICATE-----
+MIICzTCCAjagAwIBAgIBATANBgkqhkiG9w0BAQQFADCBnzELMAkGA1UEBhMCQ0Ex
+ETAPBgNVBAgTCFByb3ZpbmNlMRIwEAYDVQQHEwlTb21lIENpdHkxFTATBgNVBAoT
+DE9yZ2FuaXphdGlvbjESMBAGA1UECxMJbG9jYWxob3N0MRswGQYDVQQDExJDbGll
+bnQgY2VydGlmaWNhdGUxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNv
+bTAeFw0wNDAxMjUxMzI2MDhaFw0wNTAxMjQxMzI2MDhaMIGfMQswCQYDVQQGEwJD
+QTERMA8GA1UECBMIUHJvdmluY2UxEjAQBgNVBAcTCVNvbWUgQ2l0eTEVMBMGA1UE
+ChMMT3JnYW5pemF0aW9uMRIwEAYDVQQLEwlsb2NhbGhvc3QxGzAZBgNVBAMTElNl
+cnZlciBjZXJ0aWZpY2F0ZTEhMB8GCSqGSIb3DQEJARYSc2VydmVyQGV4YW1wbGUu
+Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4JSLIilEeRvoEvQOIQDMG
+cNSewlXKswXlF9qeBp7BwTUw+HYqroD90Z1X8PvWjRoiHwaISV0slKKSdiNHD6oT
+tvAG4RlFk8vIX2rQdFnf9LvbyoJcNIYl7ju8JpoEvj5KtK9ftGD+2EQDAyvchABN
+k57GTKclAa5SbPR3rOeVQwIDAQABoxcwFTATBgNVHSUEDDAKBggrBgEFBQcDAjAN
+BgkqhkiG9w0BAQQFAAOBgQADUPAw2sC/aR29EhJ0aDSqHDWB29WF7EgWdki9UCHx
+I1uTcZy3lEZXB3TqH0x8RE5UtiGsmfZrNWsokHQaXdPHmtVD8fScqn75u3S/Sjja
+hr8lGndaf+Bf+x2wNMe3EAKjnC2wENIMlE2U1uYPTddp/o0H1vwFkn2QdjIzB8ro
+lg==
+-----END CERTIFICATE-----
+Bag Attributes
+    localKeyID: C6 0F 30 C2 37 91 4A 39 EF 2F 5C 76 FE C1 4C E1 26 A9 89 03 
+Key Attributes: <No Attributes>
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,06AE1A3D3FF666CF
+
+jMeuAio5K0EnOejip95F9mwtkCDhUBxfkKmmOM2/OYo57WxA7GMnvjgCL2bCsBYT
+5kDapZommkKuArcx2Lcl6u7qfzWxxirxRAJNvSxZKPMv2L8yYo2mi3xDyeFUI5nf
+PbnWFBU14cqprdmI3dl2djba9BaU40RaD3lJzTZmi0PtnNtogTi0W3xjFxuIWQlP
+2Q7yq14CcNby0Za4LQeZcCSvrD+ourIenX0RpwXe7R0cdGu+1ay/u0U/wCRawhR1
+Sqw1C7RejqI2MhiHnSKy26Yk04rutkfGcwCbMFmDcW/qy6Ycqc0Rb4dKCY0mA2ch
+UFuTtHf4LPW/9AE/lLNeM01Uvaw7ywJDXnPh8CejrPJ3N6hO96a/P+/54SsmL87Q
+OSZHYLQ5heOEMly2ofSW/+QKJ+yJhZqzDqRY2NaflVVoxObewWnocs3Ev6Bf97ss
+GY6qLyYWIySjYtLdRcLm7rIl8/VJAVozXuqObZg6EMDwdfVNyNeexucUoPngKLiL
+efAREgz+4vqixQFLhiGkt6loziifdOoieukrGTd2ar3XDkJfeY/hU5ss5okgEaeR
+p2vzda6GAaZ5VyrF5yaDecT0NORTa6EThXVYvtPhYIFr5c5wF3lKYSQiZcAK1Z0P
+D29KHHMWa1c0LWcSczxr4S+cF2pQd7vcjFzcnB4j08D3FhQWL1DzCIygSHh+9gPl
+gWO5RihBPsD+sOaUF5yr/DOeHzExmos6SJoolp1wjb6qNYHwEr27KBZoqGN522NL
+SK8utXzCzB9dNM/r9XCGY2zFJh9XCA7gOYqVYOjoShFBHOUVOCOsAQ==
+-----END RSA PRIVATE KEY-----
diff --git a/raddb/certs/cert-srv.der b/raddb/certs/cert-srv.der
new file mode 100644 (file)
index 0000000..7c5e14f
Binary files /dev/null and b/raddb/certs/cert-srv.der differ
diff --git a/raddb/certs/cert-srv.p12 b/raddb/certs/cert-srv.p12
new file mode 100644 (file)
index 0000000..20bab0c
Binary files /dev/null and b/raddb/certs/cert-srv.p12 differ
diff --git a/raddb/certs/cert-srv.pem b/raddb/certs/cert-srv.pem
new file mode 100644 (file)
index 0000000..03b994f
--- /dev/null
@@ -0,0 +1,42 @@
+Bag Attributes
+    localKeyID: 0C BA ED 0A 7B E9 67 CD E7 0A 08 39 DB 9D 99 34 0A C6 2B A4 
+subject=/C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Root certificate/emailAddress=root@example.com
+issuer=/C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Client certificate/emailAddress=client@example.com
+-----BEGIN CERTIFICATE-----
+MIICyTCCAjKgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBnzELMAkGA1UEBhMCQ0Ex
+ETAPBgNVBAgTCFByb3ZpbmNlMRIwEAYDVQQHEwlTb21lIENpdHkxFTATBgNVBAoT
+DE9yZ2FuaXphdGlvbjESMBAGA1UECxMJbG9jYWxob3N0MRswGQYDVQQDExJDbGll
+bnQgY2VydGlmaWNhdGUxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNv
+bTAeFw0wNDAxMjUxMzI2MTBaFw0wNTAxMjQxMzI2MTBaMIGbMQswCQYDVQQGEwJD
+QTERMA8GA1UECBMIUHJvdmluY2UxEjAQBgNVBAcTCVNvbWUgQ2l0eTEVMBMGA1UE
+ChMMT3JnYW5pemF0aW9uMRIwEAYDVQQLEwlsb2NhbGhvc3QxGTAXBgNVBAMTEFJv
+b3QgY2VydGlmaWNhdGUxHzAdBgkqhkiG9w0BCQEWEHJvb3RAZXhhbXBsZS5jb20w
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANrFJUIr/tsIJimiy6RLNEnJDQq0
+YvtyyENKeCCYhj1+t9fnACjCt61VWlHMdWz0+h1wkWFatFDVKJVTrmYWr/AUpVCF
+1rj7Su6YY45CYXXN02xmXGPNoXfTSSDrMFhe3IdzmZwpgPga1GOLu+ocgtBUAj23
+7ySj7Bw/YkGpA9fzAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG
+SIb3DQEBBAUAA4GBAHotkhsc8TvymCqReOye3m2I7cF4oui9QKCgb7bwdplXiEzX
+CEU3CDSW/RhBZSk/WDyOgkDraOBCyUsVdS5MB+gNCXea+j3VXCT6VKwpLXcgXRwk
+d+0w1Z9Xyvm9If8qjRbMCRHFDk8pV2P8tg76PD0tDkOFD25vvihJAvboNQNl
+-----END CERTIFICATE-----
+Bag Attributes
+    localKeyID: 0C BA ED 0A 7B E9 67 CD E7 0A 08 39 DB 9D 99 34 0A C6 2B A4 
+Key Attributes: <No Attributes>
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,45A3F7FFC07A6C8D
+
+h2Hg0jIRPlwoC0CyYxdPB/+paKyJsW5RGYH4ZG0cooZUdzcc36E68MxN6rXxw8Qr
+M14ZKr3VBgbpQD3k6SdvIYxeBK1O7V4A1NCaPl9qS4tQpHuCkwjelb+PouOC4C+5
+dspfsKri9jMrX1pmzf1vWq7DSRgSisBzcdXkp2AkkLmpAtwhD+JD4gPNVoHUP0r3
+TeM6/A8twoyi73off1pUKVTE1rFzuAl0mG5+VnLy6uHUemkpVr3nZMuVQoSp7zer
+gaZvYJ5/yfjJdFMiyW0d9ZotHJ9/yfQzUwS/1M/ufrjr2cfQTn5VeOOvW+6hKqmV
+sO0sXLPINnLleTr3bvJX6WrIMtl6I8RqzFmbn/uY1wEpVKugymdauqwmNvNCBQ+u
+W0kNlQZffmE5YcH9QKKynrTB8QXa/RUhFKmqcK9ZdzI9t8cVrIGl1bogFZ72SDd8
+/Cw8fUWh+UMoRwrrOI/g/ZYKeq6UbUVTzEs7RNuPJ1LqiT+RG6HNzUfIsvo+8tTL
+nw8bpKa2uG2pGyzGNT9R3iT29xqwrZNond4mWh+xlzSqhmznaentexQGPqJJ4tAx
+dd+jt0zCDMPH7UjWcAcobEaZQzZ4JMGURctQUnbFt1YynFUtiD8Rxvw30Yi1xrw7
+qNnFdCskuqOPxzqvM/wJG2A04+qvYegA2aO/4CGLTiDE2EPQ4OgRYCf0frSLTDQa
+eUMfqVPBhiB8h82YI1Q41GwEP7Fuo+E5LLCTNEYREgb/kxfRwxECrtIzp2q27Qwr
+Mglxw0layFcCNePypRz4Nuwhl1o1kXICp6dtHb2TTeuEorKdOG6PeA==
+-----END RSA PRIVATE KEY-----
diff --git a/raddb/certs/client.cnf b/raddb/certs/client.cnf
deleted file mode 100644 (file)
index 484fdbe..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-[ ca ]
-default_ca             = CA_default
-
-[ CA_default ]
-dir                    = ./
-certs                  = $dir
-crl_dir                        = $dir/crl
-database               = $dir/index.txt
-new_certs_dir          = $dir
-certificate            = $dir/server.pem
-serial                 = $dir/serial
-crl                    = $dir/crl.pem
-private_key            = $dir/server.key
-RANDFILE               = $dir/.rand
-name_opt               = ca_default
-cert_opt               = ca_default
-default_days           = 365
-default_crl_days       = 30
-default_md             = md5
-preserve               = no
-policy                 = policy_match
-
-[ policy_match ]
-countryName            = match
-stateOrProvinceName    = match
-organizationName       = match
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-[ policy_anything ]
-countryName            = optional
-stateOrProvinceName    = optional
-localityName           = optional
-organizationName       = optional
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-[ req ]
-prompt                 = no
-distinguished_name     = client
-default_bits           = 2048
-input_password         = whatever
-output_password                = whatever
-
-[client]
-countryName            = FR
-stateOrProvinceName    = Radius
-localityName           = Somewhere
-organizationName       = Example Inc.
-emailAddress           = user@example.com
-commonName             = user@example.com
diff --git a/raddb/certs/demoCA/index.txt b/raddb/certs/demoCA/index.txt
new file mode 100644 (file)
index 0000000..d14db85
--- /dev/null
@@ -0,0 +1,2 @@
+V      050124132608Z           01      unknown /C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Server certificate/emailAddress=server@example.com
+V      050124132610Z           02      unknown /C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Root certificate/emailAddress=root@example.com
diff --git a/raddb/certs/demoCA/index.txt.old b/raddb/certs/demoCA/index.txt.old
new file mode 100644 (file)
index 0000000..a1eef2d
--- /dev/null
@@ -0,0 +1 @@
+V      050124132608Z           01      unknown /C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Server certificate/emailAddress=server@example.com
diff --git a/raddb/certs/demoCA/serial b/raddb/certs/demoCA/serial
new file mode 100644 (file)
index 0000000..75016ea
--- /dev/null
@@ -0,0 +1 @@
+03
diff --git a/raddb/certs/demoCA/serial.old b/raddb/certs/demoCA/serial.old
new file mode 100644 (file)
index 0000000..9e22bcb
--- /dev/null
@@ -0,0 +1 @@
+02
diff --git a/raddb/certs/dh b/raddb/certs/dh
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/raddb/certs/newcert.pem b/raddb/certs/newcert.pem
new file mode 100644 (file)
index 0000000..66d4641
--- /dev/null
@@ -0,0 +1,53 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=CA, ST=Province, L=Some City, O=Organization, OU=localhost, CN=Client certificate/emailAddress=client@example.com
+        Validity
+            Not Before: Jan 25 13:26:10 2004 GMT
+            Not After : Jan 24 13:26:10 2005 GMT
+        Subject: C=CA, ST=Province, L=Some City, O=Organization, OU=localhost, CN=Root certificate/emailAddress=root@example.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:da:c5:25:42:2b:fe:db:08:26:29:a2:cb:a4:4b:
+                    34:49:c9:0d:0a:b4:62:fb:72:c8:43:4a:78:20:98:
+                    86:3d:7e:b7:d7:e7:00:28:c2:b7:ad:55:5a:51:cc:
+                    75:6c:f4:fa:1d:70:91:61:5a:b4:50:d5:28:95:53:
+                    ae:66:16:af:f0:14:a5:50:85:d6:b8:fb:4a:ee:98:
+                    63:8e:42:61:75:cd:d3:6c:66:5c:63:cd:a1:77:d3:
+                    49:20:eb:30:58:5e:dc:87:73:99:9c:29:80:f8:1a:
+                    d4:63:8b:bb:ea:1c:82:d0:54:02:3d:b7:ef:24:a3:
+                    ec:1c:3f:62:41:a9:03:d7:f3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Extended Key Usage: 
+            TLS Web Server Authentication
+    Signature Algorithm: md5WithRSAEncryption
+        7a:2d:92:1b:1c:f1:3b:f2:98:2a:91:78:ec:9e:de:6d:88:ed:
+        c1:78:a2:e8:bd:40:a0:a0:6f:b6:f0:76:99:57:88:4c:d7:08:
+        45:37:08:34:96:fd:18:41:65:29:3f:58:3c:8e:82:40:eb:68:
+        e0:42:c9:4b:15:75:2e:4c:07:e8:0d:09:77:9a:fa:3d:d5:5c:
+        24:fa:54:ac:29:2d:77:20:5d:1c:24:77:ed:30:d5:9f:57:ca:
+        f9:bd:21:ff:2a:8d:16:cc:09:11:c5:0e:4f:29:57:63:fc:b6:
+        0e:fa:3c:3d:2d:0e:43:85:0f:6e:6f:be:28:49:02:f6:e8:35:
+        03:65
+-----BEGIN CERTIFICATE-----
+MIICyTCCAjKgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBnzELMAkGA1UEBhMCQ0Ex
+ETAPBgNVBAgTCFByb3ZpbmNlMRIwEAYDVQQHEwlTb21lIENpdHkxFTATBgNVBAoT
+DE9yZ2FuaXphdGlvbjESMBAGA1UECxMJbG9jYWxob3N0MRswGQYDVQQDExJDbGll
+bnQgY2VydGlmaWNhdGUxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNv
+bTAeFw0wNDAxMjUxMzI2MTBaFw0wNTAxMjQxMzI2MTBaMIGbMQswCQYDVQQGEwJD
+QTERMA8GA1UECBMIUHJvdmluY2UxEjAQBgNVBAcTCVNvbWUgQ2l0eTEVMBMGA1UE
+ChMMT3JnYW5pemF0aW9uMRIwEAYDVQQLEwlsb2NhbGhvc3QxGTAXBgNVBAMTEFJv
+b3QgY2VydGlmaWNhdGUxHzAdBgkqhkiG9w0BCQEWEHJvb3RAZXhhbXBsZS5jb20w
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANrFJUIr/tsIJimiy6RLNEnJDQq0
+YvtyyENKeCCYhj1+t9fnACjCt61VWlHMdWz0+h1wkWFatFDVKJVTrmYWr/AUpVCF
+1rj7Su6YY45CYXXN02xmXGPNoXfTSSDrMFhe3IdzmZwpgPga1GOLu+ocgtBUAj23
+7ySj7Bw/YkGpA9fzAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG
+SIb3DQEBBAUAA4GBAHotkhsc8TvymCqReOye3m2I7cF4oui9QKCgb7bwdplXiEzX
+CEU3CDSW/RhBZSk/WDyOgkDraOBCyUsVdS5MB+gNCXea+j3VXCT6VKwpLXcgXRwk
+d+0w1Z9Xyvm9If8qjRbMCRHFDk8pV2P8tg76PD0tDkOFD25vvihJAvboNQNl
+-----END CERTIFICATE-----
diff --git a/raddb/certs/newreq.pem b/raddb/certs/newreq.pem
new file mode 100644 (file)
index 0000000..7b8c239
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,F05F3967CF53418C
+
+vWEPTlya7AN8eptUDLcYabrWcvJeMD1cWEmtdyZY0Vwnb4fbfCVOumoulXHT2qt/
+NF7b/Gi/0eJhywRbE4qTtIUguO/75hz5ZfJ2y4N+t7qYBvDYa5VVsV6y8Zw/75oO
+ol3D9YzbMA455iKQL37q+sil3r1Z3yZuXj00kojrid+o7FlN2w0l82mWofP/lcHj
+63vChPpV5U6ZaTiIXTqC9dYBC/Q/VA9/5NAWH4DsSQFbccZJIOANrSVP2oxxXOW1
+Vz0TCOAM4flrz70glUPseUa7nt3diZXlVbK3SQfL81AJlGG+L0vRfps6WiO6XrWx
+BhlMb0Jadlcw0OfKelhX1cWNcnnRAjvKntklL3fnXSjLmt0pq+4Y+w/0BHtzI9nV
+/bC/fysXgjIwE9n5GDoTZ98PalAVpCdNE1V/VoXdBWCBVupfPTuFYIOLkEg9RtMS
+ym5eQQzS14lW4Vrv6/Y9hPSIxGZPZfVfFq0zWL0x07bKZY0zV8IYZK/DK+sIF89K
+MjU5FZQ9Yyeehpus76PrsPDsNitgMbFBN8zKjzSVZQ9QvqUmX4kNuWHfVsgSDpcp
+KljnIlYAhFa0oHw+hUQra1xVfw1rh0E822CTXkoxPgZlZIlXVxeiLzdo/i7aa0eY
+W2fvmhDLjJ7teBBL1IZeyFXS7Oeeos9f3b/UNov6gPcoltDSbIEE7t4xrfGgr88s
+IeYEbDfmpcQQyshHmst6fbl7woDaLitsLeS1d1bGsuyiL88IGUlaeVbDo5xHPSVe
+Pm8SQ5+x9oUnrvMQvREXeJBkvujBffOsgdzwo9jtQqKExa4oqAn8ag==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE REQUEST-----
+MIICDzCCAXgCAQAwgZsxCzAJBgNVBAYTAkNBMREwDwYDVQQIEwhQcm92aW5jZTES
+MBAGA1UEBxMJU29tZSBDaXR5MRUwEwYDVQQKEwxPcmdhbml6YXRpb24xEjAQBgNV
+BAsTCWxvY2FsaG9zdDEZMBcGA1UEAxMQUm9vdCBjZXJ0aWZpY2F0ZTEfMB0GCSqG
+SIb3DQEJARYQcm9vdEBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEA2sUlQiv+2wgmKaLLpEs0SckNCrRi+3LIQ0p4IJiGPX631+cAKMK3rVVa
+Ucx1bPT6HXCRYVq0UNUolVOuZhav8BSlUIXWuPtK7phjjkJhdc3TbGZcY82hd9NJ
+IOswWF7ch3OZnCmA+BrUY4u76hyC0FQCPbfvJKPsHD9iQakD1/MCAwEAAaAzMBcG
+CSqGSIb3DQEJBzEKEwh3aGF0ZXZlcjAYBgkqhkiG9w0BCQIxCxMJbG9jYWxob3N0
+MA0GCSqGSIb3DQEBBAUAA4GBANhsP9ZuSRSEO2dyD73yL87y7ghvd1fus5SfV/gG
++WxbISbEwCec/8lA1lRzhd6bH9TGuGHZivnDQ1TJYys4ga9f4TX75/zT1yGR35/l
+fKkK6e04SevB6lKkXewbrodFbkGNQPGB7zK4LxCsVSMYA7qkJrWA/Y7VISXnsPLm
+hX6/
+-----END CERTIFICATE REQUEST-----
diff --git a/raddb/certs/random b/raddb/certs/random
new file mode 100644 (file)
index 0000000..ba6cc66
Binary files /dev/null and b/raddb/certs/random differ
diff --git a/raddb/certs/root.der b/raddb/certs/root.der
new file mode 100644 (file)
index 0000000..94193f2
Binary files /dev/null and b/raddb/certs/root.der differ
diff --git a/raddb/certs/root.p12 b/raddb/certs/root.p12
new file mode 100644 (file)
index 0000000..27b73b3
Binary files /dev/null and b/raddb/certs/root.p12 differ
diff --git a/raddb/certs/root.pem b/raddb/certs/root.pem
new file mode 100644 (file)
index 0000000..6afa181
--- /dev/null
@@ -0,0 +1,47 @@
+Bag Attributes
+    localKeyID: E8 C6 E0 0B F9 D3 1C 88 CA 6C 2D 4C CF 7A D4 B3 9C 91 F8 34 
+subject=/C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Client certificate/emailAddress=client@example.com
+issuer=/C=CA/ST=Province/L=Some City/O=Organization/OU=localhost/CN=Client certificate/emailAddress=client@example.com
+-----BEGIN CERTIFICATE-----
+MIIDtjCCAx+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnzELMAkGA1UEBhMCQ0Ex
+ETAPBgNVBAgTCFByb3ZpbmNlMRIwEAYDVQQHEwlTb21lIENpdHkxFTATBgNVBAoT
+DE9yZ2FuaXphdGlvbjESMBAGA1UECxMJbG9jYWxob3N0MRswGQYDVQQDExJDbGll
+bnQgY2VydGlmaWNhdGUxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNv
+bTAeFw0wNDAxMjUxMzI2MDdaFw0wNjAxMjQxMzI2MDdaMIGfMQswCQYDVQQGEwJD
+QTERMA8GA1UECBMIUHJvdmluY2UxEjAQBgNVBAcTCVNvbWUgQ2l0eTEVMBMGA1UE
+ChMMT3JnYW5pemF0aW9uMRIwEAYDVQQLEwlsb2NhbGhvc3QxGzAZBgNVBAMTEkNs
+aWVudCBjZXJ0aWZpY2F0ZTEhMB8GCSqGSIb3DQEJARYSY2xpZW50QGV4YW1wbGUu
+Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUxbGXJPFkrPH/sYnbHI+/
+9PFDlup8sekPeNaUUXJTd4ld/lLMuZtB6A3etYsSepQ/T1jLxWKHgZL73G/s6fhx
+58Ew01z1GIgX6bEzJJ7dKhx10xBDrodVPOx6d+8mqn10KB25t34XxkRsXdmxiLQy
+UMoCKZY3IqEjpyawC0An/QIDAQABo4H/MIH8MB0GA1UdDgQWBBRo020+Hue8nVoF
+cCHDY9oTZdGt4zCBzAYDVR0jBIHEMIHBgBRo020+Hue8nVoFcCHDY9oTZdGt46GB
+paSBojCBnzELMAkGA1UEBhMCQ0ExETAPBgNVBAgTCFByb3ZpbmNlMRIwEAYDVQQH
+EwlTb21lIENpdHkxFTATBgNVBAoTDE9yZ2FuaXphdGlvbjESMBAGA1UECxMJbG9j
+YWxob3N0MRswGQYDVQQDExJDbGllbnQgY2VydGlmaWNhdGUxITAfBgkqhkiG9w0B
+CQEWEmNsaWVudEBleGFtcGxlLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
+DQEBBAUAA4GBADPAC2ax5Xnvc6BnmCUtq41eVRH8AP0nbYDRL4NHd8Z0P9wnQ/yh
+UHcE5LwJeeT2CsOtnug+bzRzaSKdH3cim6LpgjWdpWMCSgAWPbptbJhsC60or4UT
+L/jw12UBvxt8Lf9ljOHmLAGZe25k4+jUNzNUzpkShHZRU5BjuFu8VIXF
+-----END CERTIFICATE-----
+Bag Attributes
+    localKeyID: E8 C6 E0 0B F9 D3 1C 88 CA 6C 2D 4C CF 7A D4 B3 9C 91 F8 34 
+Key Attributes: <No Attributes>
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,A3B736EA4DDFEA0A
+
+LyhE7gY7OmuLE8vmmu+KDg0nQ3z1uU4ZbtKEknxa9vdtL2x46ct+YYpWQm12mJpU
+bokPeNn1WsI9n8QnXWovGDIPp3yhRy62qoTwoeK3ACwkL7bMxVbPD624FcpXPoFR
+WM3I6F/v/2AqfpS2UW1WMp9tUAlGsZJrmnVXysDpnkDRfgigH3kPXaBJnwM+vqhD
+Hkba9BR+DzfZc0/MZAuptyPDmSWtyRNmo5oYBmTO64DuHOdcrCRAzfwiK6tVt0G6
+4CMUy7LDaYAlPV8aCIIu80Gryu0sk3gm+uLdi32sr1UJ311f694Ytgr7W6JAI9Bg
+RKYHuW9q9WnxkcF3dSKiMIHgei0ftQIBO56MV+peVQKzwXndqWRmZOJ/Y3iOH9Qa
+IDlbIoJbn5ZCCAlIt0/yMRHEGYD6zxS2nheAkHtoT9UCzikfllNFS7x4v+qsQjYL
+/v6Is9q5BOM3Yvgg9TNZervp5wsgkZu20fLSrmEa3eNxt8sX/WVtdevRS6O3JZhn
+VUWe1VCLEMxpJ6EVxyzV6xBq55EKJlAqtLS8D0+lcnvslfZFmupOOr8zEBw80FJl
+EnoIxdjoLy7wknRuEjx131lv8OzD1Oh6VhHj8mVDHSQjaztaoRgBixJ8n/XLNhCM
+t/vMu8DXmJD07E6r8VTzeuvPbKvcSeuMtopJ7jZvNQ7+L+ELOeW/ymoEoxMYxN8F
+/InF32CjFn8R0Tm/drCozG88fIc7zZ0A2GmMScWffgKASGAg+obpPVczgMrd8D3h
+Jk+FhCAJ2BekveCyvo9g4JfzqIhf97GLB0w0IXP1kMp7ESxn86RGWA==
+-----END RSA PRIVATE KEY-----
diff --git a/raddb/certs/server.cnf b/raddb/certs/server.cnf
deleted file mode 100644 (file)
index c56b6ea..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-[ ca ]
-default_ca             = CA_default
-
-[ CA_default ]
-dir                    = ./
-certs                  = $dir
-crl_dir                        = $dir/crl
-database               = $dir/index.txt
-new_certs_dir          = $dir
-certificate            = $dir/server.pem
-serial                 = $dir/serial
-crl                    = $dir/crl.pem
-private_key            = $dir/server.key
-RANDFILE               = $dir/.rand
-name_opt               = ca_default
-cert_opt               = ca_default
-default_days           = 365
-default_crl_days       = 30
-default_md             = md5
-preserve               = no
-policy                 = policy_match
-
-[ policy_match ]
-countryName            = match
-stateOrProvinceName    = match
-organizationName       = match
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-[ policy_anything ]
-countryName            = optional
-stateOrProvinceName    = optional
-localityName           = optional
-organizationName       = optional
-organizationalUnitName = optional
-commonName             = supplied
-emailAddress           = optional
-
-[ req ]
-prompt                 = no
-distinguished_name     = server
-default_bits           = 2048
-input_password         = whatever
-output_password                = whatever
-
-[server]
-countryName            = FR
-stateOrProvinceName    = Radius
-localityName           = Somewhere
-organizationName       = Example Inc.
-emailAddress           = admin@example.com
-commonName             = "Example Server Certificate"
-
diff --git a/raddb/certs/xpextensions b/raddb/certs/xpextensions
deleted file mode 100644 (file)
index f422167..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-#  For use with the 'CA.all' script.
-#
-[ xpclient_ext]
-extendedKeyUsage = 1.3.6.1.5.5.7.3.2
-
-[ xpserver_ext]
-extendedKeyUsage = 1.3.6.1.5.5.7.3.1
-
-#
-#  Add this to the PKCS#7 keybag attributes holding the client's private key
-#  for machine authentication.
-#
-#  the presence of this OID tells Windows XP that the cert is intended
-#  for use by the computer itself, and not by an end-user.
-#
-#  The other solution is to use Microsoft's web certificate server
-#  to generate these certs.
-#
-# 1.3.6.1.4.1.311.17.2 
diff --git a/raddb/clients b/raddb/clients
new file mode 100644 (file)
index 0000000..c6e0868
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#      THIS FILE IS DEPRECATED.
+#
+#      You should NOT be using this file to configure the server.
+#      It is here ONLY for backwards compatibility.
+#
+#      See 'clients.conf' for the new configuration.
index f0ed060..e752e27 100644 (file)
 #  are not going to be permitting RADIUS queries from localhost, we suggest
 #  that you delete, or comment out, this entry.
 #
-#
-#  Rules for Prefixes
-#  ------------------
-#  IPv6 prefixes MUST end with :: or IPv6 Address or hostname
-#  IPv4 Prefixes MUST end with .0 or IPv4 Address or hostname
-#  A hostname is a valid DNS lookup name
-#
-#  Valid Prefixes
-#  --------------
-#  For IPv4:
-#    192.168.1.1/24
-#    10.0/8 = 10.0.0.0/16 = 10.0.0.1/8    != 10/8 
-#    192.168.1.1/32 = 192.168.1.1/0
-#    hostname/32   = hostname/0  = hostname
-#   (32 or 0 or NULL prefix lengths are treated same)
-#
-#  For IPv6:
-#    fec0::/64
-#    fec0::1/100
-#    fec0::1/128  = fec0::1/0 = fec0::1 
-#    hostname/128 = hostname/0 = hostname
-#   (128 or 0 or NULL prefix lengths are treated same)
-#
-#  Invalid prefixes
-#  ----------------
-#  For IPv4:
-#  1) 192.168/16 
-#       (MUST end with .0)
-#       (replace with 192.168.0/16 or 192.168.0.0/16 or 192.168.1.1/16)
-#  2) 192.168
-#       (No Prefix, so it is considered as hostname 
-#         and also returns 192.0.0.168 instead of 192.168.0.0)
-#
-#  For IPv6:
-#  1) fec0/16
-#       (MUST end with ::)
-#       (replace with fec0::/16 or fec0::1/16)
-#  2) fec0::
-#       (No prefix, so it is considered as hostname)
-#
-
 client 127.0.0.1 {
        #
        #  The shared secret use to "encrypt" and "sign" packets between
        #  the NAS and FreeRADIUS.  You MUST change this secret from the
        #  default, otherwise it's not a secret any more!
        #
-       #  The secret can be any string, up to 8k characters in length.
-       #
-       #  Control codes can be entered vi octal encoding,
-       #       e.g. "\101\102" == "AB"
-       #  Quotation marks can be entered by escaping them,
-       #       e.g. "foo\"bar"
+       #  The secret can be any string, up to 31 characters in length.
        #
        secret          = testing123
 
@@ -123,18 +77,6 @@ client 127.0.0.1 {
 #      password    = someadminpas
 }
 
-# IPv6 Client
-#client ::1 {
-#      secret          = testing123
-#      shortname       = localhost
-#}
-#
-# All IPv6 Site-local clients
-#client fe80::/16 {
-#      secret          = testing123
-#      shortname       = localhost
-#}
-
 #client some.host.org {
 #      secret          = testing123
 #      shortname       = localhost
@@ -167,16 +109,3 @@ client 127.0.0.1 {
 #      password    = someadminpas
 #}
 
-#######################################################################
-#
-#  Per-socket client lists.  The configuration entries are exactly
-#  the same as above, but they are nested inside of a section.
-#
-#  You can have as many per-socket client lists as you have "listen"
-#  sections, or you can re-use a list among multiple "listen" sections.
-#
-#per_socket_clients {
-#      client 192.168.3.4 {
-#              secret = testing123
-#        }
-#}
index 6c47ee3..5da79bd 100644 (file)
 
                ## EAP-TLS
                #
-               #  If OpenSSL was not found at the time the server was
-               #  built, the "tls", "ttls", and "peap" sections will
-               #  be ignored.
+               #  To generate ctest certificates, run the script
                #
-               #  Otherwise, when the server first starts in debugging
-               #  mode, test certificates will be created.  See the
-               #  "make_cert_command" below for details, and the README
-               #  file in raddb/certs
+               #       ../scripts/certs.sh
                #
-               #  These test certificates SHOULD NOT be used in a normal
-               #  deployment.  They are created only to make it easier
-               #  to install the server, and to perform some simple
-               #  tests with EAP-TLS, TTLS, or PEAP.
+               #  The documents on http://www.freeradius.org/doc
+               #  are old, but may be helpful.
                #
                #  See also:
                #
                #  http://www.dslreports.com/forum/remark,9286052~mode=flat
                #
-               tls {
-                       #
-                       #  These is used to simplify later configurations.
-                       #
-                       certdir = ${raddbdir}/certs
-                       cadir = ${raddbdir}/certs
-
-                       private_key_password = whatever
-                       private_key_file = ${certdir}/server.pem
+               #tls {
+               #       private_key_password = whatever
+               #       private_key_file = ${raddbdir}/certs/cert-srv.pem
 
                        #  If Private key & Certificate are located in
                        #  the same file, then private_key_file &
                        #  certificate_file must contain the same file
                        #  name.
-                       certificate_file = ${certdir}/server.pem
+               #       certificate_file = ${raddbdir}/certs/cert-srv.pem
 
                        #  Trusted Root CA list
-                       CA_file = ${cadir}/ca.pem
+               #       CA_file = ${raddbdir}/certs/demoCA/cacert.pem
+
 
                        #
                        #  For DH cipher suites to work, you have to
                        #  run OpenSSL to create the DH file first:
                        #
                        #       openssl dhparam -out certs/dh 1024
-                       #
-                       dh_file = ${certdir}/dh
-                       random_file = ${certdir}/random
+                       #                       
+               #       dh_file = ${raddbdir}/certs/dh
+               #       random_file = ${raddbdir}/certs/random
 
                        #
                        #  This can never exceed the size of a RADIUS
                        # Set this option to specify the allowed
                        # TLS cipher suites.  The format is listed
                        # in "man 1 ciphers".
-                       cipher_list = "DEFAULT"
-
-                       #
-
-                       #  This configuration entry should be deleted
-                       #  once the server is running in a normal
-                       #  configuration.  It is here ONLY to make
-                       #  initial deployments easier.
-                       #
-                       make_cert_command = "${certdir}/bootstrap"
-               }
+               #       cipher_list = "DEFAULT"
+               #}
 
                #  The TTLS module implements the EAP-TTLS protocol,
                #  which can be described as EAP inside of Diameter,
                #  have a client certificate.  EAP-TTLS does not
                #  require a client certificate.
                #
-               ttls {
+               #ttls {
                        #  The tunneled EAP session needs a default
                        #  EAP type which is separate from the one for
                        #  the non-tunneled EAP module.  Inside of the
                        #  If the request does not contain an EAP
                        #  conversation, then this configuration entry
                        #  is ignored.
-                       default_eap_type = md5
+               #       default_eap_type = md5
 
                        #  The tunneled authentication request does
                        #  not usually contain useful attributes
                        #  is copied to the tunneled request.
                        #
                        # allowed values: {no, yes}
-                       copy_request_to_tunnel = no
+               #       copy_request_to_tunnel = no
 
                        #  The reply attributes sent to the NAS are
                        #  usually based on the name of the user
                        #  the tunneled request.
                        #
                        # allowed values: {no, yes}
-                       use_tunneled_reply = no
-               }
+               #       use_tunneled_reply = no
+               #}
 
                ##################################################
                #
                #  have a client certificate.  EAP-PEAP does not
                #  require a client certificate.
                #
-               peap {
+               peap {
                        #  The tunneled EAP session needs a default
                        #  EAP type which is separate from the one for
                        #  the non-tunneled EAP module.  Inside of the
                        #  PEAP tunnel, we recommend using MS-CHAPv2,
                        #  as that is the default type supported by
                        #  Windows clients.
-                       default_eap_type = mschapv2
+               #       default_eap_type = mschapv2
 
                        #  the PEAP module also has these configuration
                        #  items, which are the same as for TTLS.
-                       copy_request_to_tunnel = no
-                       use_tunneled_reply = no
+               #       copy_request_to_tunnel = no
+               #       use_tunneled_reply = no
 
                        #  When the tunneled session is proxied, the
                        #  home server may not understand EAP-MSCHAP-V2.
                        #  Set this entry to "no" to proxy the tunneled
                        #  EAP-MSCHAP-V2 as normal MSCHAPv2.
                #       proxy_tunneled_request_as_eap = yes
-               }
+               #}
 
                #
                #  This takes no configuration.
index 39bb360..95bb8f0 100644 (file)
                #
                #  The Perl script to execute on authorize, authenticate,
                #  accounting, xlat, etc.  This is very similar to using
-               #  'rlm_exec' module, but it is persistent, and therefore
-               #  faster.
+               #  Exec-Program-Wait = "/path/foo.pl", but it is persistent,
+               #  and therefore faster.
                #
-               module = /path/to/your/perl_module.pm
+                module = /path/to/your/perl_program
 
                #
                #  The following hashes are given to the module and
                 #  filled with value-pairs (Attribute names and values)
                #
-               #  %RAD_CHECK           Read-only       Check items
-               #  %RAD_REQUEST         Read-only       Attributes from the request
-               #  %RAD_REPLY           Read-write      Attributes for the reply
-               # 
+               #  %RAD_REPLY           Attributes to go into the reply
+               #  %RAD_REQUEST         Attributes from the request
+               #  %RAD_CHECK           Check items
+               #
+               #  Only the %RAD_REPLY hash can be modified.
+               #  All of the other hashes are read only.
+               #
                #  The return codes from functions in the perl_script
                #  are passed directly back to the server.  These
                #  codes are defined in doc/configurable_failover,
                #  and are pre-defined in the 'example.pl' program
                #  which is included.
                #               
-
-               #
-               #  List of functions in the module to call.
-               #  Uncomment and change if you want to use function
-               #  names other than the defaults.
-               #
-               #func_authenticate = authenticate
-               #func_authorize = authorize
-               #func_preacct = preacct
-               #func_accounting = accounting
-               #func_checksimul = checksimul
-               #func_pre_proxy = pre_proxy
-               #func_post_proxy = post_proxy
-               #func_post_auth = post_auth
-               #func_xlat = xlat
-               #func_detach = detach
-
-               #
-               #  Uncomment the following lines if you wish
-               #  to use separate functions for Start and Stop
-               #  accounting packets. In that case, the 
-               #  func_accounting function is not called.
-               #
-               #func_start_accounting = accounting_start
-               #func_stop_accounting = accounting_stop
-               
-               #  Uncomment the following lines if your perl is 
-               #  compiled with threads support.
-               #  The settings below are the defaults.
-               #
-               #max_clones = 32
-               #start_clones = 32
-               #min_spare_clones = 0
-               #max_spare_clones = 32
-               #cleanup_delay = 5
-               #max_request_per_clone = 0
-
+                func_accounting = accounting
+                func_authenticate = authenticate
+               func_authorize = authorize
+                func_preacct = preacct
+                func_checksimul = checksimul
+                func_xlat = xlat
        }
 
        #
                # Reload the hash every 600 seconds (10mins)
                hash_reload = 600
        }
-
-       #
-       #  See also protocol_filter.conf
-       #
-       protocol_filter {
-               #
-               #  Location of the protocol filter configuration file.
-               #
-               filename = ${raddbdir}/protocol_filter.conf
-
-               #
-               #  The key to look up the section with filtering rules.
-               #
-               key = %{Realm:-DEFAULT}
-       }
-
-       # Caching module
-       #
-       # Should be added in the post-auth section (after all other modules)
-       # and in the authorize section (before any other modules)
-       #
-       # authorize {
-       #       caching {
-       #               ok = return
-       #       }
-       #       [... other modules ...]
-       # }
-       # post-auth {
-       #       [... other modules ...]
-       #       caching
-       # }
-       #
-       # The caching module will cache the Auth-Type and reply items
-       # and send them back on any subsequent requests for the same key
-       #
-       # Configuration:
-       #
-       # filename: The gdbm file to use for the cache database
-       #               (can be memory mapped for more speed)
-       #
-       # key: A string to xlat and use as a key. For instance,
-       #       "%{Acct-Unique-Session-Id}"
-       #
-       # post-auth: If we find a cached entry, set the post-auth to that value
-       #
-       # cache-ttl: The time to cache the entry. The same time format
-       #               as the counter module apply here.
-       #         num[hdwm] where:
-       #       h: hours, d: days, w: weeks, m: months
-       #       If the letter is ommited days will be assumed.
-       #       e.g. 1d == one day
-       #
-       # cache-size: The gdbm cache size to request (default 1000)
-       #
-       # hit-ratio: If set to non-zero we print out statistical
-       #       information after so many cache requests
-       #
-       # cache-rejects: Do we also cache rejects, or not? (default 'yes')
-       #
-       caching {
-               filename = ${raddbdir}/db.cache
-               cache-ttl = 1d
-               hit-ratio = 1000
-               key = "%{Acct-Unique-Session-Id}"
-               #post-auth = ""
-               # cache-size = 2000
-               # cache-rejects = yes
-       }
-
-
-       # Simple module for logging of Account packets to radiusd.log
-       # You need to declare it in the accounting section for it to work
-       acctlog {
-               acctlog_update = ""
-               acctlog_start = "Connect: [%{User-Name}] (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} ip %{Framed-IP-Address})"
-               acctlog_stop = "Disconnect: [%{User-Name}] (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} ip %{Framed-IP-Address}) %{Acct-Session-Time} seconds"
-               acctlog_on = "NAS %C (%{NAS-IP-Address}) just came online"
-               acctlog_off = "NAS %C (%{NAS-IP-Address}) just went offline"
-       }
index 912d98f..e686556 100644 (file)
@@ -3,21 +3,12 @@
 # to be used by LDAP authentication and authorization module (rlm_ldap)
 #
 # Format:
-#   ItemType   RADIUS-Attribute-Name           ldapAttributeName  [operator]
+#   ItemType   RADIUS-Attribute-Name           ldapAttributeName
 #
 # Where:
 #   ItemType              = checkItem or replyItem 
 #   RADIUS-Attribute-Name = attribute name in RADIUS dictionary
 #   ldapAttributeName     = attribute name in LDAP schema
-#   operator              = optional, and may not be present.
-#                          If not present, defaults to "==" for checkItems,
-#                          and "=" for replyItems.
-#                          If present, the operator here should be one
-#                          of the same operators as defined in the "users"3
-#                          file ("man users", or "man 5 users").
-#                          If an operator is present in the value of the
-#                          LDAP entry (i.e. ":=foo"), then it over-rides
-#                          both the default, and any operator given here.
 #
 # If $GENERIC$ is specified as RADIUS-Attribute-Name, the line specifies
 # a LDAP attribute which can be used to store any RADIUS 
@@ -35,8 +26,6 @@ checkItem     Called-Station-Id               radiusCalledStationId
 checkItem      Calling-Station-Id              radiusCallingStationId
 checkItem      LM-Password                     lmPassword
 checkItem      NT-Password                     ntPassword
-checkItem      LM-Password                     sambaLmPassword
-checkItem      NT-Password                     sambaNtPassword
 checkItem      SMB-Account-CTRL-TEXT           acctFlags
 checkItem      Expiration                      radiusExpiration
 checkItem      NAS-IP-Address                  radiusNASIpAddress
similarity index 80%
rename from raddb/sql/mssql-dialup.conf
rename to raddb/mssql.conf
index a3cfe3b..0627627 100644 (file)
@@ -7,6 +7,45 @@
 #
 #  $Id$
 #
+sql {
+
+       # Database type
+       # Current supported are: rlm_sql_mysql, rlm_sql_postgresql,
+       # rlm_sql_iodbc, rlm_sql_oracle, rlm_sql_unixodbc
+       driver = "rlm_sql_unixodbc"
+
+       # Connect info
+       server = "localhost"
+       login = "root"
+       password = "rootpass"
+
+       # Database table configuration
+       radius_db = "radius"
+
+       # If you want both stop and start records logged to the
+       # same SQL table, leave this as is.  If you want them in
+       # different tables, put the start table in acct_table1
+       # and stop table in acct_table2
+       acct_table1 = "radacct"
+       acct_table2 = "radacct"
+
+       authcheck_table = "radcheck"
+       authreply_table = "radreply"
+
+       groupcheck_table = "radgroupcheck"
+       groupreply_table = "radgroupreply"
+
+       usergroup_table = "usergroup"
+
+       # Remove stale session if checkrad does not see a double login
+       deletestalesessions = yes
+
+       # Print all SQL statements when in debug mode (-x)
+       sqltrace = no
+       sqltracefile = ${logdir}/sqltrace.sql
+
+       # number of sql connections to make to server
+       num_sql_socks = 5
 
        # Safe characters list for sql queries. Everything else is replaced
        # with their mime-encoded equivalents.
        #                               (alternate in case first query doesn't
        #                                affect any existing rows in the table)
        #######################################################################
-       accounting_onoff_query = "UPDATE ${acct_table1} SET AcctStopTime='%S', AcctSessionTime=unix_timestamp('%S') - unix_timestamp(AcctStartTime), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = %{Acct-Delay-Time:-0} WHERE AcctSessionTime=0 AND AcctStopTime=0 AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= '%S'"
+       accounting_onoff_query = "UPDATE ${acct_table1} SET AcctStopTime='%S', AcctSessionTime=unix_timestamp('%S') - unix_timestamp(AcctStartTime), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = %{Acct-Delay-Time} WHERE AcctSessionTime=0 AND AcctStopTime=0 AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= '%S'"
 
        accounting_update_query = "UPDATE ${acct_table1} SET FramedIPAddress = '%{Framed-IP-Address}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStopTime = 0"
 
 
        # accounting_start_query: Inserting of RadAcctId and AcctStopTime was
        # removed. These fields are processing by a database
-       accounting_start_query = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPort, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', '%S', '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time:-0}', '0')"
+       accounting_start_query = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPort, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', '%S', '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time}', '0')"
 
-       accounting_start_query_alt  = "UPDATE ${acct_table1} SET AcctStartTime = '%S', AcctStartDelay = '%{Acct-Delay-Time:-0}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime = 0"
+       accounting_start_query_alt  = "UPDATE ${acct_table1} SET AcctStartTime = '%S', AcctStartDelay = '%{Acct-Delay-Time}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime = 0"
 
-       accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = '%S', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime = 0"
+       accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = '%S', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime = 0"
 
        # accounting_stop_query_alt: Inserting of RadAcctId and AcctStartTime was
        # removed. These fields are processing by a database
-       accounting_stop_query_alt = "INSERT into ${acct_table2} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPort, NASPortType, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', '%S', '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time:-0}')"
+       accounting_stop_query_alt = "INSERT into ${acct_table2} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPort, NASPortType, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', '%S', '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time}')"
 
+}
diff --git a/raddb/naslist b/raddb/naslist
new file mode 100644 (file)
index 0000000..ea73423
--- /dev/null
@@ -0,0 +1,31 @@
+#
+#      THIS FILE IS DEPRECATED.
+#
+#      You should NOT be using this file to configure the server.
+#      It is here ONLY for backwards compatibility.
+#
+#      See 'clients.conf' for the new configuration.
+#
+#
+# naslist      This file contains a list of NASes (Network Access Servers,
+#              also known as terminal servers) which we know.
+#
+#              Description of the fields:
+#
+#              * The first field is a valid hostname or IP address
+#                for the client.
+#              * The second field (seperated by blanks or tabs) is the 
+#                short name we use in the logfiles for this NAS.
+#              * The third field defines what type of device it is. Valid
+#                values are "cisco", "computone", "livingston", "max40xx", 
+#                 "multitech", "netserver", "pathras", "patton", "portslave", 
+#                 "tc", "usrhiper" or "other".
+#
+#              This is used to find out how to detect double logins.
+#
+
+# NAS Name             Short Name      Type
+#----------------      ----------      ----
+#portmaster1.isp.com   pm1.NY          livingston
+#portmaster2.isp.com   pm1.LA          livingston
+localhost              local           portslave
similarity index 84%
rename from raddb/sql/oracle-dialup.conf
rename to raddb/oraclesql.conf
index 35ffe6d..ebbc7b7 100644 (file)
@@ -7,7 +7,49 @@
 #
 #      $Id$
 #
-
+sql {
+
+       # Database type
+       # Current supported are: rlm_sql_mysql, rlm_sql_postgresql,
+       # rlm_sql_iodbc, rlm_sql_oracle, rlm_sql_unixodbc, rlm_sql_freetds
+       driver = "rlm_sql_oracle"
+
+       # Connect info
+       server = "localhost"
+       login = "root"
+       password = "rootpass"
+       
+       # Database table configuration
+       radius_db = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SID=your_sid)))"
+               
+       # If you want both stop and start records logged to the
+       # same SQL table, leave this as is.  If you want them in
+       # different tables, put the start table in acct_table1
+       # and stop table in acct_table2
+       acct_table1 = "radacct"
+       acct_table2 = "radacct"
+               
+       authcheck_table = "radcheck"
+       authreply_table = "radreply"
+       
+       groupcheck_table = "radgroupcheck"
+       groupreply_table = "radgroupreply"
+       
+       usergroup_table = "usergroup"
+       
+       # Remove stale session if checkrad does not see a double login
+       deletestalesessions = yes
+
+       # Print all SQL statements when in debug mode (-x)
+       sqltrace = no
+       sqltracefile = ${logdir}/sqltrace.sql
+
+       # number of sql connections to make to server
+       num_sql_socks = 5
+
+       # number of seconds to dely retrying on a failed database
+       # connection (per_socket)
+       connect_failure_retry_delay = 60
 
        #######################################################################
        #  Query config:  Username
        #                               (alternate in case first query doesn't
        #                                affect any existing rows in the table)
        #######################################################################
-       accounting_onoff_query = "UPDATE ${acct_table1} SET AcctStopTime=TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctSessionTime=((TO_DATE('%S','yyyy-mm-dd hh24:mi:ss') - AcctStartTime)*86400), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = %{Acct-Delay-Time:-0} WHERE AcctSessionTime=0 AND AcctStopTime IS NULL AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStartTime <= TO_DATE('%S','yyyy-mm-dd hh24:mi:ss')"
+       accounting_onoff_query = "UPDATE ${acct_table1} SET AcctStopTime=TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctSessionTime=((TO_DATE('%S','yyyy-mm-dd hh24:mi:ss') - AcctStartTime)*86400), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = %{Acct-Delay-Time} WHERE AcctSessionTime=0 AND AcctStopTime IS NULL AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStartTime <= TO_DATE('%S','yyyy-mm-dd hh24:mi:ss')"
 
 accounting_update_query = "UPDATE ${acct_table1} \
     SET FramedIPAddress = NULLIF('%{Framed-IP-Address}', ''), \
@@ -116,16 +158,13 @@ accounting_update_query = "UPDATE ${acct_table1} \
 
        accounting_update_query_alt = "INSERT into ${acct_table1} (RadAcctId, AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay) values('', '%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', NULL, '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0')"
 
-       accounting_start_query = "INSERT into ${acct_table1} (RadAcctId, AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('', '%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), NULL, '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time:-0}', '0')"
-
-       accounting_start_query_alt  = "UPDATE ${acct_table1} SET AcctStartTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctStartDelay = '%{Acct-Delay-Time:-0}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
+       accounting_start_query = "INSERT into ${acct_table1} (RadAcctId, AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('', '%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), NULL, '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time}', '0')"
 
-       accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
+       accounting_start_query_alt  = "UPDATE ${acct_table1} SET AcctStartTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctStartDelay = '%{Acct-Delay-Time}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
 
-       # Optional Query - pnixon
-       #accounting_stop_query =3D "UPDATE ${acct_table2} SET AcctStopTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctSessionTime = (substr((sysdate-acctstarttime),instr((sysdate-acctstarttime),' ')+7,2) + substr((sysdate-acctstarttime),instr((sysdate-acctstarttime),' ')+4,2)*60 + substr((sysdate-acctstarttime),instr((sysdate-acctstarttime),' ')+1,2)*3600 + trunc(to_number(substr((sysdate-acctstarttime),1,instr(sysdate-acctstarttime,' '))))*86400), AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId =3D '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL" 
+       accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
 
-       accounting_stop_query_alt = "INSERT into ${acct_table2} (RadAcctId, AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('', '%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', NULL, TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time:-0}')"
+       accounting_stop_query_alt = "INSERT into ${acct_table2} (RadAcctId, AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('', '%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port-Id}', '%{NAS-Port-Type}', NULL, TO_DATE('%S','yyyy-mm-dd hh24:mi:ss'), '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time}')"
 
        #######################################################################
        # Simultaneous Use Checking Queries
@@ -149,4 +188,4 @@ accounting_update_query = "UPDATE ${acct_table1} \
        #######################################################################
 
        group_membership_query = "SELECT GroupName FROM ${usergroup_table} WHERE UserName='%{SQL-User-Name}'"
-
+}
index 3ae59e1..3984a7e 100644 (file)
@@ -10,7 +10,7 @@
 #  management and OTP verification functions; and lsmd or gsmd,
 #  which implements synchronous state management functions.
 #  otpd, lsmd and gsmd are available from TRI-D Systems:
-#              <http://www.tri-dsystems.com/>
+#              <http://www.TRI-Dsystems.com/>
 
 #  You must list this module in BOTH the authorize and authenticate
 #  sections in order to use it.
similarity index 94%
rename from raddb/sql/postgresql-voip-postpaid.conf
rename to raddb/pgsql-voip.conf
index 001a724..c4c28bd 100644 (file)
@@ -29,7 +29,7 @@ sql pgsql-voip {
        groupcheck_table = "radgroupcheck"
        groupreply_table = "radgroupreply"
        
-       usergroup_table = "radusergroup"
+       usergroup_table = "usergroup"
        
        # Remove stale session if checkrad does not see a double login
        deletestalesessions = yes
@@ -43,7 +43,7 @@ sql pgsql-voip {
        
        # Radius server name so you can tell which radius server handled a request
        # when you have multiple radius servers and one database.
-       radius_server_name = FreeRADIUS
+       radius_server_name = myservername
 
        #######################################################################
        #  Query config:  Username
@@ -97,11 +97,11 @@ sql pgsql-voip {
        accounting_stop_query = "INSERT into ${acct_table2}%{h323-call-type} \
                (RadiusServerName, UserName, NASIPAddress, AcctTime, \
                AcctSessionTime, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, \
-               AcctDelayTime, H323RemoteAddress, H323VoiceQuality, CiscoNASPort, h323callorigin, callid, \
+               AcctDelayTime, H323RemoteAddress, CiscoNASPort, h323callorigin, callid, \
                h323connecttime, h323disconnectcause, h323disconnecttime, h323gwid, h323setuptime) \
                values('${radius_server_name}', '%{SQL-User-Name}', '%{NAS-IP-Address}', now(), '%{Acct-Session-Time:-0}', \
                '%{Acct-Input-Octets:-0}', '%{Acct-Output-Octets:-0}', '%{Called-Station-Id}', '%{Calling-Station-Id}', \
-               '%{Acct-Delay-Time:-0}', NULLIF('%{h323-remote-address}', '')::inet, NULLIF('%{h323-voice-quality}','')::integer, NULLIF('%{Cisco-NAS-Port}', ''), \
+               '%{Acct-Delay-Time:-0}', NULLIF('%{h323-remote-address}', '')::inet, NULLIF('%{Cisco-NAS-Port}', ''), \
                '%{h323-call-origin}', pick_id('%{h323-conf-id}', '%{call-id}'), strip_dot('%{h323-connect-time}'), '%{h323-disconnect-cause}', \
                strip_dot('%{h323-disconnect-time}'), '%{h323-gw-id}', strip_dot('%{h323-setup-time}'))"
  
diff --git a/raddb/policy.txt b/raddb/policy.txt
deleted file mode 100755 (executable)
index a1c6754..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-#      Sample of a policy language.
-#      There's no documentation other than this file.
-#      The syntax is odd, but it works.
-#      It's not intended for production use.
-#      Use it if you want obscure error messages and possibly server crashes.
-#
-#      $Id$
-#
-#  Debugging statements
-#
-#debug print_tokens    # as we're parsing this file
-debug print_policy     # once the file has been parsed
-debug evaluate         # print limited information during evaluation
-
-#
-#  A named policy.
-#
-policy 3pm {
-if (Time-Of-Day < "15:00") {
-   reply .= {
-      # Use ARAP-Password for testing because it's an attribute
-      # no one cares about.
-      ARAP-Password = "< 15:00"
-   }
-}
-
-}
-
-#
-#  A named policy, executed during the "authorize" phase,
-#  because it's named "authorize". 
-#
-policy authorize {
-  if (CHAP-Password) {
-     if (!(CHAP-Challenge)) {
-        print "Adding CHAP-Challenge = %{request:Packet-Authentication-Vector}\n"
-
-        #
-        #  Append all attributes to the specified list.
-        #  The per-attribute operators MUST be '='
-        #
-        request .= {
-           CHAP-Challenge = "%{request:Packet-Authentication-Vector}"
-        }
-     }
-
-     #
-     #  Use per-attribute operators to do override, replace, etc.
-     #  It's "control", not "check items", because "check items"
-     #  is a hold-over from the "users" file, and we no longer like that.
-     #
-     control = {
-         Auth-Type := CHAP
-     }
-  }
-
-#
-#  This could just as well be "%{ldap: query...}" =~ ...
-#
-#  if ("%{User-Name}" =~ "^(b)") {
-#     reply .= {
-#         Arap-Password = "Hello, %{1}"
-#     }
-#  }
-
-  #
-  #  Execute "3pm", as if it was in-line here.
-  #
-#  call 3pm
-}
diff --git a/raddb/postgresql.conf b/raddb/postgresql.conf
new file mode 100644 (file)
index 0000000..b6944c2
--- /dev/null
@@ -0,0 +1,269 @@
+#
+#  $Id$
+#
+#  Configuration for the SQL module, when using Postgresql.
+#
+#  The database schema is available at:
+#
+#      doc/examples/postgresql.sql
+#
+
+sql {
+
+       # Database type
+       # Current supported are: rlm_sql_mysql, rlm_sql_postgresql,
+       # rlm_sql_unixodbc, rlm_sql_oracle.
+       driver = "rlm_sql_postgresql"
+
+       # Connect info
+       server = "localhost"
+
+       # The following credentials will most likely work on a default
+       # install of Postgresql. If they do work however, it means that
+       # you have a HUGE GAPING SECURITY RISK on your server! Please
+       # change the "postgres" users password and setup a separate
+       # radius user.
+       login = "postgres"
+       password = ""
+
+       # Database table configuration
+       radius_db = "radius"
+
+       # If you want both stop and start records logged to the
+       # same SQL table, leave this as is.  If you want them in
+       # different tables, put the start table in acct_table1
+       # and stop table in acct_table2
+       acct_table1 = "radacct"
+       acct_table2 = "radacct"
+
+       # Allow for storing data after authentication
+       postauth_table = "radpostauth"
+
+       authcheck_table = "radcheck"
+       authreply_table = "radreply"
+
+       groupcheck_table = "radgroupcheck"
+       groupreply_table = "radgroupreply"
+
+       # Table to keep group info
+       usergroup_table = "usergroup"
+
+       # Remove stale session if checkrad does not see a double login
+       deletestalesessions = yes
+
+       # Print all SQL statements when in debug mode (-x)
+       sqltrace = yes
+       sqltracefile = ${logdir}/sqltrace.sql
+
+       # number of sql connections to make to server
+       num_sql_socks = 5
+
+       # number of seconds to dely retrying on a failed database
+       # connection (per_socket)
+       #connect_failure_retry_delay = 60
+
+       #######################################################################
+       #  Query config:  Username
+       #######################################################################
+       # This is the username that will get substituted, escaped, and added
+       # as attribute 'SQL-User-Name'.  '%{SQL-User-Name}' should be used
+       # below everywhere a username substitution is needed so you you can
+       # be sure the username passed from the client is escaped properly.
+       #
+       # Uncomment the next line, if you want the sql_user_name to mean:
+       #
+       #    Use Stripped-User-Name, if it's there.
+       #    Else use User-Name, if it's there,
+       #    Else use hard-coded string "none" as the user name.
+       #
+       #sql_user_name = "%{Stripped-User-Name:-%{User-Name:-none}}"
+       #
+       sql_user_name = "%{User-Name}"
+
+
+       #######################################################################
+       #  Authorization Queries
+       #######################################################################
+       #  These queries compare the check items for the user
+       #  in ${authcheck_table} and setup the reply items in
+       #  ${authreply_table}.  You can use any query/tables
+       #  you want, but the return data for each row MUST
+       #  be in the  following order:
+       #
+       #  0. Row ID (currently unused)
+       #  1. UserName/GroupName
+       #  2. Item Attr Name
+       #  3. Item Attr Value
+       #  4. Item Attr Operation
+       #######################################################################
+
+       # Use these for case insensitive usernames. WARNING: Slower queries!
+# authorize_check_query = "SELECT id, UserName, Attribute, Value, Op \
+#   FROM ${authcheck_table} \
+#   WHERE LOWER(UserName) = LOWER('%{SQL-User-Name}') \
+#   ORDER BY id"
+# authorize_reply_query = "SELECT id, UserName, Attribute, Value, Op \
+#   FROM ${authreply_table} \
+#   WHERE LOWER(UserName) = LOWER('%{SQL-User-Name}') \
+#   ORDER BY id"
+
+       authorize_check_query = "SELECT id, UserName, Attribute, Value, Op \
+               FROM ${authcheck_table} \
+               WHERE Username = '%{SQL-User-Name}' \
+               ORDER BY id"
+
+       authorize_reply_query = "SELECT id, UserName, Attribute, Value, Op \
+               FROM ${authreply_table} \
+               WHERE Username = '%{SQL-User-Name}' \
+               ORDER BY id"
+
+       # Use these for case insensitive usernames. WARNING: Slower queries!
+# authorize_group_check_query = "SELECT ${groupcheck_table}.id, ${groupcheck_table}.GroupName, \
+#   ${groupcheck_table}.Attribute, ${groupcheck_table}.Value, ${groupcheck_table}.Op \
+#   FROM ${groupcheck_table}, ${usergroup_table} \
+#   WHERE LOWER(${usergroup_table}.UserName) = LOWER('%{SQL-User-Name}') AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName \
+#   ORDER BY ${groupcheck_table}.id"
+# authorize_group_reply_query = "SELECT ${groupreply_table}.id, ${groupreply_table}.GroupName, \
+#   ${groupreply_table}.Attribute, ${groupreply_table}.Value, ${groupreply_table}.Op \
+#   FROM ${groupreply_table}, ${usergroup_table} \
+#   WHERE LOWER(${usergroup_table}.UserName) = LOWER('%{SQL-User-Name}') AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName \
+#   ORDER BY ${groupreply_table}.id"
+
+       authorize_group_check_query = "SELECT ${groupcheck_table}.id, ${groupcheck_table}.GroupName, \
+               ${groupcheck_table}.Attribute, ${groupcheck_table}.Value,${groupcheck_table}.Op \
+               FROM ${groupcheck_table}, ${usergroup_table} \
+               WHERE ${usergroup_table}.Username = '%{SQL-User-Name}' AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName \
+               ORDER BY ${groupcheck_table}.id"
+
+       authorize_group_reply_query = "SELECT ${groupreply_table}.id, ${groupreply_table}.GroupName, ${groupreply_table}.Attribute, \
+               ${groupreply_table}.Value, ${groupreply_table}.Op \
+               FROM ${groupreply_table},${usergroup_table} \
+               WHERE ${usergroup_table}.Username = '%{SQL-User-Name}' AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName \
+               ORDER BY ${groupreply_table}.id"
+
+       #######################################################################
+       #  Authentication Query
+       #######################################################################
+       # This query is used only to get the Password for the
+       # user we want to authenticate.  The password MUST
+       # be the first field in the return row data.
+       #######################################################################
+
+       authenticate_query = "SELECT Value,Attribute FROM ${authcheck_table} \
+               WHERE UserName = '%{User-Name}' AND ( Attribute = 'User-Password' OR Attribute = 'Crypt-Password' ) \
+               ORDER BY Attribute DESC"
+
+        #######################################################################
+        # Simultaneous Use Checking Queries
+        #######################################################################
+        # simul_count_query     - query for the number of current connections
+        #                       - If this is not defined, no simultaneouls use checking
+        #                       - will be performed by this module instance
+        # simul_verify_query    - query to return details of current connections for verification
+        #                       - Leave blank or commented out to disable verification step
+        #                       - Note that the returned field order should not be changed.
+        #######################################################################
+
+        # Uncomment simul_count_query to enable simultaneous use checking
+       # simul_count_query = "SELECT COUNT(*) FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime IS NULL"
+        # simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime IS NULL"
+
+
+
+       #######################################################################
+       #  Accounting Queries
+       #######################################################################
+       # accounting_onoff_query        - query for Accounting On/Off packets
+       # accounting_update_query       - query for Accounting update packets
+       # accounting_update_query_alt   - query for Accounting update packets
+       #                               (alternate in case first query fails)
+       # accounting_start_query        - query for Accounting start packets
+       # accounting_start_query_alt    - query for Accounting start packets
+       #                               (alternate in case first query fails)
+       # accounting_stop_query         - query for Accounting stop packets
+       # accounting_stop_query_alt     - query for Accounting start packets
+       #                               (alternate in case first query doesn't
+       #                                affect any existing rows in the table)
+       #######################################################################
+
+       accounting_onoff_query = "UPDATE ${acct_table1} \
+               SET AcctStopTime = ('%S'::timestamp - '%{Acct-Delay-Time:-0}'::interval), \
+               AcctSessionTime = (EXTRACT(EPOCH FROM('%S'::timestamp with time zone - AcctStartTime::timestamp with time zone - '%{Acct-Delay-Time:-0}'::interval)))::BIGINT, \
+               AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}' \
+               WHERE AcctSessionTime IS NULL AND AcctStopTime IS NULL AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= '%S'::timestamp"
+
+       accounting_update_query = "UPDATE ${acct_table1} \
+               SET FramedIPAddress = NULLIF('%{Framed-IP-Address}', '')::inet, \
+               AcctSessionTime = (EXTRACT(EPOCH FROM('%S'::timestamp with time zone - AcctStartTime::timestamp with time zone - '%{Acct-Delay-Time:-0}'::interval)))::BIGINT, \
+                AcctInputOctets = (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
+                AcctOutputOctets = (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint) \
+               WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' \
+               AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
+
+       accounting_update_query_alt = "INSERT into ${acct_table1} \
+               (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, \
+               AcctSessionTime, AcctAuthentic, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, \
+               ServiceType, FramedProtocol, FramedIPAddress, XAscendSessionSvrKey) \
+               values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', \
+               '%{NAS-Port}', '%{NAS-Port-Type}', ('%S'::timestamp -  '%{Acct-Delay-Time:-0}'::interval - '%{Acct-Session-Time:-0}'::interval), \
+               '%{Acct-Session-Time}', '%{Acct-Authentic}', \
+               (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
+               (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint), '%{Called-Station-Id}', \
+               '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', \
+               NULLIF('%{Framed-IP-Address}', '')::inet, '%{X-Ascend-Session-Svr-Key}')"
+
+       accounting_start_query = "INSERT into ${acct_table1} \
+               (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctAuthentic, \
+               ConnectInfo_start, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, XAscendSessionSvrKey) \
+               values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', \
+               '%{NAS-Port}', '%{NAS-Port-Type}', ('%S'::timestamp - '%{Acct-Delay-Time:-0}'::interval), '%{Acct-Authentic}', '%{Connect-Info}', \
+               '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', \
+               NULLIF('%{Framed-IP-Address}', '')::inet, '%{Acct-Delay-Time:-0}', '%{X-Ascend-Session-Svr-Key}')"
+
+       accounting_start_query_alt  = "UPDATE ${acct_table1} \
+               SET AcctStartTime = ('%S'::timestamp - '%{Acct-Delay-Time:-0}'::interval), AcctStartDelay = '%{Acct-Delay-Time:-0}', \
+               ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' \
+               AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
+
+       accounting_stop_query = "UPDATE ${acct_table2} \
+               SET AcctStopTime = ('%S'::timestamp - '%{Acct-Delay-Time:-0}'::interval), \
+               AcctSessionTime = NULLIF('%{Acct-Session-Time}', '')::bigint, \
+               AcctInputOctets = (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
+               AcctOutputOctets = (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint), \
+               AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}', \
+               FramedIPAddress = NULLIF('%{Framed-IP-Address}', '')::inet, ConnectInfo_stop = '%{Connect-Info}' \
+               WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' \
+               AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
+
+       accounting_stop_query_alt = "INSERT into ${acct_table2} \
+               (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, \
+               AcctSessionTime, AcctAuthentic, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, \
+               AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStopDelay, XAscendSessionSvrKey) \
+               values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', \
+               '%{NAS-Port}', '%{NAS-Port-Type}', ('%S'::timestamp -  '%{Acct-Delay-Time:-0}'::interval - '%{Acct-Session-Time:-0}'::interval), \
+               ('%S'::timestamp - '%{Acct-Delay-Time:-0}'::interval), NULLIF('%{Acct-Session-Time}', '')::bigint, \
+               '%{Acct-Authentic}', '%{Connect-Info}', \
+               (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
+               (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint), '%{Called-Station-Id}', \
+               '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', \
+               NULLIF('%{Framed-IP-Address}', '')::inet, '%{Acct-Delay-Time:-0}', '%{X-Ascend-Session-Svr-Key}')"
+
+       #######################################################################
+       # Group Membership Queries
+       #######################################################################
+       # group_membership_query        - Check user group membership
+       #######################################################################
+
+       # Use these for case insensitive usernames. WARNING: Slower queries!
+#      group_membership_query = "SELECT GroupName FROM ${usergroup_table} WHERE LOWER(UserName) = LOWER('%{SQL-User-Name}')"
+
+       group_membership_query = "SELECT GroupName FROM ${usergroup_table} WHERE UserName='%{SQL-User-Name}'"
+
+       #######################################################################
+       # Authentication Logging Queries
+       #######################################################################
+       # postauth_query                - Insert some info after authentication
+       #######################################################################
+       postauth_query = "INSERT INTO ${postauth_table} (username, pass, reply, authdate) VALUES ('%{User-Name}', '%{User-Password:-Chap-Password}', '%{reply:Packet-Type}', NOW())"
+
+}
index 0f5d15a..b889a77 100644 (file)
@@ -1,26 +1,11 @@
 #
-#  Configuration file for the rlm_files module.
-#  Please see rlm_files(5) manpage for more information.
-#
-#  $Id$
-#
 #  This file is similar to the "users" file.  The check items
 #  are compared against the request, but the "reply" items are
-#  used to update the proxied packet, not the reply to the NAS.
-#
-#  You can use this file to re-write requests which are about to
-#  be sent to a home server.
-#
-
+#  used to update the proxied packet, not the reply to the NAS>
 #
-#  Requests destinated to realm "extisp" are sent to a RADIUS
-#  home server hosted by an other company which doesn't know about
-#  the IP addresses of our NASes. Therefore we replace the value of
-#  the NAS-IP-Address attribute by a unique value we communicated
-#  to them.
+#  You can use this file to re-write requests which are about to be
+#  sent to a home server.
 #
-#DEFAULT Realm == "extisp"
-#      NAS-IP-Address := 10.1.2.3
 
 #
 #  For all proxied packets, set the User-Name in the proxied packet
diff --git a/raddb/protocol_filter.conf b/raddb/protocol_filter.conf
deleted file mode 100755 (executable)
index 1687865..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#
-#      $Id$
-#
-#      Filter protocols by realm (or other key)
-#      The "protocol_filter" module reads this file, and implements
-#      the restrictions contained in it.
-#
-#      The main purpose of this configuration file is to permit the
-#      administrator to control, by realm (or any other key), which
-#      protocols the request is permitted to contain.  This allows
-#      the server to permit users in one realm to use (say) EAP, and
-#      to deny EAP to users in other realms.
-#
-#      The key is used to look up entries by subsection.  Within each
-#      subsection, there is a list of attributes, with value "permit"
-#      or "deny".  When a request comes in, the attributes from the
-#      request packet are looked up in the appropriate section given
-#      by the key.  If the section has an entry which says "permit"
-#      for that attribute, the request is permitted to continue.  If
-#      the section has and entry which says "deny" for that
-#      attribute, the request is immediately rejected.
-#
-#      The default (if the attribute is not listed in the subsection)
-#      is to permit the attribute.
-#
-#      The attribute names MUST be spelled the same way as in
-#      the dictionary files.
-#
-#      The entries can have sub-sections, too.  Each subsection
-#      MUST begin with a "key" entry, which is used to apply
-#      one of the rules in the subsection.  Only one rule from
-#      each subsection is applied, and that rule is the one pointed
-#      to by the key.  The key is dynamically expanded (see doc/variables.txt)
-#      at run time, for each request as it comes in.
-#
-DEFAULT {
-       #
-       #  There is no key here, as the key is always hard-coded to be
-       #  attributes in the request.  For a request to pass the tests
-       #  in this section, ALL of the rules below must permit the
-       #  request to pass.  That is, the rules are logically ANDed
-       #  together.
-       #
-
-       # allow requests to contain a user password attribute.
-       User-Password = permit
-
-       # Deny requests which try to use MS-CHAP, for testing.
-       # just because we can.  Both MS-CHAPv1 and MS-CHAPv2
-       # use MS-CHAP-Challenge, so we just deny that.
-       # If we wanted to deny just MS-CHAPv2, we would deny the
-       # MS-CHAP2-Response attribute.
-       MS-CHAP-Challenge = deny
-
-       #
-       #  Allow some EAP protocols, but not others.
-       #
-       #  The use of the EAP-Type for the key, below, means that the
-       #  protocol_filter module MUST be listed after "eap" in the
-       #  "authorize" section.
-       #
-       EAP-Message {
-               #
-               #  See the dictionary for the names of the EAP-Types.
-               #  e.g. VALUE EAP-Type <name> <number>
-               #
-               #  The names for the EAP types MUST be exactly the same
-               #  as the names in the dictionary file.
-               #
-               key = %{EAP-Type:-DEFAULT}
-
-               #  This is insecure, so we don't allow it.
-               MD5-Challenge = deny
-
-               # Permit one EAP type.  We picked this one at random.
-               EAP-MSCHAP-V2 = permit          
-
-               DEFAULT = deny
-       }
-}
-
-#
-#  A more complicated example.
-#
-example.com {
-       #
-       #  For various reasons, we often would like to use the same
-       #  configuration entries inside, and outside of the TLS tunnel.
-       #  This allows us to keep all of the per-realm configuration in
-       #  one place.
-       #
-       EAP-Message {
-               #
-               #  Define subsections, based on the request being
-               #  inside, or outside, of the TLS tunnel.
-               #
-               key = %{FreeRADIUS-Proxied-To:-Outer}
-
-               #
-               #  Outside of the tunnel.
-               #
-               Outer {
-                       key = %{EAP-Type:-DEFAULT}
-
-                       #  This is insecure, so we don't allow it.
-                       #  It's not necessary, as the DEFAULT below will
-                       #  take care of it, but this is a good example.
-                       MD5-Challenge = deny
-
-                       # We allow TTLS & PEAP as EAP types.
-                       EAP-TTLS = permit
-
-                       PEAP = permit
-
-                       DEFAULT = deny
-               }
-
-               #
-               #  Inside of the tunnel.
-               #
-               127.0.0.1 {
-                       key = %{EAP-Type:-DEFAULT}
-
-                       #  We don't do TLS inside of TTLS.
-                       EAP-TLS = deny
-
-                       DEFAULT = permit
-               }
-       }
-}
index a6e4d93..032b7a0 100644 (file)
 #  to which it sends proxy requests.
 #
 proxy server {
-       #
-       #  Note that as of 2.0, the "synchronous", "retry_delay",
-       #  "retry_count", and "dead_time" have all been deprecated.
-       #  For backwards compatibility, they are are still accepted
-       #  by the server, but they ONLY apply to the old-style realm
-       #  configuration.  i.e. realms with "authhost" and/or "accthost"
-       #  entries.
-       #
-       #  i.e. "retry_delay" and "retry_count" have been replaced
-       #  with per-home-server configuration.  See the "home_server"
-       #  example below for details.
-       #
-       #  i.e. "dead_time" has been replaced with a per-home-server
-       #  "revive_interval".  We strongly recommend that this not
-       #  be used, however.  The new method is much better.
 
-       #
-       #  In 2.0, the server is always "synchronous", and setting
-       #  "synchronous = no" is impossible.  This simplifies the
-       #  server and increases the stability of the network.
-       #
-       #  If you need to set "synchronous = no", please send a
-       #  message to the list <freeradius-users@lists.freeradius.org>
-       #  explaining why this feature is vital for your network.
-
-       #
-       #  If a realm exists, but there are no live home servers for
-       #  it, we can fall back to using the "DEFAULT" realm.  This is
-       #  most useful for accounting, where the server can proxy
-       #  accounting requests to home servers, but if they're down,
-       #  use a DEFAULT realm that is LOCAL (i.e. accthost = LOCAL),
-       #  and then store the packets in the "detail" file.  That data
-       #  can be later proxied to the home servers by radrelay, when
-       #  those home servers come back up again.       
-
-       #  Setting this to "yes" may have issues for authentication.
-       #  i.e. If you are proxying for two different ISP's, and then
-       #  act as a general dial-up for Gric.  If one of the first two
-       #  ISP's has their RADIUS server go down, you do NOT want to
-       #  proxy those requests to GRIC.  Instead, you probably want
-       #  to just drop the requests on the floor.  In that case, set
-       #  this value to 'no'.
-       #
-       #  allowed values: {yes, no}
-       #
-       default_fallback = no
+#
+#  If the NAS re-sends the request to us, we can immediately re-send
+#  the proxy request to the end server.  To do so, use 'yes' here.
+#
+#  If this is set to 'no', then we send the retries on our own schedule,
+#  and ignore any duplicate NAS requests.
+#
+#  If you want to have the server send proxy retries ONLY when the NAS
+#  sends it's retries to the server, then set this to 'yes', and
+#  set the other proxy configuration parameters to 0 (zero).
+#
+#  Additionally, if you want 'failover' to work, the server must manage
+#  retries and timeouts.  Therefore, if this is set to yes, then no
+#  failover functionality is possible.
+#
+       synchronous = no
 
-}
+#
+#  The time (in seconds) to wait for a response from the proxy, before
+#  re-sending the proxied request.
+#
+#  If this time is set too high, then the NAS may re-send the request,
+#  or it may give up entirely, and reject the user.
+#
+#  If it is set too low, then the RADIUS server which receives the proxy
+#  request will get kicked unnecessarily.
+#
+       retry_delay = 5
 
-#######################################################################
 #
-#  Configuration for the proxy realms.
+#  The number of retries to send before giving up, and sending a reject
+#  message to the NAS.
 #
-#  As of 2.0. the old-style "realms" file is deprecated, and is not
-#  used by FreeRADIUS.
+       retry_count = 3
+
 #
-#  As of 2.0, the "realm" configuration has changed.  Instead of
-#  specifying "authhost" and "accthost" in a realm section, the home
-#  servers are specified seperately in a "home_server" section.  For
-#  backwards compatibility, you can still use the "authhost" and
-#  "accthost" directives.  If you only have one home server for a
-#  realm, it is easier to use the old-style configuration.
+#  If the home server does not respond to any of the multiple retries,
+#  then FreeRADIUS will stop sending it proxy requests, and mark it 'dead'.
 #
-#  However, if you have multiple servers for a realm, we STRONGLY
-#  suggest moving to the new-style configuration.
+#  If there are multiple entries configured for this realm, then the
+#  server will fail-over to the next one listed.  If no more are listed,
+#  then no requests will be proxied to that realm.
 #
 #
-#  Load-balancing and failover between home servers is handled via
-#  a "server_pool" section.
+#  After a configurable 'dead_time', in seconds, FreeRADIUS will
+#  speculatively mark the home server active, and start sending requests
+#  to it again.
 #
-#  Finally, The "realm" section defines the realm, some options, and
-#  indicates which server pool should be used for the realm.
+#  If this dead time is set too low, then you will lose requests,
+#  as FreeRADIUS will quickly switch back to the home server, even if
+#  it isn't up again.
 #
-#  This change means that simple configurations now require multiple
-#  ssections to define a realm.  However, complex configurations
-#  are much simpler than before, as multiple realms can share the same
-#  server pool.
+#  If this dead time is set too high, then FreeRADIUS may take too long
+#  to switch back to the primary home server.
 #
-#  That is, realms point to server pools, and server pools point to
-#  home servers.  Multiple realms can point to one server pool.  One
-#  server pool can point to multiple home servers.  Each home server
-#  can appear in one or more pools.
+#  Realistic values for this number are in the range of minutes to hours.
+#  (60 to 3600)
 #
+       dead_time = 120
 
-######################################################################
-#
-#  This section defines a "Home Server" which is another RADIUS
-#  server that gets sent proxied requests.  In earlier versions
-#  of FreeRADIUS, home servers were defined in "realm" sections,
-#  which was awkward.  In 2.0, they have been made independent
-#  from realms, which is better for a number of reasons.
-#
-home_server localhost {
-       #
-       #  Home servers can be sent Access-Request packets
-       #  or Accounting-Request packets.
-       #
-       #  Allowed values are:
-       #       auth      - Handles Access-Request packets
-       #       acct      - Handles Accounting-Request packets
-       #       auth+acct - Handles Access-Request packets at "port",
-       #                   and Accounting-Request packets at "port + 1"
-       type = auth
-
-       #
-       #  Configure ONE OF the following three entries:
-       #
-       #       IPv4 address
-       #
-       ipaddr = 127.0.0.1
-
-       #       OR IPv6 address
-       # ipv6addr = ::1
-
-       #       OR hostname, which will do address detection automatically
-       #
-       #       Note that we do NOT recommend using hostnames, because
-       #       it means that the server has to do a DNS lookup to
-       #       determine the IP address of the home server.  If the
-       #       DNS server is slow or unresponsible, it means that
-       #       FreeRADIUS will NOT be able to determine the IP
-       #       address, and will therefore NOT start.
-       #
-       # hostname = localhost
-
-       #
-       #  The port to which packets are sent.
-       #
-       #  Usually 1812 for type "auth", and  1813 for type "acct".
-       #  Older servers may use 1645 and 1646.
-       #
-       port = 1812
-
-       #
-       #  The shared secret use to "encrypt" and "sign" packets between
-       #  FreeRADIUS and the home server.
-       #
-       #  The secret can be any string, up to 8k characters in length.
-       #
-       #  Control codes can be entered vi octal encoding,
-       #       e.g. "\101\102" == "AB"
-       #  Quotation marks can be entered by escaping them,
-       #       e.g. "foo\"bar"
-       #  Spaces or other "special" characters can be entered
-       #  by putting quotes around the string.
-       #       e.g. "foo bar"
-       #            "foo;bar"
-       #
-       secret = testing123
-
-       ############################################################
-       #
-       #  The rest of the configuration items listed here are optional,
-       #  and do not have to appear in every home server definition.
-       #
-       ############################################################
-
-       #
-       #  If the home server doesn't respond to the request within
-       #  this time, this server will consider the request dead, and
-       #  respond to the NAS with an Access-Reject.
-       #
-       #  Useful range of values: 5 to 60
-       response_window = 20
-
-       #
-       #  If the home server does not respond to ANY packets for
-       #  a certain time, consider it dead.  This time period is
-       #  called the "zombie" period, because the server is neither
-       #  alive nor dead.
-       #
-       #  Useful range of values: 20 to 120
-       zombie_period = 40
-
-       ############################################################
-       #
-       #  As of 2.0, FreeRADIUS supports RADIUS layer "status
-       #  checks".  These are used by a proxy server to see if a home
-       #  server is alive.
-       #
-       #  These status packets are sent ONLY if the proxying server
-       #  believes that the home server is dead.  They are NOT sent
-       #  if the proxying server believes that the home server is
-       #  alive.  They are NOT sent if the proxying server is not
-       #  proxying packets.
-       #
-       #  If the home server responds to the status check packet,
-       #  then it is marked alive again, and is returned to use.
-       #
-       ############################################################
-
-       #
-       #  Some home servers do not support status checks via the
-       #  Status-Server packet.  Others may not have a "test" user
-       #  configured that can be used to query the server, to see if
-       #  it is alive.  For those servers, we have NO WAY of knowing
-       #  when it becomes alive again.  Therefore, after the server
-       #  has been marked dead, we wait a period of time, and mark
-       #  it alive again, in the hope that it has come back to
-       #  life.
-       #
-       #  If it has NOT come back to life, then FreeRADIUS will wait
-       #  for "zombie_period" before marking it dead again.  During
-       #  the "zombie_period", ALL AUTHENTICATIONS WILL FAIL, because
-       #  the home server is still dead.  There is NOTHING that can
-       #  be done about this, other than to enable the status checks,
-       #  as documented below.
-       #
-       #  e.g. if "zombie_period" is 40 seconds, and "revive_interval"
-       #  is 300 seconds, the for 40 seconds out of every 340, or about
-       #  10% of the time, all authentications will fail.
-       #
-       #  If the "zombie_period" and "revive_interval" configurations
-       #  are set smaller, than it is possible for up to 50% of
-       #  authentications to fail.
-       #
-       #  As a result, we recommend enabling status checks, and
-       #  we do NOT recommend using "revive_interval".
-       #
-       #  If the "status_check" entry below is not "none", then the
-       #  "revive_interval" entry can be deleted, as it will not be
-       #  used.
-       #
-       #  Useful range of values: 60 to 3600
-       revive_interval = 120
+#  An ldflag attribute for all realms to be included in a round-robin 
+#  setup must be specified, and that ldflag must be the same for all
+#  realms of the same name.
+#  Currently (0 or fail_over) and (1 or round_robin) are the 
+#  supported values for ldflag.  Fail over is the default setup.
+#
+#  DO NOT INCLUDE LOCAL AUTH/ACCT HOST REALMS IN A ROUND-ROBIN QUEUE.
 
-       #
-       #  The proxying server (i.e. this one) can do periodic status
-       #  checks to see if a dead home server has come back alive.
-       #
-       #  If set to "none", then the other configuration items listed
-       #  below are not used, and the "revive_interval" time is used
-       #  instead.
-       #
-       #  If set to "status-server", the Status-Server packets are
-       #  sent.  Many RADIUS servers support Status-Server.  If a
-       #  server does not support it, please contact the server
-       #  vendor and request that they add it.
-       #
-       #  If set to "request", then Access-Request, or Accounting-Request
-       #  packets are sent, depending on the "type" entry above (auth/acct).
-       #  
-       #  Allowed values: none, status-server, request
-       status_check = status-server
 
-       #
-       #  If the home server does not support Status-Server packets,
-       #  then the server can still send Access-Request or
-       #  Accounting-Request packets, with a pre-defined user name.
-       #
-       #  This practice is NOT recommended, as it may potentially let
-       #  users gain network access by using these "test" accounts!
-       #
-       #  If it is used, we recommend that the home server ALWAYS
-       #  respond to these Access-Request status checks with
-       #  Access-Reject.  The status check just needs an answer, it
-       #  does not need an Access-Accept.
-       #
-       #  For Accounting-Request status checks, only the username
-       #  needs to be set.  The rest of the accounting attribute are
-       #  set to default values.  The home server that receives these
-       #  accounting packets SHOULD NOT treat them like normal user
-       #  accounting packets.  i.e It should probably NOT log them to
-       #  a database.
-       #
-       # username = "test_user_please_reject_me"
-       # password = "this is really secret"
+#
+#  If all exact matching realms did not respond, we can try the
+#  DEFAULT realm, too.  This is what the server normally does.
+#
+#  This behaviour may be undesired for some cases.  e.g. You are proxying
+#  for two different ISP's, and then act as a general dial-up for Gric.
+#  If one of the first two ISP's has their RADIUS server go down, you do
+#  NOT want to proxy those requests to GRIC.  Instead, you probably want
+#  to just drop the requests on the floor.  In that case, set this value
+#  to 'no'.
+#
+#  allowed values: {yes, no}
+#
+       default_fallback = yes
 
-       #
-       #  Configure the interval between sending status check packets.
-       #
-       #  Setting it too low increases the probability of spurious
-       #  fail-over and fallback attempts.
-       #
-       #  Useful range of values: 6 to 120
-       check_interval = 30
+#
+#  Older versions of the server would pass proxy requests through the
+#  'authorize' sections twice; once when the packet was received
+#  from the NAS, and again after the reply was received from the home
+#  server.  Now that we have a 'post_proxy' section, the replies from
+#  the home server should be sent through that, instead of through
+#  the 'authorize' section again.
+#
+#  However, for backwards compatibility, this behaviour is configurable.
+#  The default configuration is 'no', because this option is deprecated
+#  and will be removed in the future.
+#
+#  allowed values: {yes, no}
+#
+       post_proxy_authorize = no
 
-       #
-       #  Configure the number of status checks in a row that the
-       #  home server needs to respond to before it is marked alive.
-       #
-       #  If you want to mark a home server as alive after a short
-       #  time period of being responsive, it is best to use a small
-       #  "check_interval", and a large value for
-       #  "num_answers_to_alive".  Using a long "check_interval" and
-       #  a small number for "num_answers_to_alive" increases the
-       #  probability of spurious fail-over and fallback attempts.
-       #
-       #  Useful range of values: 3 to 10
-       num_answers_to_alive = 3
 }
 
+#######################################################################
+#
+#  Configuration for the proxy realms.
+#
+#  The information given here is used in conjunction with the 'realms'
+#  file.  This format is preferred, as it is more flexible.  The realms
+#  listed here take priority over those listed in the 'realms' file.
 
-######################################################################
-#
-#  This section defines a pool of home servers that is used
-#  for fail-over and load-balancing.  In earlier versions of
-#  FreeRADIUS, fail-over and load-balancing were defined per-realm.
-#  As a result, if a server had 5 home servers, each of which served
-#  the same 10 realms, you would need 50 "realm" entries.
-#
-#  In version 2.0, you would need 5 "home_server" sections,
-#  10 'realm" sections, and one "server_pool" section to tie the
-#  two together.
-#
-server_pool my_auth_failover {
-       #
-       #  The type of this pool controls how home servers are chosen.
-       #
-       #  fail-over - the request is sent to the first live
-       #       home server in the list.  i.e. If the first home server
-       #       is marked "dead", the second one is chosen, etc.
-       #
-       #  load-balance - the least busy home server is chosen,
-       #       where "least busy" is counted by taking the number of
-       #       requests sent to that home server, and subtracting the
-       #       number of responses received from that home server.
-       #
-       #       If there are two or more servers with the same low
-       #       load, then one of those servers is chosen at random.
-       #       This configuration is most similar to the old
-       #       "round-robin" method, though it is not exactly the same.
-       #
-       #       Note that load balancing does not work well with EAP,
-       #       as EAP requires packets for an EAP conversation to be
-       #       sent to the same home server.  The load balancing method
-       #       does not keep state in between packets, meaning that
-       #       EAP packets for the same conversation may be sent to
-       #       different home servers.  This will prevent EAP from
-       #       working.
-       #
-       #       For non-EAP authentication methods, and for accounting
-       #       packets, we recommend using "load-balance".  It will
-       #       ensure the highest availability for your network.
-       #
-       #  client-balance - the home server is chosen by hashing the
-       #       source IP address of the packet.  If that home server
-       #       is down, the next one in the list is used, just as
-       #       with "fail-over".
-       #
-       #       There is no way of predicting which source IP will map
-       #       to which home server.
-       #
-       #       This configuration is most useful to do simple load
-       #       balancing for EAP sessions, as the EAP session will
-       #       always be sent to the same home server.
-       #
-       #  client-port-balance - the home server is chosen by hashing
-       #       the source IP address and source port of the packet.
-       #       If that home server is down, the next one in the list
-       #       is used, just as with "fail-over".
-       #
-       #       This method provides slightly better load balancing
-       #       for EAP sessions than "client-balance".  However, it
-       #       also means that authentication and accounting packets
-       #       for the same session MAY go to different home servers.
-       #
-       type = fail-over
-
-       #
-       #  Next, a list of one or more home servers.  The names
-       #  of the home servers are NOT the hostnames, but the names
-       #  of the sections.  (e.g. home_server foo {...} has name "foo".
-       #
-       #  Note that ALL home servers listed here have to be of the same
-       #  type.  i.e. they all have to be "auth", or they all have to
-       #  be "acct", or the all have to be "auth+acct".
-       #
-       home_server = localhost
-
-       #  Additional home servers can be listed.
-       #  There is NO LIMIT to the number of home servers that can
-       #  be listed, though using more than 10 or so will become
-       #  difficult to manage.
-       #
-       # home_server = foo.example.com
-       # home_server = bar.example.com
-       # home_server = baz.example.com
-       # home_server = ...
-}
+#  A standard realm entry. A request from "user@company.com" will be
+#  sent to radius.company.com as "user", unless the 'nostrip'
+#  configuration item is specified.  If the 'nostrip' configuration
+#  item is specified, then the request will be proxied as
+#  "user@company.com"
+#
+#realm company.com {
+#      type            = radius
+#      authhost        = radius.company.com:1600
+#      accthost        = radius.company.com:1601
+#      secret          = testing123
+#}
 
-######################################################################
+#  A realm entry with an optional fail-over realm.  A request from
+#  "user@isp2.com" will be sent to radius.isp2.com as "user@isp2.com",
+#  because the 'nostrip' directive is specified for this realm.
 #
+#realm isp2.com {
+#      type        = radius
+#      authhost    = radius.isp2.com:1645
+#      accthost    = radius.isp2.com:1646
+#      secret      = TheirKey
+#      nostrip
+#}
 #
-#  This section defines a new-style "realm".  Note the in version 2.0,
-#  there are many fewer configuration items than in 1.x for a realm.
+#  The fail-over realm for isp2.com
 #
-#  Automatic proxying is done via the "realms" module (see "man
-#  rlm_realm").  To manually proxy the request put this entry in the
-#  "users" file:
+#realm isp2.com {
+#      type        = radius
+#      authhost    = radius2.isp2.com:1645
+#      accthost    = radius2.isp2.com:1646
+#      secret      = TheirKey2
+#      nostrip
+#}
 
 #
+#  1st node serv.com...set up for round-robin.
 #
-#DEFAULT       Proxy-To-Realm := "realm_name"
+#  The load balancing 'ldflag' attribute can be used to perform
+#  load balancing.  Allowed values are 'fail_over' and 'round_robin'.
 #
+#  If there is no ldflag attribute, or it is set to 'fail_over', then
+#  the realms are treated as "fail-over".  That is, the first matching
+#  realm is used, unless it is down, in which case the realm "fails
+#  over" to the second matching realm.  The process continues until an
+#  active matching realm is found, OR the DEFAULT realm is returned.
 #
-realm example.com {
-       #
-       #  Realms point to pools of home servers.
+#  If the ldflag attribute is set to 'round_robin', then all active
+#  realms of the same name are put into a pool internally in the
+#  server, and the proxied requests are evenly divided among the
+#  realms in the pool.  For this to work, all realms of the same name
+#  MUST have the same value of their 'ldflag' attributes.  Mixing up
+#  different types of load balancing schemes for the same realm will
+#  cause problems.
 #
-       #  For authentication, the "auth_pool" configuration item
-       #  should point to a "server_pool" that was previously
-       #  defined.  All of the home servers in the "auth_pool" must
-       #  be of type "auth".
-       #
-       #  For accounting, the "acct_pool" configuration item
-       #  should point to a "server_pool" that was previously
-       #  defined.  All of the home servers in the "acct_pool" must
-       #  be of type "acct".
-       #
-       #  If you have a "server_pool" where all of the home servers
-       #  are of type "auth+acct", you can just use the "pool"
-       #  configuration item, instead of specifying both "auth_pool"
-       #  and "acct_pool".
-
-       auth_pool = my_auth_failover
-#      acct_pool = acct
+#  The round_robin load balancing method is a probabilistic method
+#  which evenly scatters the requests among the home servers.
+#
+#  Note that you CANNOT include local auth/acct host realms in a
+#  round-robin queue.  Having a server load balance requests to itself
+#  doesn't make any sense, as it only doubles the amount of work
+#  which is needed to be done.
+#
+#realm serv.com {
+#      type        = radius
+#      authhost    = radius.serv.com:1645
+#      accthost    = radius.serv.com:1646
+#      secret      = TheirKey
+#      ldflag      = round_robin
+#      nostrip
+#}
 
-       #
-       #  Normally, when an incoming User-Name is matched against the
-       #  realm, the realm name is "stripped" off, and the "stripped"
-       #  user name is used to perform matches.
-       #
-       #  e.g. User-Name = "bob@example.com" will result in two new
-       #  attributes being created by the "realms" module:
-       #
-       #       Stripped-User-Name = "bob"
-       #       Realm = "example.com"
-       #
-       #  The Stripped-User-Name is then used as a key in the "users"
-       #  file, for example.
-       #
-       #  If you do not want this to happen, uncomment "nostrip" below.
-       #
-       # nostrip
+#
+#  Another node for serv.com
+#
+#realm serv.com {
+#      type        = radius
+#      authhost    = radius2.serv.com:1645
+#      accthost    = radius2.serv.com:1646
+#      secret      = TheirKey2
+#      ldflag      = round_robin
+#      nostrip
+#}
 
-       #  There are no more configuration entries for a realm.
-}
+#
+#  A third round-robin node realm for serv.com
+#
+#realm serv.com {
+#      type        = radius
+#      authhost    = radius3.serv.com:1645
+#      accthost    = radius3.serv.com:1646
+#      secret      = TheirKey2
+#      ldflag      = round_robin
+#      nostrip
+#}
+#
+#
 
+#
+#  This is a local realm.  The requests are NOT proxied,
+#  but instead are authenticated by the RADIUS server itself.
+#
+#  You don't need a secret if BOTH 'authhost' and 'accthost' are
+#  set to LOCAL.
+#
+#realm bla.com {
+#      type            = radius
+#      authhost        = LOCAL
+#      accthost        = LOCAL
+#}
 
 #
 #  This is a sample entry for iPass.
-#  Note that you have to define "ipass_auth_pool" and
-#  "ipass_acct_pool", along with home_servers for them, too.
 #
 #realm IPASS {
-#      nostrip
+#      type            = radius
+#      authhost        = ipass.server.hostname:11812
+#      accthost        = ipass.server.hostname:11813
 #
-#      auth_pool = ipass_auth_pool
-#      acct_pool = ipass_acct_pool
+       #  The shared secret here must be the same
+       #  value as the secret of the NetServer found in the
+       #  /usr/ipass/raddb/clients file of your NetServer software.
+#      secret          = mysecret
+#      nostrip
 #}
 
 #
@@ -476,8 +261,9 @@ realm example.com {
 #  DEFAULT EAP-Type == PEAP, Proxy-To-Realm := LOCAL
 #
 realm LOCAL {
-       #  If we do not specify a server pool, the realm is LOCAL, and
-       #  requests are not proxied to it.
+       type            = radius
+       authhost        = LOCAL
+       accthost        = LOCAL
 }
 
 #
@@ -500,4 +286,3 @@ realm LOCAL {
 #      accthost        = radius.company.com:1601
 #      secret          = testing123
 #}
-
index c3ab132..87ce019 100644 (file)
@@ -40,19 +40,6 @@ run_dir = ${localstatedir}/run/radiusd
 log_file = ${logdir}/radius.log
 
 #
-#  Destination for log messages.  This can be one of:
-#
-#      files - log to ${log_file}, as defined above.
-#      syslog - to syslog (see also the log{} section, below)
-#      stdout - standard output
-#      stderr - standard error.
-#
-#  The command-line option "-X" over-rides this option, and forces
-#  logging to go to stdout.
-#
-log_destination = files
-
-#
 # libdir: Where to find the rlm_* modules.
 #
 #   This should be automatically set at configuration time.
@@ -140,6 +127,15 @@ pidfile = ${run_dir}/radiusd.pid
 #
 max_request_time = 30
 
+#  delete_blocked_requests: If the request takes MORE THAN 'max_request_time'
+#  to be handled, then maybe the server should delete it.
+#
+#  If you're running in threaded, or thread pool mode, this setting
+#  should probably be 'no'.  Setting it to 'yes' when using a threaded
+#  server MAY cause the server to crash!
+#
+delete_blocked_requests = no
+
 #  cleanup_delay: The time to wait (in seconds) before cleaning up
 #  a reply which was sent to the NAS.
 #
@@ -178,83 +174,78 @@ cleanup_delay = 5
 #
 max_requests = 1024
 
-#  listen: Make the server listen on a particular IP address, and send
-#  replies out from that address. This directive is most useful for
-#  hosts with multiple IP addresses on one interface.
+#  bind_address:  Make the server listen on a particular IP address, and
+#  send replies out from that address.  This directive is most useful
+#  for machines with multiple IP addresses on one interface.
+#
+#  It can either contain "*", or an IP address, or a fully qualified
+#  Internet domain name.  The default is "*"
+#
+#  As of 1.0, you can also use the "listen" directive.  See below for
+#  more information.
+#
+bind_address = *
+
+#  port: Allows you to bind FreeRADIUS to a specific port.
+#
+#  The default port that most NAS boxes use is 1645, which is historical.
+#  RFC 2138 defines 1812 to be the new port.  Many new servers and
+#  NAS boxes use 1812, which can create interoperability problems.
 #
-#  If you want the server to listen on additional addresses, or on
-#  additionnal ports, you can use multiple "listen" sections.
+#  The port is defined here to be 0 so that the server will pick up
+#  the machine's local configuration for the radius port, as defined
+#  in /etc/services.
 #
-#  Each section make the server listen for only one type of packet,
-#  therefore authentication and accounting have to be configured in
-#  different sections.
+#  If you want to use the default RADIUS port as defined on your server,
+#  (usually through 'grep radius /etc/services') set this to 0 (zero).
 #
-#  The server ignore all "listen" section if you are using '-i' and '-p'
-#  on the command line.
+#  A port given on the command-line via '-p' over-rides this one.
 #
-listen {
+#  As of 1.0, you can also use the "listen" directive.  See below for
+#  more information.
+#
+port = 0
+
+#
+#  By default, the server uses "bind_address" to listen to all IP's
+#  on a machine, or just one IP.  The "port" configuration is used
+#  to select the authentication port used when listening on those
+#  addresses.
+#
+#  If you want the server to listen on additional addresses, you can
+#  use the "listen" section.  A sample section (commented out) is included
+#  below.  This "listen" section duplicates the functionality of the
+#  "bind_address" and "port" configuration entries, but it only listens
+#  for authentication packets.
+#
+#  If you comment out the "bind_address" and "port" configuration entries,
+#  then it becomes possible to make the server accept only accounting,
+#  or authentication packets.  Previously, it always listened for both
+#  types of packets, and it was impossible to make it listen for only
+#  one type of packet.
+#
+#listen {
        #  IP address on which to listen.
        #  Allowed values are:
        #       dotted quad (1.2.3.4)
        #       hostname    (radius.example.com)
        #       wildcard    (*)
-       ipaddr = *
-
-       #  OR, you can use an IPv6 address, but not both
-       #  at the same time.
-#      ipv6addr = ::   # any.  ::1 == localhost
+#      ipaddr = *
 
        #  Port on which to listen.
        #  Allowed values are:
        #       integer port number (1812)
        #       0 means "use /etc/services for the proper port"
-       port = 0
+#      port = 0
 
        #  Type of packets to listen for.
        #  Allowed values are:
        #       auth    listen for authentication packets
        #       acct    listen for accounting packets
        #
-       type = auth
-
-       #  Some systems support binding to an interface, in addition
-       #  to the IP address.  This feature isn't strictly necessary,
-       #  but for sites with many IP addresses on one interface,
-       #  it's useful to say "listen on all addresses for eth0".
-       #
-       #  If your system does not support this feature, you will
-       #  get an error if you try to use it.
-       #
-#      interface = eth0
-
-       #  Per-socket lists of clients.  This is a very useful feature.
-       #
-       #  The name here is a reference to a section elsewhere in
-       #  radiusd.conf, or clients.conf.  Having the name as
-       #  a reference allows multiple sockets to use the same
-       #  set of clients.
-       #
-       #  If this configuration is used, then the global list of clients
-       #  is IGNORED for this "listen" section.  Take care configuring
-       #  this feature, to ensure you don't accidentally disable a
-       #  client you need.
-       #
-       #  See clients.conf for the configuration of "per_socket_clients".
-       #
-#      clients = per_socket_clients
-}
+#      type = auth
+#}
 
-#  This second "listen" section is for listening on the accounting
-#  port, too.
-#
-listen {
-       ipaddr = *
-#      ipv6addr = ::
-       port = 0
-       type = acct
-#      interface = eth0
-#      clients = per_socket_clients
-}
 
 #  hostname_lookups: Log the names of clients or just their IP addresses
 #  e.g., www.freeradius.org (on) or 206.47.27.232 (off).
@@ -292,20 +283,6 @@ allow_core_dumps = no
 regular_expressions    = @REGEX@
 extended_expressions   = @REGEX_EXTENDED@
 
-#
-#  Logging section.  The various "log_*" configuration items
-#  will eventually be moved here.
-#
-log {
-       #
-       #  Which syslog facility to use, if ${log_destination} == "syslog"
-       #
-       #  The exact values permitted here are OS-dependent.  You probably
-       #  don't want to change this.
-       #
-       syslog_facility = daemon
-}
-
 #  Log the full User-Name attribute, as it was found in the request.
 #
 # allowed values: {no, yes}
@@ -327,6 +304,54 @@ log_auth = no
 log_auth_badpass = no
 log_auth_goodpass = no
 
+# usercollide:  Turn "username collision" code on and off.  See the
+# "doc/duplicate-users" file
+#
+#  WARNING
+#  !!!!!!!  Setting this to "yes" may result in the server behaving
+#  !!!!!!!  strangely.  The "username collision" code will ONLY work
+#  !!!!!!!  with clear-text passwords.  Even then, it may not do what
+#  !!!!!!!  you want, or what you expect.
+#  !!!!!!!
+#  !!!!!!!  We STRONGLY RECOMMEND that you do not use this feature,
+#  !!!!!!!  and that you find another way of acheiving the same goal.
+#  !!!!!!!
+#  !!!!!!!  e,g. module fail-over.  See 'doc/configurable_failover'
+#  WARNING
+#
+usercollide = no
+
+# lower_user / lower_pass:  
+# Lower case the username/password "before" or "after"
+# attempting to authenticate.  
+#
+#  If "before", the server will first modify the request and then try
+#  to auth the user.  If "after", the server will first auth using the
+#  values provided by the user.  If that fails it will reprocess the
+#  request after modifying it as you specify below.
+#
+#  This is as close as we can get to case insensitivity.  It is the
+#  admin's job to ensure that the username on the auth db side is
+#  *also* lowercase to make this work
+#
+# Default is 'no' (don't lowercase values)
+# Valid values = "before" / "after" / "no"
+#
+lower_user = no
+lower_pass = no
+
+# nospace_user / nospace_pass:
+#
+#  Some users like to enter spaces in their username or password
+#  incorrectly.  To save yourself the tech support call, you can
+#  eliminate those spaces here:
+#
+# Default is 'no' (don't remove spaces)
+# Valid values = "before" / "after" / "no" (explanation above)
+#
+nospace_user = no
+nospace_pass = no
+
 #  The program to execute to do concurrency checks.
 checkrad = ${sbindir}/checkrad
 
@@ -371,19 +396,17 @@ security {
        #  status_server: Whether or not the server will respond
        #  to Status-Server requests.
        #
-       #  When sent a Status-Server message, the server responds with
-       #  an Access-Accept or Accounting-Response packet.
+       #  Normally this should be set to "no", because they're useless.
+       #  See: http://www.freeradius.org/rfc/rfc2865.html#Keep-Alives
        #
-       #  This is mainly useful for administrators who want to "ping"
-       #  the server, without adding test users, or creating fake
-       #  accounting packets.
+       #  However, certain NAS boxes may require them. 
        #
-       #  It's also useful when a NAS marks a RADIUS server "dead".
-       #  The NAS can periodically "ping" the server with a Status-Server
-       #  packet.  If the server responds, it must be alive, and the
-       #  NAS can start using it for real requests.
+       #  When sent a Status-Server message, the server responds with
+       #  an Access-Accept packet, containing a Reply-Message attribute,
+       #  which is a string describing how long the server has been
+       #  running.
        #
-       status_server = yes
+       status_server = no
 }
 
 # PROXY CONFIGURATION
@@ -536,17 +559,22 @@ modules {
 
        # PAP module to authenticate users based on their stored password
        #
-       #  Supports multiple encryption/hash schemes.  See "man passwd"
-       #  for details.
-       #
-       #  The "auto_header" configuration item can be set to "yes".
-       #  In this case, the module will look inside of the User-Password
-       #  attribute for the headers {crypt}, {clear}, etc., and will
-       #  automatically create the attribute on the right-hand side,
-       #  with the correct value.  It will also automatically handle
-       #  Base-64 encoded data, hex strings, and binary data.
+       #  As of 1.1.4, the "encryption_scheme" configuration should
+       #  no longer be used.  For backwards compatibility, it will still
+       #  work as before, but we recommend that it is not used.
+       # 
+       #  The replacement is "auto_header = yes".
+       #  For backwards compatibility, the default is "auto_header = no",
+       #  but we recommend reviewing your use of the PAP module, based
+       #  on the documentation in "man rlm_pap".
+       #
+       #  The new capability in this module makes it MUCH easier to
+       #  configure the server for multiple crypt/hash schemes, AND
+       #  it supports more methods than before.  Please read "man rlm_pap"
+       #  for more detailed documentation.
+       #
        pap {
-               auto_header = no
+               auto_header = yes
        }
 
        # CHAP module
@@ -582,11 +610,45 @@ modules {
        # Unix /etc/passwd style authentication
        #
        unix {
-               #  As of 1.1.0, the Unix module no longer reads,
-               #  or caches /etc/passwd, /etc/shadow, or /etc/group.
-               #  If you wish to cache those files, see the passwd
-               #  module, above.
                #
+               #  Cache /etc/passwd, /etc/shadow, and /etc/group
+               #
+               #  The default is to NOT cache them.
+               #
+               #  For FreeBSD and NetBSD, you do NOT want to enable
+               #  the cache, as it's password lookups are done via a
+               #  database, so set this value to 'no'.
+               #
+               #  Some systems (e.g. RedHat Linux with pam_pwbd) can
+               #  take *seconds* to check a password, when th passwd
+               #  file containing 1000's of entries.  For those systems,
+               #  you should set the cache value to 'yes', and set
+               #  the locations of the 'passwd', 'shadow', and 'group'
+               #  files, below.
+               #
+               # allowed values: {no, yes}
+               cache = no
+
+               # Reload the cache every 600 seconds (10mins). 0 to disable.
+               cache_reload = 600
+
+               #
+               #  Define the locations of the normal passwd, shadow, and
+               #  group files.
+               #
+               #  'shadow' is commented out by default, because not all
+               #  systems have shadow passwords.
+               #
+               #  To force the module to use the system password functions,
+               #  instead of reading the files, leave the following entries
+               #  commented out.
+               #
+               #  This is required for some systems, like FreeBSD,
+               #  and Mac OSX.
+               #
+               #       passwd = /etc/passwd
+               #       shadow = /etc/shadow
+               #       group = /etc/group
 
                #
                #  The location of the "wtmp" file.
@@ -681,129 +743,74 @@ $INCLUDE ${confdir}/eap.conf
        #       
        ldap {
                server = "ldap.your.domain"
-               #identity = "cn=admin,o=My Org,c=UA"
-               #password = mypass
+               # identity = "cn=admin,o=My Org,c=UA"
+               # password = mypass
                basedn = "o=My Org,c=UA"
                filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"
-               #base_filter = "(objectclass=radiusprofile)"
-
-               #  How many connections to keep open to the LDAP server.
-               #  This saves time over opening a new LDAP socket for
-               #  every authentication request.
-               ldap_connections_number = 5
-
-               # seconds to wait for LDAP query to finish. default: 20
-               timeout = 4
-
-               #  seconds LDAP server has to process the query (server-side
-               #  time limit). default: 20
-               #
-               #  LDAP_OPT_TIMELIMIT is set to this value.
-               timelimit = 3
-
-               #
-               #  seconds to wait for response of the server. (network
-               #   failures) default: 10
-               #
-               #  LDAP_OPT_NETWORK_TIMEOUT is set to this value.
-               net_timeout = 1
-
-               #
-               #  This subsection configures the tls related items
-               #  that control how FreeRADIUS connects to an LDAP
-               #  server.  It contains all of the "tls_*" configuration
-               #  entries used in older versions of FreeRADIUS.  Those
-               #  configuration entries can still be used, but we recommend
-               #  using these.
-               #
-               tls {
-                       # Set this to 'yes' to use TLS encrypted connections
-                       # to the LDAP database by using the StartTLS extended
-                       # operation.
-                       #                       
-                       # The StartTLS operation is supposed to be
-                       # used with normal ldap connections instead of
-                       # using ldaps (port 689) connections
-                       start_tls = no
-
-                       # cacertfile    = /path/to/cacert.pem
-                       # cacertdir             = /path/to/ca/dir/
-                       # certfile              = /path/to/radius.crt
-                       # keyfile               = /path/to/radius.key
-                       # randfile              = /path/to/rnd
-
-                       #  Certificate Verification requirements.  Can be:
-                       #    "never" (don't even bother trying)
-                       #    "allow" (try, but don't fail if the cerificate
-                       #               can't be verified)
-                       #    "demand" (fail if the certificate doesn't verify.)
-                       #
-                       #       The default is "allow"
-                       # require_cert  = "demand"
-               }
+               # base_filter = "(objectclass=radiusprofile)"
+
+               # set this to 'yes' to use TLS encrypted connections
+               # to the LDAP database by using the StartTLS extended
+               # operation.
+               # The StartTLS operation is supposed to be used with normal
+               # ldap connections instead of using ldaps (port 689) connections
+               start_tls = no
+
+               # tls_cacertfile        = /path/to/cacert.pem
+               # tls_cacertdir         = /path/to/ca/dir/
+               # tls_certfile          = /path/to/radius.crt
+               # tls_keyfile           = /path/to/radius.key
+               # tls_randfile          = /path/to/rnd
+               # tls_require_cert      = "demand"
 
                # default_profile = "cn=radprofile,ou=dialup,o=My Org,c=UA"
                # profile_attribute = "radiusProfileDn"
-               access_attr = "dialupAccess"
+               access_attr = "dialupAccess"
 
                # Mapping of RADIUS dictionary attributes to LDAP
                # directory attributes.
                dictionary_mapping = ${raddbdir}/ldap.attrmap
 
-               #  Set password_attribute = nspmPassword to get the
-               #  user's password from a Novell eDirectory
-               #  backend. This will work ONLY IF FreeRADIUS has been
-               #  built with the --with-edir configure option.
+               ldap_connections_number = 5
+
+               #
+               # NOTICE: The password_header directive is NOT case insensitive
+               #
+               # password_header = "{clear}"
+               #
+               # Set:
+               #       password_attribute = nspmPassword
+               #
+               # to get the user's password from a Novell eDirectory
+               # backend. This will work *only if* freeRADIUS is
+               # configured to build with --with-edir option.
+               #
+               #
+               #  The server can usually figure this out on its own, and pull
+               #  the correct User-Password or NT-Password from the database.
+               #
+               #  Note that NT-Passwords MUST be stored as a 32-digit hex
+               #  string, and MUST start off with "0x", such as:
+               #
+               #       0x000102030405060708090a0b0c0d0e0f
+               #
+               #  Without the leading "0x", NT-Passwords will not work.
+               #  This goes for NT-Passwords stored in SQL, too.
                #
                # password_attribute = userPassword
-
-               #  As of 1.1.0, the LDAP module will auto-discover
-               #  the password headers (which are non-standard).
-               #  It will use the following table to map passwords
-               #  to RADIUS attributes.  The PAP module (see above)
-               #  can then automatically determine the hashing
-               #  method to use to authenticate the user.
-               #
-               #       Header          Attribute
-               #       ------          ---------
-               #       {clear}         User-Password
-               #       {cleartext}     User-Password
-               #       {md5}           MD5-Password
-               #       {smd5}          SMD5-Password
-               #       {crypt}         Crypt-Password
-               #       {sha}           SHA-Password
-               #       {ssha}          SSHA-Password
-               #       {nt}            NT-Password
-               #       {ns-mta-md5}    NS-MTA-MD5-Password
-               #               
-               #
-               #  The headers are compared in a case-insensitive manner.
-               #  The format of the password in LDAP (base 64-encoded, hex,
-               #  clear-text, whatever) is not that important.  The PAP
-               #  module will figure it out.
-               #
-               #  The default for "auto_header" is "no", to enable backwards
-               #  compatibility with the "password_header" directive,
-               #  which is now deprecated.  If this is set to "yes",
-               #  then the above table will be used, and the
-               #  "password_header" directive will be ignored.
-
-               #auto_header = yes
-
-               #  Un-comment the following to disable Novell
-               #  eDirectory account policy check and intruder
-               #  detection. This will work *only if* FreeRADIUS is
-               #  configured to build with --with-edir option.
-               #
-               edir_account_policy_check = no
-
-               #
-               #  Group membership checking.  Disabled by default.
+               #
+               # Un-comment the following to disable Novell eDirectory account
+               # policy check and intruder detection. This will work *only if*
+               # FreeRADIUS is configured to build with --with-edir option.
+               #
+               edir_account_policy_check=no
                #
                # groupname_attribute = cn
                # groupmembership_filter = "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"
                # groupmembership_attribute = radiusGroupName
-
+               timeout = 4
+               timelimit = 3
+               net_timeout = 1
                # compare_check_items = yes
                # do_xlat = yes
                # access_attr_used_for_allow = yes
@@ -814,24 +821,11 @@ $INCLUDE ${confdir}/eap.conf
                #  authentication, the LDAP module sets itself to do
                #  LDAP bind for authentication.
                #
-               #  THIS WILL ONLY WORK FOR PAP AUTHENTICATION.
-               #
-               #  THIS WILL NOT WORK FOR CHAP, MS-CHAP, or 802.1x (EAP). 
-               #
                #  You can disable this behavior by setting the following
                #  configuration entry to "no".
                #
                #  allowed values: {no, yes}
                # set_auth_type = yes
-
-               #  ldap_debug: debug flag for LDAP SDK
-               #  (see OpenLDAP documentation).  Set this to enable
-               #  huge amounts of LDAP debugging on the screen.
-               #  You should only use this if you are an LDAP expert.
-               #
-               #       default: 0x0000 (no debugging messages)
-               #       Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)
-               #ldap_debug = 0x0028 
        }
 
        # passwd module allows to do authorization via any passwd-like
@@ -852,6 +846,8 @@ $INCLUDE ${confdir}/eap.conf
        #
        #            Field marked as ',' may contain a comma separated list
        #            of attributes.
+       #   authtype - if record found this Auth-Type is used to authenticate
+       #            user
        #   hashsize - hashtable size. If 0 or not specified records are not
        #            stored in memory and file is red on every request.
        #   allowmultiplekeys - if few records for every key are allowed
@@ -866,6 +862,7 @@ $INCLUDE ${confdir}/eap.conf
        #passwd etc_smbpasswd {
        #       filename = /etc/smbpasswd
        #       format = "*User-Name::LM-Password:NT-Password:SMB-Account-CTRL-TEXT::"
+       #       authtype = MS-CHAP
        #       hashsize = 100
        #       ignorenislike = no
        #       allowmultiplekeys = no
@@ -891,10 +888,18 @@ $INCLUDE ${confdir}/eap.conf
        #  preacct sections.
        #
        #  Four config options:
-       #       format         -  must be "prefix" or "suffix"
-       #                         The special cases of "DEFAULT"
-       #                         and "NULL" are allowed, too.
+       #       format         -  must be 'prefix' or 'suffix'
        #       delimiter      -  must be a single character
+       #       ignore_default -  set to 'yes' or 'no'
+       #       ignore_null    -  set to 'yes' or 'no'
+       #
+       #  ignore_default and ignore_null can be set to 'yes' to prevent
+       #  the module from matching against DEFAULT or NULL realms.  This
+       #  may be useful if you have have multiple instances of the
+       #  realm module.
+       #
+       #  They both default to 'no'.
+       #
 
        #  'realm/username'
        #
@@ -902,6 +907,8 @@ $INCLUDE ${confdir}/eap.conf
        realm IPASS {
                format = prefix
                delimiter = "/"
+               ignore_default = no
+               ignore_null = no
        }
 
        #  'username@realm'
@@ -909,6 +916,8 @@ $INCLUDE ${confdir}/eap.conf
        realm suffix {
                format = suffix
                delimiter = "@"
+               ignore_default = no
+               ignore_null = no
        }
 
        #  'username%realm'
@@ -916,6 +925,8 @@ $INCLUDE ${confdir}/eap.conf
        realm realmpercent {
                format = suffix
                delimiter = "%"
+               ignore_default = no
+               ignore_null = no
        }
 
        #
@@ -924,6 +935,8 @@ $INCLUDE ${confdir}/eap.conf
        realm ntdomain {
                format = prefix
                delimiter = "\\"
+               ignore_default = no
+               ignore_null = no
        }       
 
        #  A simple value checking module
@@ -1052,11 +1065,6 @@ $INCLUDE ${confdir}/eap.conf
        # Livingston-style 'users' file
        #
        files {
-               # The default key attribute to use for matches.  The content
-               # of this attribute is used to match the "name" of the
-               # entry.
-               #key = "%{Stripped-User-Name:-%{User-Name}}"
-
                usersfile = ${confdir}/users
                acctusersfile = ${confdir}/acct_users
                preproxy_usersfile = ${confdir}/preproxy_users
@@ -1104,17 +1112,6 @@ $INCLUDE ${confdir}/eap.conf
                detailperm = 0600
 
                #
-               #  Every entry in the detail file has a header which
-               #  is a timestamp.  By default, we use the ctime
-               #  format (see "man ctime" for details).
-               #
-               #  The header can be customized by editing this
-               #  string.  See "doc/variables.txt" for a description
-               #  of what can be put here.
-               #
-               header = "%t"
-
-               #
                # Certain attributes such as User-Password may be
                # "sensitive", so they should not be printed in the
                # detail file.  This section lists the attributes
@@ -1125,7 +1122,6 @@ $INCLUDE ${confdir}/eap.conf
                #suppress {
                        # User-Password
                #}
-
        }
 
        #
@@ -1144,11 +1140,6 @@ $INCLUDE ${confdir}/eap.conf
                #  This MUST be 0600, otherwise anyone can read
                #  the users passwords!
                # detailperm = 0600
-
-               # You may also strip out passwords completely
-               #suppress {
-                       # User-Password
-               #}
        # }
 
        #
@@ -1162,6 +1153,9 @@ $INCLUDE ${confdir}/eap.conf
        # detail reply_log {
                # detailfile = ${radacctdir}/%{Client-IP-Address}/reply-detail-%Y%m%d
 
+               #
+               #  This MUST be 0600, otherwise anyone can read
+               #  the users passwords!
                # detailperm = 0600
        # }
 
@@ -1178,11 +1172,6 @@ $INCLUDE ${confdir}/eap.conf
                #  This MUST be 0600, otherwise anyone can read
                #  the users passwords!
                # detailperm = 0600
-
-               # You may also strip out passwords completely
-               #suppress {
-                       # User-Password
-               #}
        # }
 
        #
@@ -1194,6 +1183,9 @@ $INCLUDE ${confdir}/eap.conf
        # detail post_proxy_log {
                # detailfile = ${radacctdir}/%{Client-IP-Address}/post-proxy-detail-%Y%m%d
 
+               #
+               #  This MUST be 0600, otherwise anyone can read
+               #  the users passwords!
                # detailperm = 0600
        # }
 
@@ -1255,11 +1247,17 @@ $INCLUDE ${confdir}/eap.conf
        #  Include another file that has the SQL-related configuration.
        #  This is another file only because it tends to be big.
        #
+       #  The following configuration file is for use with MySQL.
+       #
+       #  For Postgresql, use:         ${confdir}/postgresql.conf
+       #  For MS-SQL, use:             ${confdir}/mssql.conf
+       #  For Oracle, use:             ${confdir}/oraclesql.conf
+       #
        $INCLUDE  ${confdir}/sql.conf
 
 
        #  For Cisco VoIP specific accounting with Postgresql,
-       #  use:         ${confdir}/sql/postgresql-voip-postpaid.conf
+       #  use:         ${confdir}/pgsql-voip.conf
        #
        #  You will also need the sql schema from:
        #        src/billing/cisco_h323_db_schema-postgres.sql
@@ -1333,42 +1331,18 @@ $INCLUDE ${confdir}/eap.conf
        # attr_filter - filters the attributes received in replies from
        # proxied servers, to make sure we send back to our RADIUS client
        # only allowed attributes.
-       attr_filter attr_filter.post-proxy {
+       attr_filter {
                attrsfile = ${confdir}/attrs
        }
 
-       # attr_filter - filters the attributes in the packets we send to
-       # the RADIUS home servers.
-       attr_filter attr_filter.pre-proxy {
-               attrsfile = ${confdir}/attrs.pre-proxy
-       }
-
-       # Enforce RFC requirements on the contents of Access-Reject
-       # packets.  See the comments at the top of the file for
-       # more details.
-       #
-       attr_filter attr_filter.access_reject {
-               key = %{User-Name}
-               attrsfile = ${confdir}/attrs.access_reject
-       }
-
-       #  Enforce RFC requirements on the contents of the
-       #  Accounting-Response packets.  See the comments at the
-       #  top of the file for more details.
-       #
-       attr_filter attr_filter.accounting_response {
-               key = %{User-Name}
-               attrsfile = ${confdir}/attrs.accounting_response
-       }
-
        #  counter module:
        #  This module takes an attribute (count-attribute).
        #  It also takes a key, and creates a counter for each unique
        #  key.  The count is incremented when accounting packets are
        #  received by the server.  The value of the increment depends
        #  on the attribute type.
-       #  If the attribute is Acct-Session-Time or of an integer type we add
-       #  the value of the attribute. If it is anything else we increase the
+       #  If the attribute is Acct-Session-Time or of an integer type we add the
+       #  value of the attribute. If it is anything else we increase the
        #  counter by one.
        #
        #  The 'reset' parameter defines when the counters are all reset to
@@ -1405,8 +1379,6 @@ $INCLUDE ${confdir}/eap.conf
        #  the radius.log
        #  If the count attribute is Acct-Session-Time then on each login
        #  we send back the remaining online time as a Session-Timeout attribute
-       #  ELSE and if the reply-name is set, we send back that attribute.
-       #  The reply-name attribute MUST be of an integer type.
        #
        #  The counter-name can also be used instead of using the check-name
        #  like below:
@@ -1432,7 +1404,6 @@ $INCLUDE ${confdir}/eap.conf
                reset = daily
                counter-name = Daily-Session-Time
                check-name = Max-Daily-Session
-               reply-name = Session-Timeout
                allowed-servicetype = Framed-User
                cache-size = 5000
        }
@@ -1478,6 +1449,11 @@ $INCLUDE ${confdir}/eap.conf
        #  attribute to use to access the counter in the 'users' file
        #  or SQL radcheck or radcheckgroup tables.
        #
+       #  The 'reply-name' parameter is the name the the attribute
+       #  which holds the time remaining for the user.  This is normally
+       #  Session-Timeout, which makes the NAS disconnect the user
+       #  once the session time is up.
+       #
        #  DEFAULT  Max-Daily-Session > 3600, Auth-Type = Reject
        #      Reply-Message = "You've used up more than one hour today"
        #
@@ -1591,8 +1567,6 @@ $INCLUDE ${confdir}/eap.conf
        #  The value of the attribute will be replaced with the output
        #  of the program which is executed.  Due to RADIUS protocol
        #  limitations, any output over 253 bytes will be ignored.
-       #
-       #  The module also registers a few paircompare functions
        expr {
        }
 
@@ -1607,48 +1581,6 @@ $INCLUDE ${confdir}/eap.conf
        }
 
        #
-       # The expiration module. This handles the Expiration attribute
-       # It should be included in the *end* of the authorize section
-       # in order to handle user Expiration. It should also be included
-       # in the instantiate section in order to register the Expiration
-       # compare function
-       #
-       expiration {
-               #
-               # The Reply-Message which will be sent back in case the
-               # account has expired. Dynamic substitution is supported
-               #
-               reply-message = "Password Has Expired\r\n" 
-#              reply-message = "Your account has expired, %{User-Name}\r\n"
-       }
-
-       # The logintime module. This handles the Login-Time,
-       # Current-Time, and Time-Of-Day attributes.  It should be
-       # included in the *end* of the authorize section in order to
-       # handle Login-Time checks. It should also be included in the
-       # instantiate section in order to register the Current-Time
-       # and Time-Of-Day comparison functions.
-       #
-       # When the Login-Time attribute is set to some value, and the
-       # user has bene permitted to log in, a Session-Timeout is
-       # calculated based on the remaining time.  See "doc/README".
-       #
-       logintime {
-               #
-               # The Reply-Message which will be sent back in case
-               # the account is calling outside of the allowed
-               # timespan. Dynamic substitution is supported.
-               #
-               reply-message = "You are calling outside your allowed timespan\r\n"
-#              reply-message = "Outside allowed timespan (%{check:Login-Time}), %{User-Name}\r\n"
-
-               # The minimum timeout (in seconds) a user is allowed
-               # to have. If the calculated timeout is lower we don't
-               # allow the logon. Some NASes do not handle values
-               # lower than 60 seconds well.
-               minimum-timeout = 60
-       }
-       #
        #  Execute external programs
        #
        #  This module is useful only for 'xlat'.  To use it,
@@ -1668,8 +1600,6 @@ $INCLUDE ${confdir}/eap.conf
        exec {
                wait = yes
                input_pairs = request
-               shell_escape = yes
-               output = none
        }
 
        #
@@ -1683,24 +1613,7 @@ $INCLUDE ${confdir}/eap.conf
        #  one section (e.g. 'authorize', 'pre_proxy', etc), then it
        #  is probably best to define a different instance of the
        #  'exec' module for every section.     
-       #
-       #  The return value of the program run determines the result
-       #  of the exec instance call as follows:
-       #  (See doc/configurable_failover for details)
-       #
-       #  < 0 : fail      the module failed
-       #  = 0 : ok        the module succeeded
-       #  = 1 : reject    the module rejected the user
-       #  = 2 : fail      the module failed
-       #  = 3 : ok        the module succeeded
-       #  = 4 : handled   the module has done everything to handle the request
-       #  = 5 : invalid   the user's configuration entry was invalid
-       #  = 6 : userlock  the user was locked out
-       #  = 7 : notfound  the user was not found
-       #  = 8 : noop      the module did nothing
-       #  = 9 : updated   the module updated information in the request
-       #  > 9 : fail      the module failed
-       #
+       #       
        exec echo {
                #
                #  Wait for the program to finish.
@@ -1766,18 +1679,6 @@ $INCLUDE ${confdir}/eap.conf
                #  being sent to the NAS.
                #
                #packet_type = Access-Accept
-
-               #
-               #  Should we escape the environment variables?
-               #  
-               #  If this is set, all the RADIUS attributes
-               #  are capitalised and dashes replaced with
-               #  underscores. Also, RADIUS values are surrounded
-               #  with double-quotes.
-               #
-               #  That is to say: User-Name=BobUser => USER_NAME="BobUser"
-               shell_escape = yes
-
        }
 
        #  Do server side ip pool management. Should be added in post-auth and
@@ -1788,15 +1689,10 @@ $INCLUDE ${confdir}/eap.conf
        #  attribute in the user profiles and use different pools
        #  for different users. The Pool-Name attribute is a *check* item not
        #  a reply item.
-       #  The Pool-Name should be set to the ippool module instance name or to
-       #  DEFAULT to match any module.
        #
        # Example:
        # radiusd.conf: ippool students { [...] }
-       #               ippool teachers { [...] }
        # users file  : DEFAULT Group == students, Pool-Name := "students"
-       #               DEFAULT Group == teachers, Pool-Name := "teachers"
-       #               DEFAULT Group == other, Pool-Name := "DEFAULT"
        #
        # ********* IF YOU CHANGE THE RANGE PARAMETERS YOU MUST *********
        # ********* THEN ERASE THE DB FILES                     *********
@@ -1828,10 +1724,6 @@ $INCLUDE ${confdir}/eap.conf
                # maximum-timeout: If not zero specifies the maximum time in seconds an
                # entry may be active. Default: 0
                maximum-timeout = 0
-
-               # The key to use for the session database (which holds the allocated ip's)
-               # normally it should just be the nas  ip/port (which is the default)
-               #key = "%{NAS-IP-Address} %{NAS-Port}"
        }
 
        # $INCLUDE  ${confdir}/sqlippool.conf
@@ -1839,22 +1731,6 @@ $INCLUDE ${confdir}/eap.conf
        # OTP token support.  Not included by default.
        # $INCLUDE  ${confdir}/otp.conf
 
-       #
-       #  Implements Login-Time, Current-Time, and Time-Of-Day
-       #
-       logintime {
-               #
-               #  Don't worry about anything here for now..
-               #
-       }
-
-       #
-       #  Kerberos.  See doc/rlm_krb5 for minimal docs.
-       #
-#      krb5 {
-#              keytab = /path/to/keytab
-#              service_principal = name_of_principle
-#      }
 }
 
 # Instantiation
@@ -1899,22 +1775,6 @@ instantiate {
        # the check-name attribute before any module which sets
        # it
 #      daily
-       expiration
-       logintime
-
-       # subsections here can be thought of as "virtual" modules.
-       #
-       # e.g. If you have two redundant SQL servers, and you want to
-       # use them in the authorize and accounting sections, you could
-       # place a "redundant" block in each section, containing the
-       # exact same text.  Or, you could uncomment the following
-       # lines, and list "redundant_sql" in the authorize and
-       # accounting sections.
-       #
-       #redundant redundant_sql {
-       #       sql1
-       #       sql2
-       #}
 }
 
 #  Authorization. First preprocess (hints and huntgroups files),
@@ -1942,6 +1802,8 @@ authorize {
        #  un-comment the following line, and the 'detail auth_log'
        #  section, above.
 #      auth_log
+       
+#      attr_filter
 
        #
        #  The chap module will set 'Auth-Type := CHAP' if we are
@@ -1957,14 +1819,6 @@ authorize {
        mschap
 
        #
-       #  Pull crypt'd passwords from /etc/passwd or /etc/shadow,
-       #  using the system API's to get the password.  If you want
-       #  to read /etc/passwd or /etc/shadow directly, see the
-       #  passwd module, above.
-       #
-       unix
-
-       #
        #  If you have a Cisco SIP server authenticating against
        #  FreeRADIUS, uncomment the following line, and the 'digest'
        #  line in the 'authenticate' section.
@@ -1991,20 +1845,7 @@ authorize {
        #
        #  It also sets the EAP-Type attribute in the request
        #  attribute list to the EAP type from the packet.
-       #
-       #  As of 2.0, the EAP module returns "ok" in the authorize stage
-       #  for TTLS and PEAP.  In 1.x, it never returned "ok" here, so
-       #  this change is compatible with older configurations.
-       #
-       #  The example below uses module failover to avoid querying all
-       #  of the following modules if the EAP module returns "ok".
-       #  Therefore, your LDAP and/or SQL servers will not be queried
-       #  for the many packets that go back and forth to set up TTLS
-       #  or PEAP.  The load on those servers will therefore be reduced.
-       #
-       eap {
-               ok = return
-       }
+       eap
 
        #
        #  Read the 'users' file
@@ -2036,20 +1877,9 @@ authorize {
        # Use the checkval module
 #      checkval
 
-       expiration
-       logintime
-
-       #
-       #  If no other module has claimed responsibility for
-       #  authentication, then try to use PAP.  This allows the
-       #  other modules listed above to add a "known good" password
-       #  to the request, and to do nothing else.  The PAP module
-       #  will then see that password, and use it to do PAP
-       #  authentication.
-       #
-       #  This module should be listed last, so that the other modules
-       #  get a chance to set Auth-Type for themselves.
        #
+       # As of 1.1.4, you should list "pap" last in this section.
+       # See "man rlm_pap" for more information.
        pap
 }
 
@@ -2199,8 +2029,6 @@ accounting {
        #  Cisco VoIP specific bulk accounting
 #      pgsql-voip
 
-       #  Filter attributes from the accounting response.
-       attr_filter.accounting_response
 }
 
 
@@ -2211,7 +2039,7 @@ session {
        radutmp
 
        #
-       #  See "Simultaneous Use Checking Queries" in sql.conf
+       #  See "Simultaneous Use Checking Querie" in sql.conf
 #      sql
 }
 
@@ -2247,17 +2075,17 @@ post-auth {
        #  the 'modules' section.
        #
 #      ldap
-
        #
        #  Access-Reject packets are sent through the REJECT sub-section of the
        #  post-auth section.
+       #  Uncomment the following and set the module name to the ldap instance
+       #  name if you have set 'edir_account_policy_check = yes' in the ldap
+       #  module sub-section of the 'modules' section.
        #
-       #  Add the ldap module name (or instance) if you have set 
-       #  'edir_account_policy_check = yes' in the ldap module configuration
-       #
-       Post-Auth-Type REJECT {
-               attr_filter.access_reject
-       }
+#      Post-Auth-Type REJECT {
+#              insert-module-name-here
+#      }
+
 }
 
 #
@@ -2275,11 +2103,6 @@ pre-proxy {
        #  as defined in the preproxy_users file.
 #      files
 
-       #  Uncomment the following line if you want to filter requests
-       #  sent to remote servers based on the rules defined in the
-       #  'attrs.pre-proxy' file.
-#      attr_filter.pre-proxy
-
        #  If you want to have a log of packets proxied to a home
        #  server, un-comment the following line, and the
        #  'detail pre_proxy_log' section, above.
@@ -2302,7 +2125,8 @@ post-proxy {
 
        #  Uncomment the following line if you want to filter replies from
        #  remote proxies based on the rules defined in the 'attrs' file.
-#      attr_filter.post-proxy
+
+#      attr_filter
 
        #
        #  If you are proxying LEAP, you MUST configure the EAP
@@ -2316,26 +2140,4 @@ post-proxy {
        #  reject the EAP request.
        #
        eap
-
-       #
-       #  If the server tries to proxy a request and fails, then the
-       #  request is processed through the modules in this section.
-       #
-       #  The main use of this section is to permit robust proxying
-       #  of accounting packets.  The server can be configured to
-       #  proxy accounting packets as part of normal processing.
-       #  Then, if the home server goes down, accounting packets can
-       #  be logged to a local "detail" file, for processing with
-       #  radrelay.  When the home server comes back up, radrelay
-       #  will read the detail file, and send the packets to the
-       #  home server.
-       #
-       #  With this configuration, the server always responds to
-       #  Accounting-Requests from the NAS, but only writes
-       #  accounting packets to disk if the home server is down.
-       #
-#      Post-Proxy-Type Fail {
-#                      detail
-#      }
-
 }
diff --git a/raddb/radrelay.conf.in b/raddb/radrelay.conf.in
deleted file mode 100644 (file)
index cff71f7..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-##
-## radrelay.conf       -- FreeRADIUS server configuration file.
-##
-##     http://www.freeradius.org/
-##     $Id$
-##
-#
-#      This configuration file is for the "radrelay" personality
-#      of FreeRADIUS.  It contains some of the same configuration
-#      items as "radiusd.conf", but many have been deleted, as they
-#      do not apply to "radrelay".
-#
-#      The server reads this file when it is run as "radiusd -n radrelay".
-#
-#
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-sysconfdir = @sysconfdir@
-localstatedir = @localstatedir@
-sbindir = @sbindir@
-logdir = @logdir@
-raddbdir = @raddbdir@
-radacctdir = @radacctdir@
-
-#  Location of config and logfiles.
-confdir = ${raddbdir}
-run_dir = ${localstatedir}/run/radiusd
-
-#
-#  The logging messages for the server are appended to the
-#  tail of this file.
-#
-log_file = ${logdir}/radius.log
-
-#
-#  Destination for log messages.  This can be one of:
-#
-#      files - log to ${log_file}, as defined above.
-#      syslog - to syslog (see also the log{} section, below)
-#      stdout - standard output
-#      stderr - standard error.
-#
-#  The command-line option "-X" over-rides this option, and forces
-#  logging to go to stdout.
-#
-log_destination = files
-
-#
-# libdir: Where to find the rlm_* modules.
-#
-#   This should be automatically set at configuration time.
-#
-#   If the server builds and installs, but fails at execution time
-#   with an 'undefined symbol' error, then you can use the libdir
-#   directive to work around the problem.
-#
-#   The cause is usually that a library has been installed on your
-#   system in a place where the dynamic linker CANNOT find it.  When
-#   executing as root (or another user), your personal environment MAY
-#   be set up to allow the dynamic linker to find the library.  When
-#   executing as a daemon, FreeRADIUS MAY NOT have the same
-#   personalized configuration.
-#
-#   To work around the problem, find out which library contains that symbol,
-#   and add the directory containing that library to the end of 'libdir',
-#   with a colon separating the directory names.  NO spaces are allowed.
-#
-#   e.g. libdir = /usr/local/lib:/opt/package/lib
-#
-#   You can also try setting the LD_LIBRARY_PATH environment variable
-#   in a script which starts the server.
-#
-#   If that does not work, then you can re-configure and re-build the
-#   server to NOT use shared libraries, via:
-#
-#      ./configure --disable-shared
-#      make
-#      make install
-#
-libdir = @libdir@
-
-#  pidfile: Where to place the PID of the RADIUS server.
-#
-#  The server may be signalled while it's running by using this
-#  file.
-#
-#  This file is written when ONLY running in daemon mode.
-#
-#  e.g.:  kill -HUP `cat /var/run/radiusd/radiusd.pid`
-#
-pidfile = ${run_dir}/radrelay.pid
-
-#
-#  radrelay doesn't need any special permissions to run.
-#
-#user = nobody
-#group = nobody
-
-max_request_time = 30
-delete_blocked_requests = no
-cleanup_delay = 5
-max_requests = 1024
-
-#
-#  You can have as many "listen" sections as you want.
-#
-#  The server CANNOT listen on type "detail" and type "acct"
-#  at the same time.
-#
-listen {
-       type = detail
-
-       # where the detail file is located
-       filename = ${confdir}/detail
-
-       #
-       #  The server can read accounting packets from the detail file
-       #  much more quickly than those packets can be written to a
-       #  database.  If we overload the database, then bad things happen.
-       #
-
-       #  The server will keep track of how long it takes to process
-       #  an entry from the detail file, and pause between handling
-       #  entries.  This pause allows databases to "catch up", and
-       #  gives the server time to notice that other packets may have
-       #  arrived.
-       #
-       #  The pause is calculated dynamically, to ensure that the
-       #  load due to reading the detail files is limited to a small
-       #  percentage of CPU time.  The "load_factor" configuration
-       #  item is a number between 1 and 100.  The server will try to
-       #  keep the percentage of time taken by "detail" file entries
-       #  to "load_factor" percentage of the CPU time.
-       #
-       #  If the "load_factor" is set to 100, then the server will
-       #  read packets as fast as it can, usually causing databases
-       #  to go into overload.
-       #  
-       load_factor = 10
-
-       #
-       #  Server identity.  This lets you tell the different "listen"
-       #  sections apart.  When a packet is read from a detail file,
-       #  the Server-Identity attribute will be set to the value below
-       #  for that packet.
-       #
-       identity = radrelay
-}
-
-
-hostname_lookups = no
-
-log {
-       syslog_facility = daemon
-}
-
-# PROXY CONFIGURATION
-#
-#  proxy_requests: Turns proxying of RADIUS requests on or off.
-#
-#  The server has proxying turned on by default.  If your system is NOT
-#  set up to proxy requests to another server, then you can turn proxying
-#  off here.  This will save a small amount of resources on the server.
-#
-#  If you have proxying turned off, and your configuration files say
-#  to proxy a request, then an error message will be logged.
-#
-#  To disable proxying, change the "yes" to "no", and comment the
-#  $INCLUDE line.
-#
-#  allowed values: {no, yes}
-#
-proxy_requests  = yes
-$INCLUDE  ${confdir}/proxy.conf
-
-
-# CLIENTS CONFIGURATION
-#
-#  Client configuration is defined in "clients.conf".  
-#
-#  The "radrelay" personality of the server does not have
-#  any clients, and does not need, or read, "clients.conf".
-
-
-# SNMP CONFIGURATION
-#
-# The "radrelay" personality of the server does not have
-# any SNMP configuration.
-
-
-# THREAD POOL CONFIGURATION
-#
-#  Threads are less useful for radrelay than for radiusd.
-#  This section is here just to remind you that it can be controlled.
-#
-thread pool {
-       start_servers = 5
-       max_servers = 32
-       min_spare_servers = 3
-       max_spare_servers = 10
-}
-
-# MODULE CONFIGURATION
-#
-#  The names and configuration of each module is located in this section.
-#
-#  Some modules have been deleted from this section.  e.g
-#
-#      pap
-#      chap
-#      mschap
-#      eap
-#      detail
-#      unix
-#      radutmp
-#
-#  It doesn't make sense to use these modules when the server is running
-#  as "radrelay".
-#
-modules {
-       # Realm module, for proxying.
-       #
-       #  You can have multiple instances of the realm module to
-       #  support multiple realm syntaxs at the same time.  The
-       #  search order is defined by the order in the authorize and
-       #  preacct sections.
-       #
-       #  Four config options:
-       #       format         -  must be "prefix" or "suffix"
-       #                         The special cases of "DEFAULT"
-       #                         and "NULL" are allowed, too.
-       #       delimiter      -  must be a single character
-
-       #  'realm/username'
-       #
-       #  Using this entry, IPASS users have their realm set to "IPASS".
-       realm IPASS {
-               format = prefix
-               delimiter = "/"
-       }
-
-       #  'username@realm'
-       #
-       realm suffix {
-               format = suffix
-               delimiter = "@"
-       }
-
-       #  'username%realm'
-       #
-       realm realmpercent {
-               format = suffix
-               delimiter = "%"
-       }
-
-       #
-       #  'domain\user'
-       #
-       realm ntdomain {
-               format = prefix
-               delimiter = "\\"
-       }       
-
-       #  A simple value checking module
-       #
-       #  It can be used to check if an attribute value in the request
-       #  matches a (possibly multi valued) attribute in the check
-       #  items This can be used for example for caller-id
-       #  authentication.  For the module to run, both the request
-       #  attribute and the check items attribute must exist
-       #
-       #  i.e.
-       #  A user has an ldap entry with 2 radiusCallingStationId
-       #  attributes with values "12345678" and "12345679".  If we
-       #  enable rlm_checkval, then any request which contains a
-       #  Calling-Station-Id with one of those two values will be
-       #  accepted.  Requests with other values for
-       #  Calling-Station-Id will be rejected.
-       #
-       #  Regular expressions in the check attribute value are allowed
-       #  as long as the operator is '=~'
-       #
-       checkval {
-               # The attribute to look for in the request
-               item-name = Calling-Station-Id
-
-               # The attribute to look for in check items. Can be multi valued
-               check-name = Calling-Station-Id
-
-               # The data type. Can be
-               # string,integer,ipaddr,date,abinary,octets
-               data-type = string
-
-               # If set to yes and we dont find the item-name attribute in the
-               # request then we send back a reject
-               # DEFAULT is no
-               #notfound-reject = no
-       }
-       
-       #  rewrite arbitrary packets.  Useful in accounting and authorization.
-       #
-       #
-       #  The module can also use the Rewrite-Rule attribute. If it
-       #  is set and matches the name of the module instance, then
-       #  that module instance will be the only one which runs.
-       #
-       #  Also if new_attribute is set to yes then a new attribute
-       #  will be created containing the value replacewith and it
-       #  will be added to searchin (packet, reply, proxy, proxy_reply or config).
-       # searchfor,ignore_case and max_matches will be ignored in that case.
-       #
-       # Backreferences are supported: %{0} will contain the string the whole match
-       # and %{1} to %{8} will contain the contents of the 1st to the 8th parentheses
-       #
-       # If max_matches is greater than one the backreferences will correspond to the
-       # first match
-
-       #
-       #attr_rewrite sanecallerid {
-       #       attribute = Called-Station-Id
-               # may be "packet", "reply", "proxy", "proxy_reply" or "config"
-       #       searchin = packet
-       #       searchfor = "[+ ]"
-       #       replacewith = ""
-       #       ignore_case = no
-       #       new_attribute = no
-       #       max_matches = 10
-       #       ## If set to yes then the replace string will be appended to the original string
-       #       append = no
-       #}
-
-       # Preprocess the incoming RADIUS request, before handing it off
-       # to other modules.
-       #
-       #  This module processes the 'huntgroups' and 'hints' files.
-       #  In addition, it re-writes some weird attributes created
-       #  by some NASes, and converts the attributes into a form which
-       #  is a little more standard.
-       #
-       preprocess {
-               huntgroups = ${confdir}/huntgroups
-               hints = ${confdir}/hints
-
-               # This hack changes Ascend's wierd port numberings
-               # to standard 0-??? port numbers so that the "+" works
-               # for IP address assignments.
-               with_ascend_hack = no
-               ascend_channels_per_line = 23
-
-               # Windows NT machines often authenticate themselves as
-               # NT_DOMAIN\username
-               #
-               # If this is set to 'yes', then the NT_DOMAIN portion
-               # of the user-name is silently discarded.
-               #
-               # This configuration entry SHOULD NOT be used.
-               # See the "realms" module for a better way to handle
-               # NT domains.
-               with_ntdomain_hack = no
-
-               # Specialix Jetstream 8500 24 port access server.
-               #
-               # If the user name is 10 characters or longer, a "/"
-               # and the excess characters after the 10th are
-               # appended to the user name.
-               #
-               # If you're not running that NAS, you don't need
-               # this hack.
-               with_specialix_jetstream_hack = no
-
-               # Cisco (and Quintum in Cisco mode) sends it's VSA attributes
-               # with the attribute name *again* in the string, like:
-               #
-               #   H323-Attribute = "h323-attribute=value".
-               #
-               # If this configuration item is set to 'yes', then
-               # the redundant data in the the attribute text is stripped
-               # out.  The result is:
-               #
-               #  H323-Attribute = "value"
-               #
-               # If you're not running a Cisco or Quintum NAS, you don't
-               # need this hack.
-               with_cisco_vsa_hack = no
-       }
-
-       # Livingston-style 'users' file
-       #
-       files {
-               usersfile = ${confdir}/users
-               acctusersfile = ${confdir}/acct_users
-
-               #  If you want to use the old Cistron 'users' file
-               #  with FreeRADIUS, you should change the next line
-               #  to 'compat = cistron'.  You can the copy your 'users'
-               #  file from Cistron.
-               compat = no
-       }
-
-       # Create a unique accounting session Id.  Many NASes re-use or
-       # repeat values for Acct-Session-Id, causing no end of
-       # confusion.
-       #
-       #  This module will add a (probably) unique session id 
-       #  to an accounting packet based on the attributes listed
-       #  below found in the packet.  See doc/rlm_acct_unique for
-       #  more information.
-       #
-       acct_unique {
-               key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port"
-       }
-
-
-       #  Include another file that has the SQL-related configuration.
-       #  This is another file only because it tends to be big.
-       #
-       #  The following configuration file is for use with MySQL.
-       #
-       #  For Postgresql, use:         ${confdir}/postgresql.conf
-       #  For MS-SQL, use:             ${confdir}/mssql.conf
-       #  For Oracle, use:             ${confdir}/oraclesql.conf
-       #
-#      $INCLUDE  ${confdir}/sql.conf
-
-
-       #  For Cisco VoIP specific accounting with Postgresql,
-       #  use:         ${confdir}/pgsql-voip.conf
-       #
-       #  You will also need the sql schema from:
-       #        src/billing/cisco_h323_db_schema-postgres.sql
-       #  Note: This config can be use AS WELL AS the standard sql
-       #  config if you need SQL based Auth
-
-       # The "always" module is here for debugging purposes. Each
-       # instance simply returns the same result, always, without
-       # doing anything.
-       always fail {
-               rcode = fail
-       }
-       always reject {
-               rcode = reject
-       }
-       always ok {
-               rcode = ok
-               simulcount = 0
-               mpp = no
-       }
-
-       #
-       #  The 'expression' module currently has no configuration.
-       #
-       #  This module is useful only for 'xlat'.  To use it,
-       #  put 'exec' into the 'instantiate' section.  You can then
-       #  do dynamic translation of attributes like:
-       #
-       #  Attribute-Name = `%{expr:2 + 3 + %{exec: uid -u}}`
-       #
-       #  The value of the attribute will be replaced with the output
-       #  of the program which is executed.  Due to RADIUS protocol
-       #  limitations, any output over 253 bytes will be ignored.
-       #
-       #  The module also registers a few paircompare functions
-       expr {
-       }
-
-       #
-       #  Execute external programs
-       #
-       #  This module is useful only for 'xlat'.  To use it,
-       #  put 'exec' into the 'instantiate' section.  You can then
-       #  do dynamic translation of attributes like:
-       #
-       #  Attribute-Name = `%{exec:/path/to/program args}`
-       #
-       #  The value of the attribute will be replaced with the output
-       #  of the program which is executed.  Due to RADIUS protocol
-       #  limitations, any output over 253 bytes will be ignored.
-       #
-       #  The RADIUS attributes from the user request will be placed
-       #  into environment variables of the executed program, as
-       #  described in 'doc/variables.txt'
-       #
-       exec {
-               wait = yes
-               input_pairs = request
-               shell_escape = yes
-       }
-}
-
-# Instantiation
-#
-#  This section orders the loading of the modules.  Modules
-#  listed here will get loaded BEFORE the later sections like
-#  authorize, authenticate, etc. get examined.
-#
-#  This section is not strictly needed.  When a section like
-#  authorize refers to a module, it's automatically loaded and
-#  initialized.  However, some modules may not be listed in any
-#  of the following sections, so they can be listed here.
-#
-#  Also, listing modules here ensures that you have control over
-#  the order in which they are initalized.  If one module needs
-#  something defined by another module, you can list them in order
-#  here, and ensure that the configuration will be OK.
-#
-instantiate {
-       exec
-       expr
-
-       # subsections here can be thought of as "virtual" modules.
-       #
-       # e.g. If you have two redundant SQL servers, and you want to
-       # use them in the authorize and accounting sections, you could
-       # place a "redundant" block in each section, containing the
-       # exact same text.  Or, you could uncomment the following
-       # lines, and list "redundant_sql" in the authorize and
-       # accounting sections.
-       #
-       #redundant redundant_sql {
-       #       sql1
-       #       sql2
-       #}
-}
-
-#
-#  There are no authorize, authenticate, or post-auth sections.
-#
-
-#
-#  Pre-accounting.  Decide which accounting type to use.
-#
-preacct {
-       preprocess
-
-       #
-       #  Ensure that we have a semi-unique identifier for every
-       #  request, and many NAS boxes are broken.
-       acct_unique
-
-       #
-       #  Look for IPASS-style 'realm/', and if not found, look for
-       #  '@realm', and decide whether or not to proxy, based on
-       #  that.
-       #
-       #  Accounting requests are generally proxied to the same
-       #  home server as authentication requests.
-#      IPASS
-       suffix
-#      ntdomain
-
-       #
-       #  Read the 'acct_users' file
-       files
-}
-
-#
-#  Accounting.  Log the accounting data.
-#
-accounting {
-       #
-       #  Log traffic to an SQL database.
-       #
-       #  See "Accounting queries" in sql.conf
-#      sql
-
-
-       #  Cisco VoIP specific bulk accounting
-#      pgsql-voip
-
-}
-
-
-#
-#  When the server decides to proxy a request to a home server,
-#  the proxied request is first passed through the pre-proxy
-#  stage.  This stage can re-write the request, or decide to
-#  cancel the proxy.
-#
-#  Only a few modules currently have this method.
-#
-pre-proxy {
-#      attr_rewrite
-
-       #  If you want to have a log of packets proxied to a home
-       #  server, un-comment the following line, and the
-       #  'detail pre_proxy_log' section, above.
-#      pre_proxy_log
-}
-
-#
-#  When the server receives a reply to a request it proxied
-#  to a home server, the request may be massaged here, in the
-#  post-proxy stage.
-#
-post-proxy {
-       #
-
-       #  If you want to have a log of replies from a home server,
-       #  un-comment the following line, and the 'detail post_proxy_log'
-       #  section, above.
-#      post_proxy_log
-
-#      attr_rewrite
-
-       #  Uncomment the following line if you want to filter replies from
-       #  remote proxies based on the rules defined in the 'attrs' file.
-
-#      attr_filter
-}
index 5b9ee40..3fc11a9 100644 (file)
 #
 #  Specifies password used when connecting to the SNMP master agent.
 #  This must match the password as configured on the agent. The OID
-#  used to register the radius subagent is 1.3.6.1.4.1.11344.1.1.1.
+#  used to register the radius subagent is 1.3.6.1.4.1.3317.1.3.1.
 #  A sample entry for the ucd-snmp deamon looks like this:
 #
-#  smuxpeer .1.3.6.1.4.1.11344.1.1.1 verysecret
+#  smuxpeer .1.3.6.1.4.1.3317.1.3.1 verysecret
 #
 #  A sample entry for AIX 4.3 is:
 #
-#  smux 1.3.6.1.4.1.11344.1.1.1 verysecret
+#  smux 1.3.6.1.4.1.3317.1.3.1 verysecret
 #
 #  The default password is an empty password.
 #
index f5cacd7..9c576ab 100644 (file)
@@ -1,42 +1,38 @@
-#  $Id$
 #
-#  Configuration for the SQL module
+#  Configuration for the SQL module, when using MySQL.
 #
-#  The database schemas are available at:
+#  The database schema is available at:
 #
-#      doc/examples/*.sql
+#      doc/examples/mysql.sql
+#
+#  If you are using PostgreSQL, please use 'postgresql.conf', instead.
+#  If you are using Oracle, please use 'oracle.conf', instead.
+#  If you are using MS-SQL, please use 'mssql.conf', instead.
+#
+#  $Id$
 #
-
 sql {
-
-       ## Database type you wish to connect to:
-       # driver = "rlm_sql_freetds"
-       # driver = "rlm_sql_iodbc"
+       # Database type
+       # Current supported are: rlm_sql_mysql, rlm_sql_postgresql,
+       # rlm_sql_iodbc, rlm_sql_oracle, rlm_sql_unixodbc, rlm_sql_freetds
        driver = "rlm_sql_mysql"
-       # driver = "rlm_sql_oracle"
-       # driver = "rlm_sql_postgresql"
-       # driver = "rlm_sql_unixodbc"
-       
-       ## Also see the bottom of this file to modify which SQL dialect you use
 
-       ## Connection info:
+       # Connect info
        server = "localhost"
-       login = "radius"
-       password = "radpass"
+       login = "root"
+       password = "rootpass"
 
-       ## Database table configuration for everything except Oracle
+       # Database table configuration
        radius_db = "radius"
-       ## If you are using Oracle then use this instead
-        # radius_db = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SID=your_sid)))"
 
-       ## If you want both stop and start records logged to the
-       ## same SQL table, leave this as is.  If you want them in
-       ## different tables, put the start table in acct_table1
-       ## and stop table in acct_table2
+       # If you want both stop and start records logged to the
+       # same SQL table, leave this as is.  If you want them in
+       # different tables, put the start table in acct_table1
+       # and stop table in acct_table2
        acct_table1 = "radacct"
        acct_table2 = "radacct"
 
-       ## Allow for storing data after authentication
+       # Allow for storing data after authentication
        postauth_table = "radpostauth"
 
        authcheck_table = "radcheck"
@@ -45,39 +41,187 @@ sql {
        groupcheck_table = "radgroupcheck"
        groupreply_table = "radgroupreply"
 
-       ## Table to keep group info
-       usergroup_table = "radusergroup"
+       usergroup_table = "usergroup"
 
-       ## If set to 'yes' (default) we read the group tables
-       ## If set to 'no' the user MUST have Fall-Through = Yes in the radreply table
-       # read_groups = yes
-
-       ## Table to keep radius client info
+       # Table to keep radius client info
        nas_table = "nas"
 
-       ## Set to 'yes' to read radius clients from the database ('nas' table)
-       # readclients = yes
-
-       ## Remove stale session if checkrad does not see a double login
+       # Remove stale session if checkrad does not see a double login
        deletestalesessions = yes
 
-       ## Print all SQL statements when in debug mode (-x)
+       # Print all SQL statements when in debug mode (-x)
        sqltrace = no
        sqltracefile = ${logdir}/sqltrace.sql
 
-       ## number of sql connections to make to server
+       # number of sql connections to make to server
        num_sql_socks = 5
 
-       ## number of seconds to dely retrying on a failed database
-       ## connection (per_socket)
+       # number of seconds to dely retrying on a failed database
+       # connection (per_socket)
        connect_failure_retry_delay = 60
 
-
-       ## Uncomment the appropriate config file for your SQL dialect
-
-       # $INCLUDE ${confdir}/sql/mssql-dialup.conf
-       $INCLUDE ${confdir}/sql/mysql-dialup.conf
-       # $INCLUDE ${confdir}/sql/oracle-dialup.conf
-       # $INCLUDE ${confdir}/sql/postgresql-dialup.conf
-
+       # Safe characters list for sql queries. Everything else is replaced
+       # with their mime-encoded equivalents.
+       # The default list should be ok
+       #safe-characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"
+
+       #######################################################################
+       #  Query config:  Username
+       #######################################################################
+       # This is the username that will get substituted, escaped, and added
+       # as attribute 'SQL-User-Name'.  '%{SQL-User-Name}' should be used below
+       # everywhere a username substitution is needed so you you can be sure
+       # the username passed from the client is escaped properly.
+       #
+       #  Uncomment the next line, if you want the sql_user_name to mean:
+       #
+       #    Use Stripped-User-Name, if it's there.
+       #    Else use User-Name, if it's there,
+       #    Else use hard-coded string "DEFAULT" as the user name.
+       #sql_user_name = "%{Stripped-User-Name:-%{User-Name:-DEFAULT}}"
+       #
+       sql_user_name = "%{User-Name}"
+
+       #######################################################################
+       #  Default profile
+       #######################################################################
+       # This is the default profile. It is found in SQL by group membership.
+       # That means that this profile must be a member of at least one group
+       # which will contain the corresponding check and reply items.
+       # This profile will be queried in the authorize section for every user.
+       # The point is to assign all users a default profile without having to
+       # manually add each one to a group that will contain the profile.
+       # The SQL module will also honor the User-Profile attribute. This
+       # attribute can be set anywhere in the authorize section (ie the users
+       # file). It is found exactly as the default profile is found.
+       # If it is set then it will *overwrite* the default profile setting.
+       # The idea is to select profiles based on checks on the incoming packets,
+       # not on user group membership. For example:
+       # -- users file --
+       # DEFAULT       Service-Type == Outbound-User, User-Profile := "outbound"
+       # DEFAULT       Service-Type == Framed-User, User-Profile := "framed"
+       #
+       # By default the default_user_profile is not set
+       #
+       #default_user_profile = "DEFAULT"
+       #
+       # Determines if we will query the default_user_profile or the User-Profile
+       # if the user is not found. If the profile is found then we consider the user
+       # found. By default this is set to 'no'.
+       #
+       #query_on_not_found = no
+
+       #######################################################################
+       #  Authorization Queries
+       #######################################################################
+       #  These queries compare the check items for the user
+       #  in ${authcheck_table} and setup the reply items in
+       #  ${authreply_table}.  You can use any query/tables
+       #  you want, but the return data for each row MUST
+       #  be in the  following order:
+       #
+       #  0. Row ID (currently unused)
+       #  1. UserName/GroupName
+       #  2. Item Attr Name
+       #  3. Item Attr Value
+       #  4. Item Attr Operation
+       #######################################################################
+       # Use these for case sensitive usernames.
+#      authorize_check_query = "SELECT id, UserName, Attribute, Value, op \
+#         FROM ${authcheck_table} \
+#         WHERE Username = BINARY '%{SQL-User-Name}' \
+#         ORDER BY id"
+#      authorize_reply_query = "SELECT id, UserName, Attribute, Value, op \
+#         FROM ${authreply_table} \
+#         WHERE Username = BINARY '%{SQL-User-Name}' \
+#         ORDER BY id"
+
+       # The default queries are case insensitive. (for compatibility with
+       # older versions of FreeRADIUS)
+       authorize_check_query = "SELECT id, UserName, Attribute, Value, op \
+          FROM ${authcheck_table} \
+          WHERE Username = '%{SQL-User-Name}' \
+          ORDER BY id"
+       authorize_reply_query = "SELECT id, UserName, Attribute, Value, op \
+          FROM ${authreply_table} \
+          WHERE Username = '%{SQL-User-Name}' \
+          ORDER BY id"
+
+       # Use these for case sensitive usernames.
+#      authorize_group_check_query = "SELECT ${groupcheck_table}.id,${groupcheck_table}.GroupName,${groupcheck_table}.Attribute,${groupcheck_table}.Value,${groupcheck_table}.op FROM ${groupcheck_table},${usergroup_table} WHERE ${usergroup_table}.Username = BINARY '%{SQL-User-Name}' AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName ORDER BY ${groupcheck_table}.id"
+#      authorize_group_reply_query = "SELECT ${groupreply_table}.id,${groupreply_table}.GroupName,${groupreply_table}.Attribute,${groupreply_table}.Value,${groupreply_table}.op  FROM ${groupreply_table},${usergroup_table} WHERE ${usergroup_table}.Username = BINARY '%{SQL-User-Name}' AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName ORDER BY ${groupreply_table}.id"
+
+       authorize_group_check_query = "SELECT ${groupcheck_table}.id,${groupcheck_table}.GroupName,${groupcheck_table}.Attribute,${groupcheck_table}.Value,${groupcheck_table}.op  FROM ${groupcheck_table},${usergroup_table} WHERE ${usergroup_table}.Username = '%{SQL-User-Name}' AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName ORDER BY ${groupcheck_table}.id"
+       authorize_group_reply_query = "SELECT ${groupreply_table}.id,${groupreply_table}.GroupName,${groupreply_table}.Attribute,${groupreply_table}.Value,${groupreply_table}.op  FROM ${groupreply_table},${usergroup_table} WHERE ${usergroup_table}.Username = '%{SQL-User-Name}' AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName ORDER BY ${groupreply_table}.id"
+
+       #######################################################################
+       #  Accounting Queries
+       #######################################################################
+       # accounting_onoff_query        - query for Accounting On/Off packets
+       # accounting_update_query       - query for Accounting update packets
+       # accounting_update_query_alt   - query for Accounting update packets
+       #                               (alternate in case first query fails)
+       # accounting_start_query        - query for Accounting start packets
+       # accounting_start_query_alt    - query for Accounting start packets
+       #                               (alternate in case first query fails)
+       # accounting_stop_query         - query for Accounting stop packets
+       # accounting_stop_query_alt     - query for Accounting start packets
+       #                               (alternate in case first query doesn't
+       #                                affect any existing rows in the table)
+       #######################################################################
+       accounting_onoff_query = "UPDATE ${acct_table1} SET AcctStopTime='%S', AcctSessionTime=unix_timestamp('%S') - unix_timestamp(AcctStartTime), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}' WHERE AcctSessionTime=0 AND AcctStopTime=0 AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= '%S'"
+
+       accounting_update_query = "UPDATE ${acct_table1} \
+          SET FramedIPAddress = '%{Framed-IP-Address}', \
+          AcctSessionTime = '%{Acct-Session-Time}', \
+          AcctInputOctets = '%{Acct-Input-Octets}', \
+          AcctOutputOctets = '%{Acct-Output-Octets}' \
+          WHERE AcctSessionId = '%{Acct-Session-Id}' \
+          AND UserName = '%{SQL-User-Name}' \
+          AND NASIPAddress= '%{NAS-IP-Address}'"
+
+       accounting_update_query_alt = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S',INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0')"
+
+       accounting_start_query = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', '%S', '0', '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time}', '0')"
+
+       accounting_start_query_alt  = "UPDATE ${acct_table1} SET AcctStartTime = '%S', AcctStartDelay = '%{Acct-Delay-Time}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'"
+
+       accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = '%S', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'"
+
+       accounting_stop_query_alt = "INSERT into ${acct_table2} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S', INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%S', '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time}')"
+
+       #######################################################################
+       # Simultaneous Use Checking Queries
+       #######################################################################
+       # simul_count_query     - query for the number of current connections
+       #                       - If this is not defined, no simultaneouls use checking
+       #                       - will be performed by this module instance
+       # simul_verify_query    - query to return details of current connections for verification
+       #                       - Leave blank or commented out to disable verification step
+       #                       - Note that the returned field order should not be changed.
+       #######################################################################
+
+       # Uncomment simul_count_query to enable simultaneous use checking
+       # simul_count_query = "SELECT COUNT(*) FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime = 0"
+       simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime = 0"
+
+       #######################################################################
+       # Group Membership Queries
+       #######################################################################
+       # group_membership_query        - Check user group membership
+       #######################################################################
+
+       group_membership_query = "SELECT GroupName FROM ${usergroup_table} WHERE UserName='%{SQL-User-Name}'"
+
+       #######################################################################
+       # Authentication Logging Queries
+       #######################################################################
+       # postauth_query                - Insert some info after authentication
+       #######################################################################
+
+       postauth_query = "INSERT into ${postauth_table} (id, user, pass, reply, date) values ('', '%{User-Name}', '%{User-Password:-Chap-Password}', '%{reply:Packet-Type}', NOW())"
+
+       #
+       # Set to 'yes' to read radius clients from the database ('nas' table)
+       #readclients = yes
 }
diff --git a/raddb/sql/mysql-dialup.conf b/raddb/sql/mysql-dialup.conf
deleted file mode 100644 (file)
index 9418437..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-#  $Id$
-#
-# FreeRADIUS "dialup" SQL Queries for the MySQL Dialect
-
-       # Safe characters list for sql queries. Everything else is replaced
-       # with their mime-encoded equivalents.
-       # The default list should be ok
-       #safe-characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"
-
-       #######################################################################
-       #  Query config:  Username
-       #######################################################################
-       # This is the username that will get substituted, escaped, and added
-       # as attribute 'SQL-User-Name'.  '%{SQL-User-Name}' should be used below
-       # everywhere a username substitution is needed so you you can be sure
-       # the username passed from the client is escaped properly.
-       #
-       #  Uncomment the next line, if you want the sql_user_name to mean:
-       #
-       #    Use Stripped-User-Name, if it's there.
-       #    Else use User-Name, if it's there,
-       #    Else use hard-coded string "DEFAULT" as the user name.
-       #sql_user_name = "%{Stripped-User-Name:-%{User-Name:-DEFAULT}}"
-       #
-       sql_user_name = "%{User-Name}"
-
-       #######################################################################
-       #  Default profile
-       #######################################################################
-       # This is the default profile. It is found in SQL by group membership.
-       # That means that this profile must be a member of at least one group
-       # which will contain the corresponding check and reply items.
-       # This profile will be queried in the authorize section for every user.
-       # The point is to assign all users a default profile without having to
-       # manually add each one to a group that will contain the profile.
-       # The SQL module will also honor the User-Profile attribute. This
-       # attribute can be set anywhere in the authorize section (ie the users
-       # file). It is found exactly as the default profile is found.
-       # If it is set then it will *overwrite* the default profile setting.
-       # The idea is to select profiles based on checks on the incoming packets,
-       # not on user group membership. For example:
-       # -- users file --
-       # DEFAULT       Service-Type == Outbound-User, User-Profile := "outbound"
-       # DEFAULT       Service-Type == Framed-User, User-Profile := "framed"
-       #
-       # By default the default_user_profile is not set
-       #
-       #default_user_profile = "DEFAULT"
-
-       #######################################################################
-       #  NAS Query
-       #######################################################################
-       #  This query retrieves the radius clients
-       #
-       #  0. Row ID (currently unused)
-       #  1. Name (or IP address)
-       #  2. Shortname
-       #  3. Type
-       #  4. Secret
-       #######################################################################
-
-       nas_query = "SELECT id, nasname, shortname, type, secret FROM ${nas_table}"
-
-       #######################################################################
-       #  Authorization Queries
-       #######################################################################
-       #  These queries compare the check items for the user
-       #  in ${authcheck_table} and setup the reply items in
-       #  ${authreply_table}.  You can use any query/tables
-       #  you want, but the return data for each row MUST
-       #  be in the  following order:
-       #
-       #  0. Row ID (currently unused)
-       #  1. UserName/GroupName
-       #  2. Item Attr Name
-       #  3. Item Attr Value
-       #  4. Item Attr Operation
-       #######################################################################
-       # Use these for case sensitive usernames.
-#      authorize_check_query = "SELECT id, UserName, Attribute, Value, op \
-#         FROM ${authcheck_table} \
-#         WHERE Username = BINARY '%{SQL-User-Name}' \
-#         ORDER BY id"
-#      authorize_reply_query = "SELECT id, UserName, Attribute, Value, op \
-#         FROM ${authreply_table} \
-#         WHERE Username = BINARY '%{SQL-User-Name}' \
-#         ORDER BY id"
-
-       # The default queries are case insensitive. (for compatibility with
-       # older versions of FreeRADIUS)
-       authorize_check_query = "SELECT id, UserName, Attribute, Value, op \
-          FROM ${authcheck_table} \
-          WHERE Username = '%{SQL-User-Name}' \
-          ORDER BY id"
-       authorize_reply_query = "SELECT id, UserName, Attribute, Value, op \
-          FROM ${authreply_table} \
-          WHERE Username = '%{SQL-User-Name}' \
-          ORDER BY id"
-
-       # Use these for case sensitive usernames.
-#      group_membership_query = "SELECT GroupName \
-#         FROM ${usergroup_table} \
-#         WHERE UserName = BINARY '%{SQL-User-Name}' \
-#         ORDER BY priority"
-
-       group_membership_query = "SELECT GroupName \
-          FROM ${usergroup_table} \
-          WHERE UserName = '%{SQL-User-Name}' \
-          ORDER BY priority"
-
-       authorize_group_check_query = "SELECT id, GroupName, Attribute, Value, op \
-          FROM ${groupcheck_table} \
-          WHERE GroupName = '%{Sql-Group}' \
-          ORDER BY id"
-       authorize_group_reply_query = "SELECT id, GroupName, Attribute, Value, op \
-          FROM ${groupreply_table} \
-          WHERE GroupName = '%{Sql-Group}' \
-          ORDER BY id"
-
-       #######################################################################
-       #  Accounting Queries
-       #######################################################################
-       # accounting_onoff_query        - query for Accounting On/Off packets
-       # accounting_update_query       - query for Accounting update packets
-       # accounting_update_query_alt   - query for Accounting update packets
-       #                               (alternate in case first query fails)
-       # accounting_start_query        - query for Accounting start packets
-       # accounting_start_query_alt    - query for Accounting start packets
-       #                               (alternate in case first query fails)
-       # accounting_stop_query         - query for Accounting stop packets
-       # accounting_stop_query_alt     - query for Accounting start packets
-       #                               (alternate in case first query doesn't
-       #                                affect any existing rows in the table)
-       #######################################################################
-       accounting_onoff_query = "UPDATE ${acct_table1} SET AcctStopTime='%S', AcctSessionTime=unix_timestamp('%S') - unix_timestamp(AcctStartTime), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = %{Acct-Delay-Time:-0} WHERE AcctSessionTime=0 AND AcctStopTime=0 AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= '%S'"
-
-       accounting_update_query = "UPDATE ${acct_table1} \
-          SET FramedIPAddress = '%{Framed-IP-Address}', \
-          AcctSessionTime = '%{Acct-Session-Time}', \
-          AcctInputOctets = '%{Acct-Input-Octets}', \
-          AcctOutputOctets = '%{Acct-Output-Octets}' \
-          WHERE AcctSessionId = '%{Acct-Session-Id}' \
-          AND UserName = '%{SQL-User-Name}' \
-          AND NASIPAddress= '%{NAS-IP-Address}'"
-
-       accounting_update_query_alt = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S',INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0')"
-
-       accounting_start_query = "INSERT into ${acct_table1} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', '%S', '0', '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time:-0}', '0')"
-
-       accounting_start_query_alt  = "UPDATE ${acct_table1} SET AcctStartTime = '%S', AcctStartDelay = '%{Acct-Delay-Time:-0}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'"
-
-       accounting_stop_query = "UPDATE ${acct_table2} SET AcctStopTime = '%S', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'"
-
-       accounting_stop_query_alt = "INSERT into ${acct_table2} (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S', INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%S', '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time:-0}')"
-
-       #######################################################################
-       # Simultaneous Use Checking Queries
-       #######################################################################
-       # simul_count_query     - query for the number of current connections
-       #                       - If this is not defined, no simultaneouls use checking
-       #                       - will be performed by this module instance
-       # simul_verify_query    - query to return details of current connections for verification
-       #                       - Leave blank or commented out to disable verification step
-       #                       - Note that the returned field order should not be changed.
-       #######################################################################
-
-       # Uncomment simul_count_query to enable simultaneous use checking
-       # simul_count_query = "SELECT COUNT(*) FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime = 0"
-       simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime = 0"
-
-       #######################################################################
-       # Authentication Logging Queries
-       #######################################################################
-       # postauth_query                - Insert some info after authentication
-       #######################################################################
-
-       postauth_query = "INSERT into ${postauth_table} (id, user, pass, reply, date) values ('', '%{User-Name}', '%{User-Password:-Chap-Password}', '%{reply:Packet-Type}', '%S')"
-
diff --git a/raddb/sql/mysql-ippool-dialup.conf b/raddb/sql/mysql-ippool-dialup.conf
deleted file mode 100644 (file)
index 3d799c4..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#  $Id$
-#
-# FreeRADIUS rlm_sqlippool SQL Queries for the MySQL Dialect 
-
- #
- # This series of queries allocates an IP address
- #
- allocate-clear = "UPDATE radippool \
-  SET NASIPAddress = '', pool_key = 0, CallingStationId = '', \
-  expiry_time = NOW() - INTERVAL 1 SECOND \
-  WHERE pool_key = '${pool-key}'"
-
- # note the ORDER BY clause of next query, it'll try to allocate IPs
- # like Cisco internal pools do - it _trys_ to allocate the same IP-address
- # which user had last session...
- allocate-find = "SELECT FramedIPAddress FROM radippool \
-  WHERE pool_name = '%{reply:Pool-Name}' AND expiry_time < NOW() \
-  ORDER BY pool_name, (UserName <> '%{User-Name}'), (CallingStationId <>
-'%{Calling-Station-Id}'), expiry_time \
-  LIMIT 1 \
-  FOR UPDATE"
-
- allocate-update = "UPDATE radippool \
-  SET NASIPAddress = '%{NAS-IP-Address}', pool_key = '${pool-key}', \
-  CallingStationId = '%{Calling-Station-Id}', UserName = '%{User-Name}', \
-  expiry_time = NOW() + INTERVAL ${lease-duration} SECOND \
-  WHERE FramedIPAddress = '%{Framed-IP-Address}'"
-
-
-
- #
- # This series of queries frees an IP number when an accounting
- # START record arrives
- #
- start-update = "UPDATE radippool \
-  SET expiry_time = NOW() + INTERVAL %J SECOND \
-  WHERE NASIPAddress = '%n' AND pool_key = '${pool-key}' AND pool_name =
-'%P'"
-
- #
- # This series of queries frees an IP number when an accounting
- # STOP record arrives
- #
- stop-clear = "UPDATE radippool \
-  SET NASIPAddress = '', pool_key = 0, CallingStationId = '', \
-  expiry_time = NOW() - INTERVAL 1 SECOND \
-  WHERE NASIPAddress = '%{NAS-IP-Address}' AND pool_key = '${pool-key}'
-AND UserName = '%{User-Name}' \
-  AND CallingStationId = '%{Calling-Station-Id}' AND FramedIPAddress =
-'%{Framed-IP-Address}'"
-
-
-
-
- #
- # This series of queries frees an IP number when an accounting
- # ALIVE record arrives
- #
- alive-update = "UPDATE radippool \
-  SET expiry_time = NOW() + INTERVAL ${lease-duration} SECOND \
-  WHERE NASIPAddress = '%{Nas-IP-Address}' AND pool_key = '${pool-key}'
-AND UserName = '%{User-Name}' \
-  AND CallingStationId = '%{Calling-Station-Id}' AND FramedIPAddress =
-'%{Framed-IP-Address}'"
-
-
- #
- # This series of queries frees the IP numbers allocate to a
- # NAS when an accounting ON record arrives
- #
- on-clear = "UPDATE radippool \
-  SET NASIPAddress = '', pool_key = 0, CallingStationId = '', \
-  expiry_time = NOW() - INTERVAL 1 SECOND \
-  WHERE NASIPAddress = '%{NAS-IP-Address}' AND UserName = '%{User-Name}' \
-  AND CallingStationId = '%{Calling-Station-Id}' AND FramedIPAddress =
-'%{Framed-IP-Address}'"
-
- #
- # This series of queries frees the IP numbers allocate to a
- # NAS when an accounting OFF record arrives
- #
- off-clear = "UPDATE radippool \
-  SET NASIPAddress = '', pool_key = 0, CallingStationId = '', \
-  expiry_time = NOW() - INTERVAL 1 SECOND \
-  WHERE NASIPAddress = '%{NAS-IP-Address}' AND UserName = '%{User-Name}' \
-  AND CallingStationId = '%{Calling-Station-Id}' AND FramedIPAddress =
-'%{Framed-IP-Address}'"
-
diff --git a/raddb/sql/postgresql-dialup.conf b/raddb/sql/postgresql-dialup.conf
deleted file mode 100644 (file)
index b58e062..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-#
-#  $Id$
-#
-#  Configuration for the SQL module, when using Postgresql.
-#
-#  The database schema is available at:
-#
-#      doc/examples/postgresql.sql
-#
-
-
-       # Safe characters list for sql queries. Everything else is replaced
-       # with their mime-encoded equivalents.
-       # The default list should be ok
-#      safe-characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"
-
-       #######################################################################
-       #  Query config:  Username
-       #######################################################################
-       # This is the username that will get substituted, escaped, and added
-       # as attribute 'SQL-User-Name'.  '%{SQL-User-Name}' should be used
-       # below everywhere a username substitution is needed so you you can
-       # be sure the username passed from the client is escaped properly.
-       #
-       # Uncomment the next line, if you want the sql_user_name to mean:
-       #
-       #    Use Stripped-User-Name, if it's there.
-       #    Else use User-Name, if it's there,
-       #    Else use hard-coded string "none" as the user name.
-       #
-       #sql_user_name = "%{Stripped-User-Name:-%{User-Name:-none}}"
-       #
-       sql_user_name = "%{User-Name}"
-
-       #######################################################################
-       #  Default profile
-       #######################################################################
-       # This is the default profile. It is found in SQL by group membership.
-       # That means that this profile must be a member of at least one group
-       # which will contain the corresponding check and reply items.
-       # This profile will be queried in the authorize section for every user.
-       # The point is to assign all users a default profile without having to
-       # manually add each one to a group that will contain the profile.
-       # The SQL module will also honor the User-Profile attribute. This
-       # attribute can be set anywhere in the authorize section (ie the users
-       # file). It is found exactly as the default profile is found.
-       # If it is set then it will *overwrite* the default profile setting.
-       # The idea is to select profiles based on checks on the incoming
-       # packets, not on user group membership. For example:
-       # -- users file --
-       # DEFAULT       Service-Type == Outbound-User, User-Profile := "outbound"
-       # DEFAULT       Service-Type == Framed-User, User-Profile := "framed"
-       #
-       # By default the default_user_profile is not set
-       #
-#      default_user_profile = "DEFAULT"
-
-       #######################################################################
-       #  NAS Query
-       #######################################################################
-       #  This query retrieves the radius clients
-       #
-       #  0. Row ID (currently unused)
-       #  1. Name (or IP address)
-       #  2. Shortname
-       #  3. Type
-       #  4. Secret
-       #######################################################################
-
-       nas_query = "SELECT id, nasname, shortname, type, secret FROM ${nas_table}"
-
-       #######################################################################
-       #  Authorization Queries
-       #######################################################################
-       #  These queries compare the check items for the user
-       #  in ${authcheck_table} and setup the reply items in
-       #  ${authreply_table}.  You can use any query/tables
-       #  you want, but the return data for each row MUST
-       #  be in the  following order:
-       #
-       #  0. Row ID (currently unused)
-       #  1. UserName/GroupName
-       #  2. Item Attr Name
-       #  3. Item Attr Value
-       #  4. Item Attr Operation
-       #######################################################################
-
-       # Use these for case insensitive usernames. WARNING: Slower queries!
-# authorize_check_query = "SELECT id, UserName, Attribute, Value, Op \
-#   FROM ${authcheck_table} \
-#   WHERE LOWER(UserName) = LOWER('%{SQL-User-Name}') \
-#   ORDER BY id"
-# authorize_reply_query = "SELECT id, UserName, Attribute, Value, Op \
-#   FROM ${authreply_table} \
-#   WHERE LOWER(UserName) = LOWER('%{SQL-User-Name}') \
-#   ORDER BY id"
-
-       authorize_check_query = "SELECT id, UserName, Attribute, Value, Op \
-               FROM ${authcheck_table} \
-               WHERE Username = '%{SQL-User-Name}' \
-               ORDER BY id"
-
-       authorize_reply_query = "SELECT id, UserName, Attribute, Value, Op \
-               FROM ${authreply_table} \
-               WHERE Username = '%{SQL-User-Name}' \
-               ORDER BY id"
-
-       # Use these for case insensitive usernames. WARNING: Slower queries!
-# authorize_group_check_query = "SELECT ${groupcheck_table}.id, ${groupcheck_table}.GroupName, \
-#   ${groupcheck_table}.Attribute, ${groupcheck_table}.Value, ${groupcheck_table}.Op \
-#   FROM ${groupcheck_table}, ${usergroup_table} \
-#   WHERE LOWER(${usergroup_table}.UserName) = LOWER('%{SQL-User-Name}') AND ${usergroup_table}.GroupName = ${groupcheck_table}.GroupName \
-#   ORDER BY ${groupcheck_table}.id"
-# authorize_group_reply_query = "SELECT ${groupreply_table}.id, ${groupreply_table}.GroupName, \
-#   ${groupreply_table}.Attribute, ${groupreply_table}.Value, ${groupreply_table}.Op \
-#   FROM ${groupreply_table}, ${usergroup_table} \
-#   WHERE LOWER(${usergroup_table}.UserName) = LOWER('%{SQL-User-Name}') AND ${usergroup_table}.GroupName = ${groupreply_table}.GroupName \
-#   ORDER BY ${groupreply_table}.id"
-
-  authorize_group_check_query = "SELECT id, GroupName, Attribute, Value, op \
-    FROM ${groupcheck_table} \
-    WHERE GroupName = '%{Sql-Group}' \
-    ORDER BY id"
-
-  authorize_group_reply_query = "SELECT id, GroupName, Attribute, Value, op \
-    FROM ${groupreply_table} \
-    WHERE GroupName = '%{Sql-Group}' \
-    ORDER BY id"
-
-        #######################################################################
-        # Simultaneous Use Checking Queries
-        #######################################################################
-        # simul_count_query     - query for the number of current connections
-        #                       - If this is not defined, no simultaneous use checking
-        #                       - will be performed by this module instance
-        # simul_verify_query    - query to return details of current connections for verification
-        #                       - Leave blank or commented out to disable verification step
-        #                       - Note that the returned field order should not be changed.
-        #######################################################################
-
-        # Uncomment simul_count_query to enable simultaneous use checking
-       # simul_count_query = "SELECT COUNT(*) FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime IS NULL"
-        # simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol FROM ${acct_table1} WHERE UserName='%{SQL-User-Name}' AND AcctStopTime IS NULL"
-
-
-
-       #######################################################################
-       #  Accounting Queries
-       #######################################################################
-       # accounting_onoff_query        - query for Accounting On/Off packets
-       # accounting_update_query       - query for Accounting update packets
-       # accounting_update_query_alt   - query for Accounting update packets
-       #                               (alternate in case first query fails)
-       # accounting_start_query        - query for Accounting start packets
-       # accounting_start_query_alt    - query for Accounting start packets
-       #                               (alternate in case first query fails)
-       # accounting_stop_query         - query for Accounting stop packets
-       # accounting_stop_query_alt     - query for Accounting start packets
-       #                               (alternate in case first query doesn't
-       #                                affect any existing rows in the table)
-       #######################################################################
-
-  accounting_onoff_query = "UPDATE ${acct_table1} \
-    SET AcctStopTime = (now() - '%{Acct-Delay-Time:-0}'::interval), \
-    AcctSessionTime = (EXTRACT(EPOCH FROM (now()::timestamp with time zone - AcctStartTime::timestamp with time zone \
-    - '%{Acct-Delay-Time:-0}'::interval)))::BIGINT, \
-    AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}' \
-    WHERE AcctSessionTime IS NULL AND AcctStopTime IS NULL AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= now()"
-
-  accounting_update_query = "UPDATE ${acct_table1} \
-    SET FramedIPAddress = NULLIF('%{Framed-IP-Address}', '')::inet, \
-    AcctSessionTime = '%{Acct-Session-Time}', \
-    AcctInputOctets = (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
-    AcctOutputOctets = (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint) \
-    WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' \
-    AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
-
-  accounting_update_query_alt = "INSERT INTO ${acct_table1} \
-    (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, \
-    AcctSessionTime, AcctAuthentic, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, \
-    ServiceType, FramedProtocol, FramedIPAddress) \
-    values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', \
-    %{NAS-Port:-NULL}::integer, '%{NAS-Port-Type}', (now() - '%{Acct-Delay-Time:-0}'::interval - '%{Acct-Session-Time:-0}'::interval), \
-    '%{Acct-Session-Time}', '%{Acct-Authentic}', \
-    (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
-    (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint), '%{Called-Station-Id}', \
-    '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', NULLIF('%{Framed-IP-Address}', '')::inet)"
-
-  accounting_start_query = "INSERT INTO ${acct_table1} \
-    (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctAuthentic, \
-    ConnectInfo_start, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay) \
-    values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', \
-    %{NAS-Port:-NULL}::integer, '%{NAS-Port-Type}', (now() - '%{Acct-Delay-Time:-0}'::interval), '%{Acct-Authentic}', \
-    '%{Connect-Info}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', \
-    NULLIF('%{Framed-IP-Address}', '')::inet, '%{Acct-Delay-Time:-0}')"
-
-  accounting_start_query_alt  = "UPDATE ${acct_table1} \
-    SET AcctStartTime = (now() - '%{Acct-Delay-Time:-0}'::interval), AcctStartDelay = '%{Acct-Delay-Time:-0}', \
-    ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' \
-    AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
-
-  accounting_stop_query = "UPDATE ${acct_table2} \
-    SET AcctStopTime = (now() - '%{Acct-Delay-Time:-0}'::interval), \
-    AcctSessionTime = CASE WHEN '%{Acct-Session-Time}' = '' THEN \
-    (EXTRACT(EPOCH FROM (now()::TIMESTAMP WITH TIME ZONE - AcctStartTime::TIMESTAMP WITH TIME ZONE \
-    - '%{Acct-Delay-Time:-0}'::INTERVAL)))::BIGINT ELSE '%{Acct-Session-Time}' END, \
-    AcctInputOctets = (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
-    AcctOutputOctets = (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint), \
-    AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time:-0}', \
-    FramedIPAddress = NULLIF('%{Framed-IP-Address}', '')::inet, ConnectInfo_stop = '%{Connect-Info}' \
-    WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' \
-    AND NASIPAddress = '%{NAS-IP-Address}' AND AcctStopTime IS NULL"
-
-  accounting_stop_query_alt = "INSERT INTO ${acct_table2} \
-    (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, \
-    AcctSessionTime, AcctAuthentic, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, \
-    CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStopDelay) \
-    values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', \
-    %{NAS-Port:-NULL}::integer, '%{NAS-Port-Type}', (now() - '%{Acct-Delay-Time:-0}'::interval - '%{Acct-Session-Time:-0}'::interval), \
-    (now() - '%{Acct-Delay-Time:-0}'::interval), NULLIF('%{Acct-Session-Time}', '')::bigint, '%{Acct-Authentic}', \
-    '%{Connect-Info}', (('%{Acct-Input-Gigawords:-0}'::bigint << 32) + '%{Acct-Input-Octets:-0}'::bigint), \
-    (('%{Acct-Output-Gigawords:-0}'::bigint << 32) + '%{Acct-Output-Octets:-0}'::bigint), '%{Called-Station-Id}', \
-    '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', \
-    NULLIF('%{Framed-IP-Address}', '')::inet, '%{Acct-Delay-Time:-0}')"
-
-       #######################################################################
-       # Group Membership Queries
-       #######################################################################
-       # group_membership_query        - Check user group membership
-       #######################################################################
-
-       # Use these for case insensitive usernames. WARNING: Slower queries!
-# group_membership_query = "SELECT GroupName FROM ${usergroup_table} WHERE LOWER(UserName) = LOWER('%{SQL-User-Name}') ORDER BY priority"
-
-  group_membership_query = "SELECT GroupName FROM ${usergroup_table} WHERE UserName='%{SQL-User-Name}' ORDER BY priority"
-
-       #######################################################################
-       # Authentication Logging Queries
-       #######################################################################
-       # postauth_query                - Insert some info after authentication
-       #######################################################################
-  postauth_query = "INSERT INTO ${postauth_table} (username, pass, reply, authdate) \
-    VALUES ('%{User-Name}', '%{User-Password:-Chap-Password}', '%{reply:Packet-Type}', NOW())"
-
diff --git a/raddb/sql/postgresql-ippool-dialup.conf b/raddb/sql/postgresql-ippool-dialup.conf
deleted file mode 100644 (file)
index ed3fcbb..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#  $Id$
-#
-# FreeRADIUS rlm_sqlippool SQL Queries for the PostgreSQL Dialect
-
- ## This series of queries allocates an IP address
- allocate-clear = "UPDATE ${ippool_table} \
-  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
-  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
-  WHERE pool_key = '${pool-key}'"
-
- ## The ORDER BY clause of this query tries to allocate the same IP-address
- ## which user had last session...
- allocate-find = "SELECT framedipaddress FROM ${ippool_table} \
-  WHERE pool_name = '%{check:Pool-Name}' AND expiry_time < 'now'::timestamp(0) \
-  ORDER BY (username <> '%{SQL-User-Name}'), (callingstationid <> '%{Calling-Station-Id}'), expiry_time \
-  LIMIT 1 \
-  FOR UPDATE"
-
- ## If you prefer to allocate a random IP address every time, use this query instead
- #allocate-find = "SELECT framedipaddress FROM ${ippool_table} \
- # WHERE pool_name = '%P' AND expiry_time < 'now'::timestamp(0) \
- # ORDER BY RANDOM() \
- # LIMIT 1 \
- # FOR UPDATE"
-
-
- ## If an IP could not be allocated, check to see if the pool exists or not
- ## This allows the module to differentiate between a full pool and no pool
- ## Note: If you are not running redundant pool modules this query may be commented
- ## out to save running this query every time an ip is not allocated.
- pool-check = "SELECT id FROM ${ippool_table} WHERE pool_name='%{check:Pool-Name}' LIMIT 1"
-
- allocate-update = "UPDATE ${ippool_table} \
-  SET nasipaddress = '%{NAS-IP-Address}', pool_key = '${pool-key}', \
-  callingstationid = '%{Calling-Station-Id}', username = '%{SQL-User-Name}', \
-  expiry_time = 'now'::timestamp(0) + '${lease-duration} second'::interval \
-  WHERE framedipaddress = '%I'"
-
-
- ## This series of queries frees an IP number when an accounting
- ## START record arrives
- start-update = "UPDATE ${ippool_table} \
-  SET expiry_time = 'now'::timestamp(0) + '${lease-duration} second'::interval \
-  WHERE nasipaddress = '%{NAS-IP-Address}' AND  pool_key = '${pool-key}'"
-
- ## This series of queries frees an IP number when an accounting
- ## STOP record arrives
- stop-clear = "UPDATE ${ippool_table} \
-  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
-  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
-  WHERE nasipaddress = '%{Nas-IP-Address}' AND pool_key = '${pool-key}' AND username = '%{SQL-User-Name}' \
-  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
-
-
-
- ## This series of queries frees an IP number when an accounting
- ## ALIVE record arrives
- alive-update = "UPDATE ${ippool_table} \
-  SET expiry_time = 'now'::timestamp(0) + '${lease-duration} seconds'::interval \
-  WHERE nasipaddress = '%{Nas-IP-Address}' AND pool_key = '${pool-key}' AND username = '%{SQL-User-Name}' \
-  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
-
-
- ## This series of queries frees the IP numbers allocate to a
- ## NAS when an accounting ON record arrives
- on-clear = "UPDATE ${ippool_table} \
-  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
-  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
-  WHERE nasipaddress = '%{Nas-IP-Address}' AND username = '%{SQL-User-Name}' \
-  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
-
- ## This series of queries frees the IP numbers allocate to a
- ## NAS when an accounting OFF record arrives
- off-clear = "UPDATE ${ippool_table} \
-  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
-  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
-  WHERE nasipaddress = '%{Nas-IP-Address}' AND username = '%{SQL-User-Name}' \
-  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
-
index 8f47eb3..75d21e6 100644 (file)
@@ -1,49 +1,95 @@
-#  Configuration for the SQL based IPPool module (rlm_sqlippool)
-#
-#  The database schemas are available at:
-#
-#       doc/examples/*.sql
-#
-#  $Id$
 
-sqlippool {
+sqlippool sqlippool {
 
- ## SQL instance to use (from sql.conf)
+ #
+ # SQL connection information
+ #
  sql-instance-name = "sql"
 
- ## Table to keep ippool info
- ippool_table = "radippool"
-
- ## lease_duration. fix for lost acc-stop packets
+ # lease_duration. fix for lost acc-stop packets
  lease-duration = 3600
 
- ## Attribute which should be considered unique per NAS
- ## Using NAS-Port gives behaviour similar to rlm_ippool. Calling-Station-Id is for NAS that send fixed NAS-Port
+ # Attribute which should be considered unique per NAS
  pool-key = "%{NAS-Port}"
  # pool-key = "%{Calling-Station-Id}"
 
- ## Logging configuration.
- sqlippool_log_exists = "Existing IP: %{reply:Framed-IP-Address} \
-  (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
-
- sqlippool_log_success = "Allocated IP: %{reply:Framed-IP-Address} from %{check:Pool-Name} \
-  (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
-
- sqlippool_log_clear = "Released IP %{Framed-IP-Address}\
- (did %{Called-Station-Id} cli %{Calling-Station-Id} user %{User-Name})"
-
- sqlippool_log_failed = "IP Allocation FAILED from %{check:Pool-Name} \
-  (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
-
- sqlippool_log_nopool = "No Pool-Name defined \
-  (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
 
-
-
- ## Uncomment the appropriate config file for your SQL dialect
-
- # $INCLUDE ${confdir}/sql/mysql-dialup.conf
- $INCLUDE ${confdir}/sql/postgresql-ippool-dialup.conf
+ #
+ # This series of queries allocates an IP address
+ #
+ allocate-clear = "UPDATE radippool \
+  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
+  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
+  WHERE pool_key = '%{Calling-Station-Id}'"
+
+ # note the ORDER BY clause of next query, it'll try to allocate IPs
+ # like Cisco internal pools do - it _trys_ to allocate the same IP-address
+ # which user had last session...
+ allocate-find = "SELECT framedipaddress FROM radippool \
+  WHERE pool_name = '%{reply:Pool-Name}' AND expiry_time < 'now'::timestamp(0) \
+  ORDER BY pool_name, (username <> '%{User-Name}'), (callingstationid <> '%{Calling-Station-Id}'), expiry_time \
+  LIMIT 1 \
+  FOR UPDATE"
+
+ allocate-update = "UPDATE radippool \
+  SET nasipaddress = '%{NAS-IP-Address}', pool_key = '%{Calling-Station-Id}', \
+  callingstationid = '%{Calling-Station-Id}', username = '%{User-Name}', \
+  expiry_time = 'now'::timestamp(0) + '${lease-duration} second'::interval \
+  WHERE framedipaddress = '%I'"
+
+
+
+ #
+ # This series of queries frees an IP number when an accounting
+ # START record arrives
+ #
+ start-update = "UPDATE radippool \
+  SET expiry_time = 'now'::timestamp(0) + '%J second'::interval \
+  WHERE nasipaddress = '%n' AND nas_port = '%p' AND pool_name = '%P'"
+
+ #
+ # This series of queries frees an IP number when an accounting
+ # STOP record arrives
+ #
+ stop-clear = "UPDATE radippool \
+  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
+  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
+  WHERE nasipaddress = '%{Nas-IP-Address}' AND pool_key = '${pool-key}' AND username = '%{User-Name}' \
+  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
+
+
+
+
+ #
+ # This series of queries frees an IP number when an accounting
+ # ALIVE record arrives
+ #
+ alive-update = "UPDATE radippool \
+  SET expiry_time = 'now'::timestamp(0) + '${lease-duration} seconds'::interval \
+  WHERE nasipaddress = '%{Nas-IP-Address}' AND pool_key = '${pool-key}' AND username = '%{User-Name}' \
+  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
+
+
+ #
+ # This series of queries frees the IP numbers allocate to a
+ # NAS when an accounting ON record arrives
+ #
+ on-clear = "UPDATE radippool \
+  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
+  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
+  WHERE nasipaddress = '%{Nas-IP-Address}' AND username = '%{User-Name}' \
+  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
+
+ #
+ # This series of queries frees the IP numbers allocate to a
+ # NAS when an accounting OFF record arrives
+ #
+ off-clear = "UPDATE radippool \
+  SET nasipaddress = '', pool_key = 0, callingstationid = '', \
+  expiry_time = 'now'::timestamp(0) - '1 second'::interval \
+  WHERE nasipaddress = '%{Nas-IP-Address}' AND username = '%{User-Name}' \
+  AND callingstationid = '%{Calling-Station-Id}' AND framedipaddress = '%{Framed-IP-Address}'"
 
 
 }
+
diff --git a/raddb/templates.conf b/raddb/templates.conf
deleted file mode 100644 (file)
index 4570dda..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-######################################################################
-#
-#  Version 2.0 has a useful new feature called "templates".
-#
-#  Use templates by adding a line in radiusd.conf:
-#
-#      $INCLUDE ${confdir}/templates.conf.
-#
-#  Templates are not included in the default configuration because
-#  they can have large effects on the server configuration.
-#
-#  The goal of the templates is to have common configuration located
-#  in this file, and to list only the *differences* in the individual
-#  sections.  This feature is most useful for sections like "clients"
-#  or "home_servers", where many may be defined, and each one has
-#  similar repeated configuration.
-#
-#  Something similar to templates can be done by putting common
-#  configuration into separate files, and using "$INCLUDE file...",
-#  but this is more flexible, and simpler to understand.  It's also
-#  cheaper for the server, because "$INCLUDE" makes a copy of the
-#  configuration for inclusion, and templates are simply referenced.
-#
-#  The templates are defined in the "templates" section, so that they
-#  do not affect the rest of the server configuration.
-#
-templates {
-         #
-         #  The contents of the templates section are other
-         #  configuration sections that would normally go into
-         #  the configuration files.
-         #
-
-         #
-         #  This is a default template for the "home_server" section.
-         #  Note that there is no name for the section.
-         #
-         #  Any configuration item that is valid for a "home_server"
-         #  section is also valid here.  When a "home_server" section
-         #  is defined in proxy.conf, this section is referenced as
-         #  the template.
-         #
-         #  Configuration items that are explicitly listed in a
-         #  "home_server" section of proxy.conf are used in
-         #  preference to the configuration items listed here.
-         #
-         #  However, if a configuration item is NOT listed in a
-         #  "home_server" section of proxy.conf, then the value here
-         #  is used.
-         #
-         #  This functionality lets you put common configuration into
-         #  a template, and to put only the unique configuration
-         #  items in "proxy.conf".
-         #
-         home_server {
-                       response_window = 20
-                       zombie_period = 40
-                       revive_interval = 120
-                       #
-                       #  Etc.
-         }
-
-         #
-         #  You can also have named templates.  For example, if you
-         #  are proxying to 3 different home servers all at the same
-         #  site, with identical configurations (other than IP
-         #  addresses), you can use this named template.
-         #
-
-         #  Then, each "home_server" section in "proxy.conf" would
-         #  only list the IP address of that home server, and a
-         #  line saying
-         #
-         #             template = example.com
-         #
-         #  That would tell FreeRADIUS to look in the section below
-         #  for the rest of the configuration items.
-         #
-         home_server example.com {
-                     type = auth
-                     port = 1812
-                     secret = testing123
-                     response_window = 20
-                     #
-                     # Etc...
-         }
-
-         #
-         #  You can have templates for other sections, too, but they
-         #  seem to be most useful for home_servers.
-         #
-         #  For now, you can use templates only for sections in
-         #  radiusd.conf, not sub-sections.  So you still have to use
-         #  the "$INCLUDE file.." method for things like defining
-         #  multiple "sql" modules, each with similar configuration.
-         #       
-}
index f0e1372..2c2586f 100644 (file)
@@ -2,6 +2,12 @@
 #      Please read the documentation file ../doc/processing_users_file,
 #      or 'man 5 users' (after installing the server) for more information.
 #
+#      As of 1.1.4, you SHOULD NOT use Auth-Type.  See "man rlm_pap"
+#      for a much better way of dealing with differing passwords.
+#      If you set Auth-Type, SOME AUTHENTICATION METHODS WILL NOT WORK.
+#      If you don't set Auth-Type, the server will figure out what to do,
+#      and will almost always do the right thing.
+#
 #      This file contains authentication security and configuration
 #      information for each user.  Accounting requests are NOT processed
 #      through this file.  Instead, see 'acct_users', in this directory.
 #      type (perhaps set by the "hints" file), and huntgroup name (set by
 #      the "huntgroups" file).
 #
+#      Indented (with the tab character) lines following the first
+#      line indicate the configuration values to be passed back to
+#      the comm server to allow the initiation of a user session.
+#      This can include things like the PPP configuration values
+#      or the host to log the user onto.
+#
 #      If you are not sure why a particular reply is being sent by the
 #      server, then run the server in debugging mode (radiusd -X), and
 #      you will see which entries in this file are matched.
 #      matches the login-request will stop processing unless you use
 #      the Fall-Through variable.
 #
-#      If you use the database support to turn this file into a .db or .dbm
-#      file, the DEFAULT entries _have_ to be at the end of this file and
-#      you can't have multiple entries for one username.
-#
-#      Indented (with the tab character) lines following the first
-#      line indicate the configuration values to be passed back to
-#      the comm server to allow the initiation of a user session.
-#      This can include things like the PPP configuration values
-#      or the host to log the user onto.
-#
 #      You can include another `users' file with `$INCLUDE users.other'
 #
 
@@ -73,7 +75,7 @@
 # entry so that no DEFAULT entry will be used, and the user will NOT
 # get any attributes in addition to the ones listed here.
 #
-#steve User-Password := "testing"
+#steve Cleartext-Password := "testing"
 #      Service-Type = Framed-User,
 #      Framed-Protocol = PPP,
 #      Framed-IP-Address = 172.16.3.33,
 # This is an entry for a user with a space in their name.
 # Note the double quotes surrounding the name.
 #
-#"John Doe"    User-Password := "hello"
-#              Reply-Message = "Hello, %{User-Name}"
+#"John Doe"    Cleartext-Password := "hello"
+#              Reply-Message = "Hello, %u"
 
 #
 # Dial user back and telnet to the default host for that port
 #
-#Deg   User-Password := "ge55ged"
+#Deg   Cleartext-Password := "ge55ged"
 #      Service-Type = Callback-Login-User,
 #      Login-IP-Host = 0.0.0.0,
 #      Callback-Number = "9,5551212",
 # connection will be broken and the user will be dialed back after which
 # he will get a connection to the host "timeshare1".
 #
-#dialbk        User-Password := "callme"
+#dialbk        Cleartext-Password := "callme"
 #      Service-Type = Callback-Login-User,
 #      Login-IP-Host = timeshare1,
 #      Login-Service = PortMaster,
 # against the system database, give them shell access, and stop processing
 # the rest of the file.
 #
+# Note that authenticating against an /etc/passwd file works ONLY for PAP,
+# and not for CHAP, MS-CHAP, or EAP.
+#
 #DEFAULT       Suffix == ".shell", Auth-Type := System
 #              Service-Type = Login-User,
 #              Login-Service = Telnet,
 #
 
 #
+# First setup all accounts to be checked against the UNIX /etc/passwd.
+# (Unless a password was already given earlier in this file).
+#
+DEFAULT        Auth-Type = System
+       Fall-Through = 1
+
+#
 # Set up different IP address pools for the terminal servers.
 # Note that the "+" behind the IP address means that this is the "base"
 # IP address. The Port-Id (S0, S1 etc) will be added to it.
 #              Fall-Through = Yes
 
 #
-# Sample defaults for all framed connections.
+# Defaults for all framed connections.
 #
-#DEFAULT       Service-Type == Framed-User
-#      Framed-IP-Address = 255.255.255.254,
-#      Framed-MTU = 576,
-#      Service-Type = Framed-User,
-#      Fall-Through = Yes
+DEFAULT        Service-Type == Framed-User
+       Framed-IP-Address = 255.255.255.254,
+       Framed-MTU = 576,
+       Service-Type = Framed-User,
+       Fall-Through = Yes
 
 #
 # Default for PPP: dynamic IP address, PPP mode, VJ-compression.
@@ -198,6 +210,6 @@ DEFAULT     Hint == "SLIP"
 # # Last default: shell on the local terminal server.
 # #
 # DEFAULT
-#      Service-Type = Administrative-User
+#      Service-Type = Shell-User
 
 # On no match, the user is denied access.
index 12e8deb..e387d10 100644 (file)
@@ -1,7 +1,7 @@
 Summary: High-performance and highly configurable RADIUS server
 URL: http://www.freeradius.org/
 Name: freeradius
-Version: 2.0.0
+Version: 1.1.6
 Release: 0
 License: GPL
 Group: Networking/Daemons
@@ -114,7 +114,6 @@ fi
 %{_libdir}/*
 %{_mandir}/*/*
 %{_sbindir}/*
-%{_incdir}/freeradius/*
 %attr(0700,radiusd,radiusd) %dir /var/log/radius
 %attr(0700,radiusd,radiusd) %dir /var/log/radius/radacct
 %attr(0700,radiusd,radiusd) %dir /var/run/radiusd
index 2bac22d..ac5265a 100755 (executable)
@@ -15,7 +15,7 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 #    Copyright (C) 2001 The FreeRADIUS Project   http://www.freeradius.org
 #
diff --git a/scripts/CA.all b/scripts/CA.all
new file mode 100755 (executable)
index 0000000..a3df90a
--- /dev/null
@@ -0,0 +1,81 @@
+#!/bin/sh -x
+
+#
+#  This is a script to help generate certificates for use with
+#  the EAP-TLS module.
+#
+
+SSL=/usr/local/ssl
+
+export PATH=${SSL}/bin/:${SSL}/ssl/misc:${PATH}
+
+export LD_LIBRARY_PATH=${SSL}/lib
+
+rm -rf demoCA roo* cert* *.pem *.der
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreate private key"
+echo -e "\t\tname : name-root"
+echo -e "\t\tCA.pl -newcert"
+echo -e "\t\t##################\n"
+
+openssl req -new -x509 -keyout newreq.pem -out newreq.pem -days 730 -passin pass:whatever -passout pass:whatever
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreate CA"
+echo -e "\t\tuse just created 'newreq.pem' private key as filename"
+echo -e "\t\tCA.pl -newca"
+echo -e "\t\t##################\n"
+
+echo "newreq.pem" | /usr/local/ssl/misc/CA.pl -newca
+
+#ls -lg demoCA/private/cakey.pem
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\texporting ROOT CA"
+echo -e "\t\tCA.pl -newreq"
+echo -e "\t\tCA.pl -signreq"
+echo -e "\t\topenssl pkcs12 -export -in demoCA/cacert.pem -inkey newreq.pem -out root.pem"
+echo -e "\t\topenssl pkcs12 -in root.cer -out root.pem"
+echo -e "\t\t##################\n"
+
+openssl pkcs12 -export -in demoCA/cacert.pem -inkey newreq.pem -out root.p12 -cacerts -passin pass:whatever -passout pass:whatever
+openssl pkcs12 -in root.p12 -out root.pem -passin pass:whatever -passout pass:whatever
+openssl x509 -inform PEM -outform DER -in root.pem -out root.der 
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreating client certificate"
+echo -e "\t\tname : name-clt"
+echo -e "\t\tclient certificate stored as cert-clt.pem"
+echo -e "\t\tCA.pl -newreq"
+echo -e "\t\tCA.pl -signreq"
+echo -e "\t\t##################\n"
+
+openssl req -new -keyout newreq.pem -out newreq.pem -days 730 -passin pass:whatever -passout pass:whatever
+openssl ca  -policy policy_anything -out newcert.pem -passin pass:whatever -key whatever -extensions xpclient_ext -extfile xpextensions -infiles newreq.pem
+
+openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -out cert-clt.p12 -clcerts -passin pass:whatever -passout pass:whatever
+openssl pkcs12 -in cert-clt.p12 -out cert-clt.pem -passin pass:whatever -passout pass:whatever
+openssl x509 -inform PEM -outform DER -in cert-clt.pem -out cert-clt.der 
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreating server certificate"
+echo -e "\t\tname : name-srv"
+echo -e "\t\tserver certificate stored as cert-srv.pem"
+echo -e "\t\tCA.pl -newreq"
+echo -e "\t\tCA.pl -signreq"
+echo -e "\t\t##################\n"
+
+openssl req -new  -keyout newreq.pem -out newreq.pem -days 730 -passin pass:whatever -passout pass:whatever
+openssl ca  -policy policy_anything  -out newcert.pem -passin pass:whatever -key whatever -extensions xpserver_ext -extfile xpextensions -infiles newreq.pem 
+
+ openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -out cert-srv.p12 -clcerts -passin pass:whatever -passout pass:whatever
+openssl pkcs12 -in cert-srv.p12 -out cert-srv.pem -passin pass:whatever -passout pass:whatever
+openssl x509 -inform PEM -outform DER -in cert-srv.pem -out cert-srv.der 
+
+echo -e "\n\t\t##################\n"
diff --git a/scripts/CA.certs b/scripts/CA.certs
new file mode 100755 (executable)
index 0000000..e01f1d0
--- /dev/null
@@ -0,0 +1,178 @@
+#!/bin/sh
+
+#
+#  This is a NON-INTERACTIVE script to help generate certificates for
+#  use with the EAP-TLS module.
+#
+#      $Id$
+
+#
+#  This environment variable should point to the SSL installation
+#
+[ "$SSL" = "" ] && SSL=/usr/local/ssl
+export SSL
+
+#
+#  Edit the following variables for your organization.
+#
+COUNTRY="CA"
+PROVINCE="Province"
+CITY="Some City"
+ORGANIZATION="Organization"
+ORG_UNIT=`hostname`
+PASSWORD="whatever"
+
+COMMON_NAME_CLIENT="Client certificate"
+EMAIL_CLIENT="client@example.com"
+PASSWORD_CLIENT=$PASSWORD
+
+COMMON_NAME_SERVER="Server certificate"
+EMAIL_SERVER="server@example.com"
+PASSWORD_SERVER=$PASSWORD
+
+COMMON_NAME_ROOT="Root certificate"
+EMAIL_ROOT="root@example.com"
+PASSWORD_ROOT=$PASSWORD
+
+#
+#  lifetime, in days, of the certs
+#
+LIFETIME=730
+
+######################################################################
+#
+#  Don't change anything below this line...
+#
+######################################################################
+
+#
+#  Prefer the SSL configured above, over any previous installation.
+#
+PATH=${SSL}/bin/:${SSL}/misc:${PATH}
+LD_LIBRARY_PATH=${SSL}/lib
+export PATH LD_LIBRARY_PATH
+
+rm -rf demoCA roo* cert* *.pem *.der
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreate private key"
+echo -e "\t\tname : name-root"
+echo -e "\t\tCA.pl -newcert"
+echo -e "\t\t##################\n"
+
+(echo $COUNTRY
+echo $PROVINCE
+echo $CITY
+echo $ORGANIZATION
+echo $ORG_UNIT
+echo $COMMON_NAME_CLIENT
+echo $EMAIL_CLIENT
+) | openssl req -new -x509 -keyout newreq.pem -out newreq.pem -days $LIFETIME -passin pass:$PASSWORD_CLIENT -passout pass:$PASSWORD_CLIENT
+if [ "$?" != "0" ]
+then
+    echo "Failed to create client certificate"
+    exit 1
+fi
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreate CA"
+echo -e "\t\tuse just created 'newreq.pem' private key as filename"
+echo -e "\t\tCA.pl -newca"
+echo -e "\t\t##################\n"
+
+echo "newreq.pem" | CA.pl -newca || exit 2
+
+#ls -lg demoCA/private/cakey.pem
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\texporting ROOT CA"
+echo -e "\t\tCA.pl -newreq"
+echo -e "\t\tCA.pl -signreq"
+echo -e "\t\topenssl pkcs12 -export -in demoCA/cacert.pem -inkey newreq.pem -out root.pem"
+echo -e "\t\topenssl pkcs12 -in root.cer -out root.pem"
+echo -e "\t\t##################\n"
+
+openssl pkcs12 -export -in demoCA/cacert.pem -inkey newreq.pem -out root.p12 -cacerts -passin pass:$PASSWORD_ROOT -passout pass:$PASSWORD_ROOT
+openssl pkcs12 -in root.p12 -out root.pem -passin pass:$PASSWORD_ROOT -passout pass:$PASSWORD_ROOT
+openssl x509 -inform PEM -outform DER -in root.pem -out root.der 
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreating client certificate"
+echo -e "\t\tname : name-clt"
+echo -e "\t\tclient certificate stored as cert-clt.pem"
+echo -e "\t\tCA.pl -newreq"
+echo -e "\t\tCA.pl -signreq"
+echo -e "\t\t##################\n"
+
+(echo $COUNTRY
+echo $PROVINCE
+echo $CITY
+echo $ORGANIZATION
+echo $ORG_UNIT
+echo $COMMON_NAME_SERVER
+echo $EMAIL_SERVER
+echo $PASSWORD_SERVER
+echo "testing"
+) | openssl req -new -keyout newreq.pem -out newreq.pem -days $LIFETIME -passin pass:$PASSWORD_SERVER -passout pass:$PASSWORD_SERVER
+if [ "$?" != "0" ]
+then
+    echo "Failed to create server certificate"
+    exit 1
+fi
+
+(echo y
+echo y) | openssl ca  -policy policy_anything -out newcert.pem -passin pass:$PASSWORD_SEREVER -key $PASSWORD_SERVER -extensions xpclient_ext -extfile xpextensions -infiles newreq.pem
+if [ "$?" != "0" ]
+then
+    echo "Failed to do sign certificate"
+    exit 1
+fi
+
+openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -out cert-clt.p12 -clcerts -passin pass:$PASSWORD_CLIENT -passout pass:$PASSWORD_CLIENT || exit 8
+openssl pkcs12 -in cert-clt.p12 -out cert-clt.pem -passin pass:$PASSWORD_CLIENT -passout pass:$PASSWORD_CLIENT || exit 9
+openssl x509 -inform PEM -outform DER -in cert-clt.pem -out cert-clt.der || exit 10
+
+echo -e ""
+echo -e "\t\t##################"
+echo -e "\t\tcreating server certificate"
+echo -e "\t\tname : name-srv"
+echo -e "\t\tserver certificate stored as cert-srv.pem"
+echo -e "\t\tCA.pl -newreq"
+echo -e "\t\tCA.pl -signreq"
+echo -e "\t\t##################\n"
+
+(echo $COUNTRY
+echo $PROVINCE
+echo $CITY
+echo $ORGANIZATION
+echo $ORG_UNIT
+echo $COMMON_NAME_ROOT
+echo $EMAIL_ROOT
+echo $PASSWORD_ROOT
+echo $ORG_UNIT
+) | openssl req -new  -keyout newreq.pem -out newreq.pem -days $LIFETIME -passin pass:$PASSWORD_ROOT -passout pass:$PASSWORD_ROOT
+if [ "$?" != "0" ]
+then
+    echo "Failed to create root certificate"
+    exit 1
+fi
+
+(echo y
+echo y) | openssl ca  -policy policy_anything  -out newcert.pem -passin pass:$PASSWORD_ROOT -key $PASSWORD_ROOT -extensions xpserver_ext -extfile xpextensions -infiles newreq.pem 
+if [ "$?" != "0" ]
+then
+    echo "Failed to sign root certificate"
+    exit 1
+fi
+
+openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -out cert-srv.p12 -clcerts -passin pass:$PASSWORD_SERVER -passout pass:$PASSWORD_SERVER || exit 5
+openssl pkcs12 -in cert-srv.p12 -out cert-srv.pem -passin pass:$PASSWORD_SERVER -passout pass:$PASSWORD_SERVER || exit 6
+openssl x509 -inform PEM -outform DER -in cert-srv.pem -out cert-srv.der || exit 7
+
+echo -e "\n\t\t#################################"
+echo -e "\t\tDONE.  Thank you for your patience."
+echo -e "\t\t###################################\n"
index dcd3cd8..4e17270 100644 (file)
@@ -4,9 +4,6 @@ include ../Make.inc
 
 all:
 
-radwatch:
-       $(INSTALL) -m 755 radwatch              $(R)$(sbindir)
-
 install:
        $(INSTALL) -m 755 rc.radiusd            $(R)$(sbindir)
        $(INSTALL) -m 755 radsqlrelay           $(R)$(bindir)
diff --git a/scripts/certs.sh b/scripts/certs.sh
new file mode 100755 (executable)
index 0000000..a71350e
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+#      $Id$
+
+#
+#  Set this variable to the location of your SSL installation.
+#
+[ "$SSL" = "" ] && SSL=/usr/local/ssl
+export SSL
+
+#
+#  Don't touch the following text.
+#
+[ -d certs ] && rm -rf certs
+mkdir certs
+cp xpextensions certs/
+cd certs
+
+#
+# Generate DH stuff...
+#
+$(SSL)/bin/openssl gendh > dh
+
+#
+#  /dev/urandom is not a file, and we can't rely on "test -e" working
+#  everywhere.
+#
+if ls /dev/urandom >/dev/null 2>&1
+then
+  dd if=/dev/urandom of=random count=2 >/dev/null 2>&1
+else
+  echo "Please replace this text with 1k of random data" > random
+fi
+
+rm -f CA.log
+../CA.certs > CA.log 2>&1
+if [ "$?" != "0" ]
+then
+    echo "  Certificate creation failed."
+    echo "  Please see the 'CA.log' file for messages,"
+    echo "  or read the 'CA.all' script, and run it by hand."
+    echo
+    echo "  Sorry."
+    exit 1
+fi
+echo "  See the 'certs' directory for the certificates."
+echo "  The 'certs' directory should be copied to .../etc/raddb/"
+echo "  All passwords have been set to 'whatever'"
+rm -f CA.log xpextensions
+exit 0
index 753013d..2fc9460 100755 (executable)
@@ -3,7 +3,7 @@
 #  Check the RADIUS server configuration files.
 #
 #  If everything is OK, this script exits without an error.
-#
+#  
 #  If there was an error parsing the configuration files, this script
 #  prints the errors to the screen, and exits with an error.
 #
diff --git a/scripts/clients.pl b/scripts/clients.pl
deleted file mode 100755 (executable)
index 819887c..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env perl
-#
-#  Convert old-style "clients" file to new "clients.conf" format.
-#
-#  Usage: clients.pl clients [naslist] new-clients.conf
-#      The "new-clients.conf" will be created if it does not exist.
-#      If it does exist, it will be over-written.
-#
-#
-#      $Id$
-#
-if (($#ARGV < 1) || ($#ARGV > 2)) {
-    print "Usage: clients.pl clients [naslist] new-clients.conf\n";
-    print "       The \"new-clients.conf\" will be created if it does not exist.\n";
-    print "       If it does exist, it will be over-written.\n";
-    exit(1);
-}
-
-$old = shift;
-$new = shift;
-
-if ($new =~ /naslist/) {
-    $naslist = $new;
-    $new = shift;
-}
-
-open OLD, "< $old" or die "Failed to open $old: $!\n";
-
-while (<OLD>) {
-    next if (/^\s*\#/);
-    next if (/^\s*$/);
-
-    split;
-
-    $clients{$_[0]}{"secret"} = $_[1];
-}
-close OLD;
-
-if (defined $naslist) {
-    open OLD, "< $naslist" or die "Failed to open $naslist: $!\n";
-
-    while (<OLD>) {
-       next if (/^\s*\#/);
-       next if (/^\s*$/);
-
-       split;
-
-       if (!defined $clients{$_[0]}) {
-           print "WARNING! client $_[0] is defined in naslist, but not in clients!";
-           next;
-       }
-
-       $clients{$_[0]}{"shortname"} = $_[1];
-       $clients{$_[0]}{"nastype"} = $_[2];
-    }
-}
-
-open NEW, "> $new" or die "Failed to open $new: $!\n";
-foreach $client (keys %clients) {
-    print NEW "client $client {\n";
-    print NEW "\tsecret = ", $clients{$client}{"secret"}, "\n";
-    if (defined $clients{$client}{"shortname"}) {
-       print NEW "\tshortname = ", $clients{$client}{"shortname"}, "\n";
-       print NEW "\tnastype = ", $clients{$client}{"nastype"}, "\n";
-    }
-    print NEW "}\n";
-    print NEW "\n";
-}
index 1faa406..c316e26 100755 (executable)
@@ -37,8 +37,8 @@ for ($num=0; $num<$numusers; $num++) {
                $num--;
                next;
        }
-       $userlist{$username} = 1;
-
+       $userlist{$username} = 1;       
+       
        # generate password
        $password = "";
        for($i=0; $i<rand($passlen)+2; $i++) {
@@ -51,8 +51,8 @@ for ($num=0; $num<$numusers; $num++) {
        printf RAD  "User-Name=$username, User-Password=$password,NAS-IP-Address=127.0.0.1,NAS-Port-Id=0\n\n";
        print NOCRYPT "$username:$password\n";
        print USERS "$username  Auth-Type:=Local, User-Password==\"$password\"\n\tClass=\"0x$num\"\n\n";
-}
-
+} 
+       
 close(PASS);
 close(SHAD);
 close(RAD);
index 905442e..e9388ad 100755 (executable)
@@ -14,7 +14,7 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 #    Copyright (C) 2001 The FreeRADIUS Project   http://www.freeradius.org
 #
index ea303bc..1d388ac 100755 (executable)
@@ -1,33 +1,20 @@
 #!/bin/sh
 #
-#  $Id$
-#
-#  Sample script to add Attribute/Value pairs in the reply sent to
-#  the NAS.
-#
-#  Before version 2.0 of FreeRADIUS, the script could be run from the
-#  deprecated attributes 'Exec-Program' and 'Exec-Program-Wait'.
-#  However, these attributes are no longer supported and you have to
-#  use the module 'rlm_exec' instead.
-#
-#  An entry for the module 'rlm_exec' must be added to the file
-#  'radiusd.conf' with the path of the script.
-#
-#modules {
-#      exec {
-#              program = "/path/to/program/exec-program-wait"
-#              wait = yes
-#              input_pairs = request
-#              output_pairs = reply
-#      }
-#      ...
-#}
-#
-#authorize {
-#      ...
-#      exec
-#      ...
-#}
+# $Id$
+#
+#  Sample script to run when a 'user' file entry is similar to:
+#
+#bob   Password == "bob"
+#      Exec-Program-Wait = "/path/to/program/exec-program-wait"
+#
+#  For 'acct_users':
+#
+#DEFAULT Acct-Status-Type == Start
+#      Exec-Program = "/path/to/exec/acct/start"
+#
+#DEFAULT Acct-Status-Type == Stop
+#      Exec-Program = "/path/to/exec/acct/stop"
+#
 #
 #  Each of the attributes in the request will be available in an
 #  environment variable.  The name of the variable depends on the
 #  to the script.  Then look in the file for a complete list of
 #  variables.
 #
-#  The return value of the program run determines the result
-#  of the exec instance call as follows:
-#  (See doc/configurable_failover for details)
-#  < 0 : fail      the module failed
-#  = 0 : okthe module succeeded
-#  = 1 : reject    the module rejected the user
-#  = 2 : fail      the module failed
-#  = 3 : okthe module succeeded
-#  = 4 : handled   the module has done everything to handle the request
-#  = 5 : invalid   the user's configuration entry was invalid
-#  = 6 : userlock  the user was locked out
-#  = 7 : notfound  the user was not found
-#  = 8 : noop      the module did nothing
-#  = 9 : updated   the module updated information in the request
-#  > 9 : fail      the module failed
-#
 echo "Reply-Message += \"Hello, %u\","
 echo "Reply-Message += \"PATH=$PATH\","
 echo Framed-IP-Address = 255.255.255.255
diff --git a/scripts/min-includes.pl b/scripts/min-includes.pl
deleted file mode 100755 (executable)
index eff8b1b..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env perl
-######################################################################
-#
-#  This script find duplicates of #include files, ignoring #ifdef's, etc.
-#  from C source files, and (at your command) removes the duplicates.
-#
-#  It is meant to be run ONLY by FreeRADUS developers, and has nothing
-#  whatsoever to do with RADIUS, FreeRADIUS, or confguring a RADIUS server.
-#
-######################################################################
-#
-#  Run as: ./min-includes.pl `find . -name "*.c" -print`
-#              prints out duplicate includes from files.
-#
-#         ./min-includes.pl +n `find . -name "*.c" -print`
-#              removes the duplicate includes from each file.
-#              Remember to check that it still builds!
-#
-#  It has to be run from the TOP of the FreeRADIUS build tree,
-#  i.e. where the top-level "configure" script is located.
-#
-######################################################################
-#
-#  FIXME: We don't handle include files taken from the current
-#  directory...
-#
-#  FIXME: we should take -I <path> from the command line.
-#
-######################################################################
-#
-#  Copyright (C) 2006 Alan DeKok <aland@freeradius.org>
-#
-#  $Id$
-#
-######################################################################
-
-my %processed;
-
-$any_dups = 0;
-$debug = 0;
-
-#
-#  Find the #include's for one file.
-#
-sub process($) {
-    my $file = shift;
-
-    return if ($processed{$file});
-
-    $processed{$file}++;
-
-    open FILE, "<$file" or die "Failed to open $file: $!\n";
-
-    $line = 0;
-    while (<FILE>) {
-       $line++;
-
-       next if (!/^\s*\#\s*include\s+/);
-
-       if (/^\s*\#\s*include\s+"(.+?)"/) {
-           $refs{$file}{$1} = $line;
-
-           # FIXME: local header files?
-           # src/foo/bar.c: #include "foo.h"
-           #   src/foo/foo.h do stuff..
-
-           $include{$1}++;
-       } elsif (/^\s*\#\s*include\s+<(.+?)>/) {
-           $refs{$file}{$1} = $line;
-           $include{$1}++;
-       }
-    }
-
-    close FILE;
-}
-
-#
-#  Where include files are located.
-#
-#  FIXME:
-#
-@directories = ("src/lib", "src");
-$do_it = 0;
-
-#
-#  Horrid.
-#
-if ($ARGV[0] eq "+n") {
-    shift;
-    $do_it = 1;
-}
-
-#
-#  Bootstrap the basic C files.
-#
-foreach $file (@ARGV) {
-    process($file);
-}
-
-
-#
-#  Process the include files referenced from the C files, to find out
-#  what they include Note that we create a temporary array, rather
-#  than walking over %include, because the process() function adds
-#  entries to the %include hash.
-#
-@work = sort keys %include;
-foreach $inc (@work) {
-
-    foreach $dir (@directories) {
-       $path = $dir . "/" . $inc;
-
-       # normalize path
-       $path =~ s:/.*?/\.\.::;
-       $path =~ s:/.*?/\.\.::;
-
-       next if (! -e $path);
-       process($path);
-       $forward{$inc} = $path;
-       $reverse{$path} = $inc;
-
-       # ignore system include files
-       next if ((scalar keys %{$refs{$path}}) == 0);
-
-       #  Remember that X includes Y, and push Y onto the list
-       #  of files to scan.
-       foreach $inc2 (sort keys %{$refs{$path}}) {
-           $maps{$inc}{$inc2} = 0;
-           push @work, $inc2;
-       }
-    }
-}
-
-#
-#  Process all of the forward refs, so that we have a complete
-#  list of who's referencing who.
-#
-#  This doesn't find the shortest path from A to B, but it does
-#  find one path.
-#
-foreach $inc (sort keys %maps) {
-    foreach $inc2 (sort keys %{$maps{$inc}}) {
-       foreach $inc3 (sort keys %{$maps{$inc2}}) {
-           # map is already there...
-           next if (defined $maps{$inc}{$inc3});
-
-           $maps{$inc}{$inc3} = $maps{$inc2}{$inc3} + 1;
-       }
-    }
-}
-
-#
-#  Walk through the files again, looking for includes that are
-#  unnecessary.  Note that we process header files, too.
-#
-foreach $file (sort keys %refs) {
-
-    # print out some debugging information.
-    if ($debug > 0) {
-       if (defined $reverse{$file}) {
-           print $file, "\t(", $reverse{$file}, ")\n";
-       } else {
-           print $file, "\n";
-       }
-    }
-
-    #  walk of the list of include's in this file
-    foreach $ref (sort keys %{$refs{$file}}) {
-
-       #  walk over the include files we include, or included by
-       #  files that we include.
-       foreach $inc2 (sort keys %{$maps{$ref}}) {
-           #
-           #  If we include X, and X includes Y, and we include
-           #  Y ourselves *after* X, it's a definite dupe.
-           #
-           #  Note that this is a *guaranteed* duplicate.
-           #
-           #  Sometimes order matters, so we can't always delete X if
-           #  we include Y after X, and Y includes X
-           #
-           if (defined $refs{$file}{$inc2} &&
-               ($refs{$file}{$inc2} > $refs{$file}{$ref})) {
-               $duplicate{$file}{$inc2} = $ref;
-
-               # mark the line to be deleted.
-               $delete_line{$file}{$refs{$file}{$inc2}}++;
-
-               $any_dups++;
-           }
-       }
-       print "\t", $ref, "\n" if ($debug > 0);
-    }
-}
-
-if ($debug > 0) {
-    print "------------------------------------\n";
-}
-
-#
-#  Maybe just print out the dups so that a person can validate them.
-#
-if (!$do_it) {
-    foreach $file (sort keys %duplicate) {
-       print $file, "\n";
-
-       foreach $inc (sort keys %{$duplicate{$file}}) {
-           print "\t[", $refs{$file}{$inc}, "] ", $inc, " (", $duplicate{$file}{$inc}, " at ", $refs{$file}{$duplicate{$file}{$inc}}, ")\n";
-       }
-    }
-} else {
-    foreach $file (sort keys %duplicate) {
-       open FILE, "<$file" or die "Failed to open $file: $!\n";
-       open OUTPUT, ">$file.tmp" or die "Failed to create $file.tmp: $!\n";
-
-       $line = 0;
-       while (<FILE>) {
-           $line++;
-
-           # supposed to delete this line, don't print it to the output.
-           next if (defined $delete_line{$file}{$line});
-
-           print OUTPUT;
-       }
-
-       rename "$file.tmp", $file;
-    }
-
-}
-
-#  If we succeeded in re-writing the files, it's OK.
-exit 0 if ($do_it);
-
-#  If there are no duplicates, then we're OK.
-exit 0 if (!$any_dups);
-
-#  Else there are duplicates, complain.
-exit 1
index 4dbd04f..fea38d0 100755 (executable)
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 # -----------------------------------------------------------------------
 
 
-# TODO:
+# TODO: 
 # currently does not encrypt passwords (takes them from outside file)
 
 # Command line options
@@ -72,7 +72,7 @@ use Getopt::Std;
 getopts('dpmf:');
 $debug = $opt_d;
 
-%passwords;
+%passwords; 
 # This might or might not be necessary depending if your LDAP server
 # when importing from ldif introduces crypted passwords in the LDAP db
 # (not necessary for Netscape's Directory Server)
@@ -144,14 +144,14 @@ $addgroup = $addgroup."\ncn: $groupname";
 #        { "radiusLoginLATPort", "Login-LAT-Port" },
 # You can change to the mappings below like this
 # cat radius2ldif.pl | grep ^# | \
-# perl -ne 'if ( /\{ \"(.*?)\", \"(.*?)\" \}/ ) \
+# perl -ne 'if ( /\{ \"(.*?)\", \"(.*?)\" \}/ ) \ 
 # { $attr=lc $2; print "\$mapping{\"$attr\"} = \"$1\";\n" ; } '
 
 
 # Warning: sometimes password must be encrypted before sent to the LDAP
 # Which Perl libraries are available? Only way I find is through
-# Netscape's NDS getpwenc.
-# However NDS does the cyphering even if sending plain passwords
+# Netscape's NDS getpwenc. 
+# However NDS does the cyphering even if sending plain passwords 
 # (do all LDAP's do this?)
 # TODO: test with OpenLDAP
 $mapping{'password'} = "userpassword";
@@ -211,7 +211,7 @@ while ($line=<STDIN>) {
        }
        # Start line is hardcoded must be uid followed by password
        # this could be changed to use any other parameter however
-       if ( $line =~ /^(\w+)\s*\t*(?:User-)?Password=(\w+)/ ) {
+       if ( $line =~ /^(\w+)\s*\t*(?:User-)?Password=(\w+)/ ) { 
                $uid = $1;
                $password= $2;
                $password = $passwords{$password} if $opt_f;
@@ -220,7 +220,7 @@ while ($line=<STDIN>) {
                $dn=$predn.$uid.$basedn; # Start of LDIF entry
                $header = "$dn\n";
                push @userlist, $dn;
-               if ( $opt_m ) {
+               if ( $opt_m ) { 
                        $header= $header."changetype: modify\n";
                } else {
                        for (my $i=0; $i < $#objectClass+1; $i++) {
@@ -255,7 +255,7 @@ while ($line=<STDIN>) {
                                }
                } # of if line
        } # of if startentry
-
+               
 } # of while
 
 
index c21c25c..9db1ffa 100755 (executable)
@@ -14,7 +14,7 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 #    Copyright (C) 2001-2002 The FreeRADIUS Project http://www.freeradius.org
 
index abaa9c0..4aeac6c 100644 (file)
@@ -42,15 +42,15 @@ sub check_attribs {
                print "undefined parameter!\n";
                return undef;
        };
-
+       
        $attr = $_[0];
        $val  =  $_[1];
-
+       
        if ($attr !~ /Password|Framed-IP-Address|Framed-IP-Netmask|Framed-IP-Routing|Framed-Routing|Framed-IP-Route|Password|Simultaneous-Use|Idle-Timeout|Auth-Type|Service-Type|Netmask|Framed-Protocol/ ) {
                print "unrecognized attribute: $attr\n" if $debug>1;
                return undef;
        };
-
+       
        return undef if (       (! defined($val) ) or
                ( ($attr =~ /Simultaneous\-Use/i) && ( $val !~ /^[0-9]*$/ ) )
                );
@@ -75,10 +75,10 @@ sub user_attribute {
        $duser=$_[1];
        $dattrib=$_[2];
        $dval=$_[3];
-
+       
        print "inserting \"$dattrib\", \"$dval\" for \"$duser\" in rad$dtable\n" if ( $dtable !~ /group/ and $debug>2);
        print "inserting \"$duser\" into usergroup table as member of \"$dattrib\"\n" if ( $dtable =~ /group/ and $debug>2);
-
+       
        if ( $dtable =~ /group/ ) {
                $table = "usergroup";
        } elsif ( $dtable =~ /check/ ) {
@@ -88,7 +88,7 @@ sub user_attribute {
        } else {
                die "argh! what table is $dtable?\n";
        };
-
+       
 
        if ( $table =~ /usergroup/ ) {
                if ( $dattrib =~ /static/ ) {
@@ -96,7 +96,7 @@ sub user_attribute {
                        $return = $database->do ("DELETE FROM `$table` WHERE `UserName`='$duser' LIMIT 1");
                };
                $return = $database->do ("INSERT INTO `$table` SET `UserName`='$duser',`GroupName`='$dattrib'");
-
+               
        } else {
                $return = $database->do ("INSERT INTO `$table` SET `UserName`='$duser',`Attribute`='$dattrib',`Value`='$dval', `op`=':='");
        };
@@ -111,7 +111,7 @@ while (<USERS>) {
        next if ( /^\#/ );
        next if ( /^$/ );
        next if ( /^\s*$/ );
-
+       
        if ( /^[a-zA-Z0-9]+/ ) {
                print "located a user entry: $_\n" if $debug>6;
                ($user,$rest) = split /\s/, $_, 2;
@@ -123,7 +123,7 @@ while (<USERS>) {
                # Already found the user, now finding attributes...
                @attribs = $_;
        };
-
+       
        foreach $attr (@attribs) {
                ($attrib,$value) = split /=/, $attr, 2;
                #TODO: insert sanity checks here!
@@ -134,13 +134,13 @@ while (<USERS>) {
                        next;
                };
                print "attrib: $attrib has value: $value\n" if $debug>8;
-
+       
                if ( $attrib =~ /Framed-IP-Address/ ) {
                        #user is a static IP user...
                        $static{$user} = 1;
                        user_attribute("group",$user,"static","");
                };
-
+       
                if ( $attrib =~ /Password|Simultaneous-Use/ ) {
                        #This is an individual check attribute, so we'll pass it along...
                        user_attribute("check",$user,$attrib,$value);
@@ -150,7 +150,7 @@ while (<USERS>) {
                        user_attribute("reply",$user,$attrib,$value);
                };
        };
-
+       
 };
 
 close USERS;
diff --git a/scripts/xpextensions b/scripts/xpextensions
new file mode 100644 (file)
index 0000000..4a1f01f
--- /dev/null
@@ -0,0 +1,8 @@
+#
+#  For use with the 'CA.all' script.
+#
+[ xpclient_ext]
+extendedKeyUsage = 1.3.6.1.5.5.7.3.2
+
+[ xpserver_ext]
+extendedKeyUsage = 1.3.6.1.5.5.7.3.1
diff --git a/share/Makefile b/share/Makefile
deleted file mode 100644 (file)
index ab342b4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-#      Scripts to format dictionary files.
-#
-#      $Id$
-#
-.PHONY: format
-
-#
-#  This should only be run by hand, and then sanity checked by hand!
-#
-format: dictionary*
-       @for x in dictionary* ; do \
-               cat $$x | ./format.pl > tmp; \
-               mv tmp $$x; \
-       done
index 98bf225..3e685a3 100644 (file)
@@ -85,8 +85,8 @@ $INCLUDE dictionary.alcatel
 $INCLUDE dictionary.alteon
 $INCLUDE dictionary.alvarion
 $INCLUDE dictionary.aruba
-$INCLUDE dictionary.azaire
 $INCLUDE dictionary.ascend
+$INCLUDE dictionary.asn
 $INCLUDE dictionary.bay
 $INCLUDE dictionary.bintec
 $INCLUDE dictionary.cablelabs
@@ -137,6 +137,7 @@ $INCLUDE dictionary.riverstone
 $INCLUDE dictionary.roaringpenguin
 $INCLUDE dictionary.shasta
 $INCLUDE dictionary.shiva
+$INCLUDE dictionary.sofaware
 $INCLUDE dictionary.sonicwall
 $INCLUDE dictionary.springtide
 $INCLUDE dictionary.starent
index 4819471..9de40d9 100644 (file)
@@ -1,16 +1,15 @@
 # -*- text -*-
-##############################################################################
 #
-#      Ascend dictionary.
+# Ascend dictionary.
+# $Id$
 #
-#      $Id$
+#              Enable by putting the line "$INCLUDE dictionary.ascend" into
+#              the main dictionary file.
 #
-##############################################################################
-
-#
-#      For 16-bit Ascend VSA's, see dictionary.lucent.  Those VSA's
-#      are in the Lucent namespace, and belong in that file, rather
-#      than here.
+# Version:     1.00  21-Jul-1997  Jens Glaser <jens@regio.net>
+#              1.01  22-Jan-1998  Tomas Pospisek <tpo@spin.ch>
+#              1.2   28-Sept-2000 Chris Adams <cmadams@hiwaay.net>
+#              1.3   12-Dec-2000 Miquel van Smoorenburg <miquels@cistron.nl>
 #
 #
 #  The Ascend-Data-Filter and Ascend-Call-Filter are case insensitive
index 8a64e4d..7bef948 100755 (executable)
@@ -75,8 +75,8 @@ VALUE ASN-Webfilter-Mode              Allow                   2
 #         query string of %u, but note for convenience
 #         without the leading "/".
 #    %t - matched destination group or "unknown"
-#    %u - requested URL
-#    %% - single '%'
+#    %u - requested URL                  
+#    %% - single '%'                          
 #
 ATTRIBUTE      ASN-Webfilter-Redirect                  114     string
 
diff --git a/share/dictionary.azaire b/share/dictionary.azaire
deleted file mode 100644 (file)
index 1a536ac..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# -*- text -*-
-##############################################################################
-#
-#      Azaire VSAs
-#
-#      $Id$
-#
-##############################################################################
-
-VENDOR         Azaire                          7751
-
-BEGIN-VENDOR   Azaire
-
-ATTRIBUTE      Azaire-Triplets                         1       octets
-ATTRIBUTE      Azaire-IMSI                             2       octets
-ATTRIBUTE      Azaire-MSISDN                           3       octets
-ATTRIBUTE      Azaire-APN                              4       string
-ATTRIBUTE      Azaire-QoS                              5       octets
-ATTRIBUTE      Azaire-Selection-Mode                   6       integer
-ATTRIBUTE      Azaire-APN-Resolution-Req               7       integer
-ATTRIBUTE      Azaire-Start-Time                       8       octets
-ATTRIBUTE      Azaire-NAS-Type                         9       integer
-ATTRIBUTE      Azaire-Status                           10      integer
-ATTRIBUTE      Azaire-APN-OI                           11      string
-ATTRIBUTE      Azaire-Auth-Type                        12      integer
-ATTRIBUTE      Azaire-Gn-User-Name                     13      string
-ATTRIBUTE      Azaire-Brand-Code                       14      string
-ATTRIBUTE      Azaire-Policy-Name                      15      string
-ATTRIBUTE      Azaire-Client-Local-IP                  16      ipaddr
-
-VALUE  Azaire-Selection-Mode           Subscribed              0
-VALUE  Azaire-Selection-Mode           Sent-By-MS              1
-VALUE  Azaire-Selection-Mode           Chosen-By-SGSN          2
-
-VALUE  Azaire-APN-Resolution-Req       Not-Required            0
-VALUE  Azaire-APN-Resolution-Req       Required                1
-
-VALUE  Azaire-Status                   Success                 0
-VALUE  Azaire-Status                   Failure                 1
-
-VALUE  Azaire-Auth-Type                PPP-SIM                 1
-VALUE  Azaire-Auth-Type                Dummy-IMSI              2
-VALUE  Azaire-Auth-Type                Soft-SIM                3
-VALUE  Azaire-Auth-Type                Radius-SIM              4
-VALUE  Azaire-Auth-Type                Post-paid               5
-VALUE  Azaire-Auth-Type                Pre-paid                6
-VALUE  Azaire-Auth-Type                Local-Radius            7
-VALUE  Azaire-Auth-Type                Proxy-Radius            8
-
-END-VENDOR     Azaire
diff --git a/share/dictionary.chillispot b/share/dictionary.chillispot
deleted file mode 100644 (file)
index 15b3c63..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- text -*-
-##############################################################################
-#
-#      ChilliSpot captive portal
-#      http://www.chillispot.org
-#
-#      $Id$
-#
-##############################################################################
-
-VENDOR         ChilliSpot                      14559
-
-BEGIN-VENDOR   ChilliSpot
-
-ATTRIBUTE      ChilliSpot-Max-Input-Octets             1       integer
-ATTRIBUTE      ChilliSpot-Max-Output-Octets            2       integer
-ATTRIBUTE      ChilliSpot-Max-Total-Octets             3       integer
-
-# Configuration management parameters
-ATTRIBUTE      ChilliSpot-UAM-Allowed                  100     string
-ATTRIBUTE      ChilliSpot-MAC-Allowed                  101     string
-ATTRIBUTE      ChilliSpot-Interval                     102     integer
-
-# Inline with RFC 2882 use of VSE-Authorize-Only for remote config
-# Note that 14559 = 0x38df is used as prefix for the VSE.
-# This is recognized as the best (but bad) way of doing VSEs.
-#
-VALUE  Service-Type                    ChilliSpot-Authorize-Only 0x38df0001
-
-END-VENDOR     ChilliSpot
index 08b43a5..ef9377a 100644 (file)
 #
 # http://www.cisco.com/univercd/cc/td/doc/product/access/acs_serv/vapp_dev/vsaig3.htm
 #
-#  For general documentation on Cisco RADIUS configuration, see:
-#
-# http://www.cisco.com/en/US/partner/tech/tk583/tk547/tsd_technology_support_sub-protocol_home.html
-#
 
 VENDOR         Cisco                           9
 
index dbb6794..a58ee06 100644 (file)
@@ -56,8 +56,7 @@ ATTRIBUTE     EAP-Type                                1018    integer
 ATTRIBUTE      EAP-TLS-Require-Client-Cert             1019    integer
 ATTRIBUTE      EAP-Id                                  1020    integer
 ATTRIBUTE      EAP-Code                                1021    integer
-# Attribute 1022 unused, was EAP-MD5-Password, which was
-# used only be radeapclient.  It's been replaced by Cleartext-Password
+ATTRIBUTE      EAP-MD5-Password                        1022    string
 ATTRIBUTE      PEAP-Version                            1023    integer
 
 #
@@ -122,8 +121,6 @@ ATTRIBUTE   Cache-No-Caching                        1091    string
 ATTRIBUTE      Cache-Delete-Cache                      1092    string
 ATTRIBUTE      SHA-Password                            1093    octets
 ATTRIBUTE      SSHA-Password                           1094    octets
-ATTRIBUTE      SHA1-Password                           1093    octets
-ATTRIBUTE      SSHA1-Password                          1094    octets
 ATTRIBUTE      MD5-Password                            1095    octets
 ATTRIBUTE      SMD5-Password                           1096    octets
 ATTRIBUTE      Packet-Src-IPv6-Address                 1097    ipv6addr
@@ -353,16 +350,18 @@ VALUE     Packet-Type                     Terminate-Session       31
 VALUE  Packet-Type                     Password-Expired        32
 VALUE  Packet-Type                     Event-Request           33
 VALUE  Packet-Type                     Event-Response          34
-
-#      RFC 3576 allocates packet types 40-45
-
 VALUE  Packet-Type                     Disconnect-Request      40
 VALUE  Packet-Type                     Disconnect-ACK          41
 VALUE  Packet-Type                     Disconnect-NAK          42
+
+# Old names, if no one uses them, they should be deleted.
+VALUE  Packet-Type                     CoF-Request             43
+VALUE  Packet-Type                     CoF-ACK                 44
+VALUE  Packet-Type                     CoF-NAK                 45
+
 VALUE  Packet-Type                     CoA-Request             43
 VALUE  Packet-Type                     CoA-ACK                 44
 VALUE  Packet-Type                     CoA-NAK                 45
-
 VALUE  Packet-Type                     IP-Address-Allocate     50
 VALUE  Packet-Type                     IP-Address-Release      51
 
index f6b18e2..5723fa4 100644 (file)
@@ -7,7 +7,7 @@
 #
 ##############################################################################
 
-VENDOR         HP                              11
+VENDOR         HP                              11 
 
 # Management authorization
 BEGIN-VENDOR   HP
index 7341e44..38bbdb6 100644 (file)
@@ -320,8 +320,6 @@ ATTRIBUTE   Lucent-User-Login-Level                 307     integer
 ATTRIBUTE      Lucent-First-Level-User                 308     string
 ATTRIBUTE      Lucent-IP-Source-If                     309     string
 ATTRIBUTE      Lucent-Reverse-Path-Check               310     integer
-ATTRIBUTE      Lucent-LCP-Keepalive-Period             321     integer
-ATTRIBUTE      Lucent-LCP-Keepalive-Missed-Limit       322     integer
 ATTRIBUTE      Lucent-Dsl-Atuc-Chan-Uncorrect-Blks     10000   integer
 ATTRIBUTE      Lucent-Dsl-Atuc-Chan-Corrected-Blks     10001   integer
 ATTRIBUTE      Lucent-Dsl-Atuc-Chan-Xmit-Blks          10002   integer
diff --git a/share/dictionary.nortel b/share/dictionary.nortel
deleted file mode 100644 (file)
index 88b62a7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- text -*-
-##############################################################################
-#
-#      Nortel Passport 8600 VSA's.
-#
-#      http://www142.nortelnetworks.com/bvdoc/setips/july04/engineeringtipstricksv12.pdf
-#
-#      $Id$
-#
-##############################################################################
-
-VENDOR         Nortel                          562
-BEGIN-VENDOR   Nortel
-
-ATTRIBUTE      Passport-Command-Scope                  200     integer
-ATTRIBUTE      Passport-Command-Impact                 201     integer
-ATTRIBUTE      Passport-Customer-Identifier            202     integer
-ATTRIBUTE      Passport-Allowed-Access                 203     integer
-ATTRIBUTE      Passport-AllowedOut-Access              204     integer
-ATTRIBUTE      Passport-Login-Directory                205     string
-ATTRIBUTE      Passport-Timeout-Protocol               206     integer
-ATTRIBUTE      Passport-Role                           207     string
-
-END-VENDOR     Nortel
index 740f6b5..9f75423 100644 (file)
@@ -1,5 +1,5 @@
-#
-# dictionary.patton
+# 
+# dictionary.patton 
 #               Dictionary for Patton IADs.
 #               Written by Pawel Pierscionek <pawel@voiceworks.pl>
 #               based on specifications available from vendor
@@ -7,21 +7,21 @@
 # Version:      @(#)dictionary.patton  1.00  urtho  08-Sep-2006
 #  $Id$
 
-VENDOR         Patton                          1768
+VENDOR         Patton                          1768    
 
 BEGIN-VENDOR   Patton
 
-ATTRIBUTE      Patton-Setup-Time                               32      string
-ATTRIBUTE      Patton-Connect-Time                             33      string
+ATTRIBUTE      Patton-Setup-Time                               32      string  
+ATTRIBUTE      Patton-Connect-Time                             33      string  
 ATTRIBUTE      Patton-Disconnect-Time                          34      string
 ATTRIBUTE      Patton-Disconnect-Cause                         35      integer
 ATTRIBUTE      Patton-Disconnect-Source                        36      string
-ATTRIBUTE      Patton-Called-Unique-Id                         48      string
+ATTRIBUTE      Patton-Called-Unique-Id                         48      string  
 ATTRIBUTE      Patton-Called-IP-Address                        49      ipaddr
 ATTRIBUTE      Patton-Called-Numbering-Plan                    50      string
 ATTRIBUTE      Patton-Called-Type-Of-Number                    51      string
 ATTRIBUTE      Patton-Calling-Unique-Id                        80      string
-ATTRIBUTE      Patton-Calling-IP-Address                       81      ipaddr
+ATTRIBUTE      Patton-Calling-IP-Address                       81      ipaddr  
 ATTRIBUTE      Patton-Calling-Numbering-Plan                   82      string
 ATTRIBUTE      Patton-Calling-Type-Of-Number                   83      string
 ATTRIBUTE      Patton-Calling-Presentation-Indicator           88      string
diff --git a/share/dictionary.rfc4590 b/share/dictionary.rfc4590
new file mode 100644 (file)
index 0000000..0332dd2
--- /dev/null
@@ -0,0 +1,23 @@
+# -*- text -*-
+#
+#       Attributes and values defined in RFC 4590.
+#       http://www.ietf.org/rfc/rfc4590.txt
+#       Previously defined in draft-sterman-aaa-sip-00.txt
+#
+#       $Id$
+#
+ATTRIBUTE      Digest-Response                         206     string
+ATTRIBUTE      Digest-Attributes                       207     octets  # stupid format
+
+BEGIN-SUB-ATTR Digest-Attributes
+ATTRIBUTE      Digest-Realm                            1       string
+ATTRIBUTE      Digest-Nonce                            2       string
+ATTRIBUTE      Digest-Method                           3       string
+ATTRIBUTE      Digest-URI                              4       string
+ATTRIBUTE      Digest-QOP                              5       string
+ATTRIBUTE      Digest-Algorithm                        6       string
+ATTRIBUTE      Digest-Body-Digest                      7       string
+ATTRIBUTE      Digest-CNonce                           8       string
+ATTRIBUTE      Digest-Nonce-Count                      9       string
+ATTRIBUTE      Digest-User-Name                        10      string
+END-SUB-ATTR
diff --git a/share/dictionary.rfc4818 b/share/dictionary.rfc4818
deleted file mode 100644 (file)
index c18b850..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- text -*-
-##############################################################################
-#
-#      Attributes and values defined in RFC 4818.
-#      http://www.ietf.org/rfc/rfc4818.txt
-#
-#      $Id$
-#
-##############################################################################
-
-ATTRIBUTE      Delegated-IPv6-Prefix                   123     ipv6prefix
index eb31d2d..9592063 100644 (file)
@@ -15,13 +15,13 @@ BEGIN-VENDOR        Roaring-Penguin
 ATTRIBUTE      RP-Upstream-Speed-Limit                 1       integer
  # Downstream speed limit in kb/s
 ATTRIBUTE      RP-Downstream-Speed-Limit               2       integer
-
 # Send a HURL
 ATTRIBUTE      RP-HURL                                 3       string
-
 # Send a MOTM
 ATTRIBUTE      RP-MOTM                                 4       string
-
 # Maximum sessions per user
 ATTRIBUTE      RP-Max-Sessions-Per-User                5       integer
 
diff --git a/share/dictionary.schulzrinne-sipping b/share/dictionary.schulzrinne-sipping
new file mode 100644 (file)
index 0000000..9a32865
--- /dev/null
@@ -0,0 +1,31 @@
+# http://www.freeradius.org/rfc/draft-schulzrinne-sipping-radius-accounting-00.txt
+#
+# $Id$
+#
+
+
+ATTRIBUTE Sip-Method                   101  integer
+ATTRIBUTE Sip-Response-Code            102  integer
+ATTRIBUTE Sip-Cseq                     103  string
+ATTRIBUTE Sip-To-Tag                   104  string
+ATTRIBUTE Sip-From-Tag                 105  string
+ATTRIBUTE Sip-Branch-ID                106  string
+ATTRIBUTE Sip-Translated-Request-ID    107  string
+ATTRIBUTE Sip-Source-IP-Address        108  ipaddr
+ATTRIBUTE Sip-Source-Port              109  integer
+
+
+### Service-Type Values ###
+VALUE Service-Type       Sip-Session      15
+
+
+### Sip-Method Values ###
+VALUE Sip-Method         INVITE         0
+VALUE Sip-Method         BYE            1
+VALUE Sip-Method         REGISTER       2
+VALUE Sip-Method         CANCEL         3
+VALUE Sip-Method         OPTIONS        4
+VALUE Sip-Method         ACK            5
+VALUE Sip-Method         SUBSCRIBE      6
+VALUE Sip-Method         NOTIFY         7
+
index cad3ded..56eb275 100755 (executable)
 $begin_vendor = 0;
 $blank = 0;
 
-while (@ARGV) {
-    $filename = shift;
-
-    open FILE, "<$filename" or die "Failed to open $filename: $!\n";
-
-    @output = ();
-
-    while (<FILE>) {
-       #
-       #  Clear out trailing whitespace
-       #
-       s/[ \t]+$//;
-
-       #
-       #  And CR's
-       #
-       s/\r//g;
-
-       #
-       #  Suppress multiple blank lines
-       #
-       if (/^\s+$/) {
-           next if ($blank == 1);
-           $blank = 1;
-           push @output, "\n";
-           next;
+while (<>) {
+    #
+    #  Clear out trailing whitespace
+    #
+    s/[ \t]+$//;
+
+    #
+    #  And CR's
+    #
+    s/\r//g;
+
+    #
+    #  Suppress multiple blank lines
+    #
+    if (/^\s+$/) {
+       next if ($blank == 1);
+       $blank = 1;
+       print "\n";
+       next;
+    }
+    $blank = 0;
+
+    #
+    #  Remember the vendor
+    #
+    if (/^VENDOR\s+([\w-]+)\s+(\w+)(.*)/) {
+       $name=$1;
+       $len = length $name;
+       if ($len < 32) {
+           $lenx = 32 - $len;
+           $lenx += 7;         # round up
+           $lenx /= 8;
+           $lenx = int $lenx;
+           $tabs = "\t" x $lenx;
+       } else {
+           $tabs = " ";
        }
-       $blank = 0;
+       print "VENDOR\t\t$name$tabs$2$3\n";
+       $vendor = $name;
+       next;
+    }
 
-       #
-       #  Remember the vendor
-       #
-       if (/^VENDOR\s+([\w-]+)\s+(\w+)(.*)/) {
-           $name=$1;
-           $len = length $name;
-           if ($len < 32) {
-               $lenx = 32 - $len;
-               $lenx += 7;             # round up
-               $lenx /= 8;
-               $lenx = int $lenx;
-               $tabs = "\t" x $lenx;
-           } else {
+    #  
+    #  Remember if we did begin-vendor.
+    #
+    if (/^BEGIN-VENDOR\s+([\w-]+)/) {
+       $begin_vendor = 1;
+       print "BEGIN-VENDOR\t$vendor\n";
+       next;
+    }
+
+    #
+    #  Get attribute.
+    #
+    if (/^ATTRIBUTE\s+([\w-]+)\s+(\w+)\s+(\w+)(.*)/) {
+       $name=$1;
+       $len = length $name;
+       if ($len < 40) {
+           $lenx = 40 - $len;
+           $lenx += 7;         # round up
+           $lenx /= 8;
+           $lenx = int $lenx;
+           $tabs = "\t" x $lenx;
+           if ($tabs eq "") {
                $tabs = " ";
            }
-           push @output, "VENDOR\t\t$name$tabs$2$3\n";
-           $vendor = $name;
-           next;
+       } else {
+           $tabs = " ";
        }
 
+       $value = $2;
+       $type = $3;
+       $stuff = $4;
+
        #
-       #  Remember if we did begin-vendor.
+       #  See if it's old format, with the vendor at the end of
+       #  the line.  If so, make it the new format.
        #
-       if (/^BEGIN-VENDOR\s+([\w-]+)/) {
-           $begin_vendor = 1;
-           if (!defined $vendor) {
-               $vendor = $1;
-           } elsif ($vendor ne $1) {
-               # do something smart
+       if ($stuff =~ /$vendor/) {
+           if ($begin_vendor == 0) {
+               print "BEGIN-VENDOR\t$vendor\n\n";
+               $begin_vendor = 1;
            }
-
-           push @output, "BEGIN-VENDOR\t$vendor\n";
-           next;
+           $stuff =~ s/$vendor//;
+           $stuff =~ s/\s+$//;
        }
 
-       #
-       #  Get attribute.
-       #
-       if (/^ATTRIBUTE\s+([\w-]+)\s+(\w+)\s+(\w+)(.*)/) {
-           $name=$1;
-           $len = length $name;
-           if ($len < 40) {
-               $lenx = 40 - $len;
-               $lenx += 7;             # round up
-               $lenx /= 8;
-               $lenx = int $lenx;
-               $tabs = "\t" x $lenx;
-               if ($tabs eq "") {
-                   $tabs = " ";
-               }
-           } else {
-               $tabs = " ";
-           }
+       print "ATTRIBUTE\t$name$tabs$value\t$type$stuff\n";
+       next;
+    }
 
-           $value = $2;
-           $type = $3;
-           $stuff = $4;
-
-           #
-           #  See if it's old format, with the vendor at the end of
-           #  the line.  If so, make it the new format.
-           #
-           if ($stuff =~ /$vendor/) {
-               if ($begin_vendor == 0) {
-                   push @output, "BEGIN-VENDOR\t$vendor\n\n";
-                   $begin_vendor = 1;
-               }
-               $stuff =~ s/$vendor//;
-               $stuff =~ s/\s+$//;
+    #
+    #  Values.
+    #
+    if (/^VALUE\s+([\w-]+)\s+([\w-\/,.]+)\s+(\w+)(.*)/) {
+       $attr=$1;
+       $len = length $attr;
+       if ($len < 32) {
+           $lenx = 32 - $len;
+           $lenx += 7;         # round up
+           $lenx /= 8;
+           $lenx = int $lenx;
+           $tabsa = "\t" x $lenx;
+           if ($tabsa eq "") {
+               $tabsa = " ";
+               $len += 1;
+           } else {
+               $len -= $len % 8;
+               $len += 8 * length $tabsa;
            }
-
-           push @output, "ATTRIBUTE\t$name$tabs$value\t$type$stuff\n";
-           next;
+       } else {
+           $tabsa = " ";
+           $len += 1;
        }
 
        #
-       #  Values.
+       #  For the code below, we assume that the attribute lengths
        #
-       if (/^VALUE\s+([\w-]+)\s+([\w-\/,.]+)\s+(\w+)(.*)/) {
-           $attr=$1;
-           $len = length $attr;
-           if ($len < 32) {
-               $lenx = 32 - $len;
-               $lenx += 7;             # round up
-               $lenx /= 8;
-               $lenx = int $lenx;
-               $tabsa = "\t" x $lenx;
-               if ($tabsa eq "") {
-                   $tabsa = " ";
-                   $len += 1;
-               } else {
-                   $len -= $len % 8;
-                   $len += 8 * length $tabsa;
-               }
-           } else {
-               $tabsa = " ";
-               $len += 1;
-           }
-
-           #
-           #  For the code below, we assume that the attribute lengths
-           #
-           if ($len < 32) {
-               $lena = 0;
-           } else {
-               $lena = $len - 32;
-           }
+       if ($len < 32) {
+           $lena = 0;
+       } else {
+           $lena = $len - 32;
+       }
 
-           $name = $2;
-           $len = length $name;
-           if ($len < 24) {
-               $lenx = 24 - $lena - $len;
-               $lenx += 7;             # round up
-               $lenx /= 8;
-               $lenx = int $lenx;
-               $tabsn = "\t" x $lenx;
-               if ($tabsn eq "") {
-                   $tabsn = " ";
-               }
-           } else {
+       $name = $2;
+       $len = length $name;
+       if ($len < 24) {
+           $lenx = 24 - $lena - $len;
+           $lenx += 7;         # round up
+           $lenx /= 8;
+           $lenx = int $lenx;
+           $tabsn = "\t" x $lenx;
+           if ($tabsn eq "") {
                $tabsn = " ";
            }
-
-           push @output, "VALUE\t$attr$tabsa$name$tabsn$3$4\n";
-           next;
+       } else {
+           $tabsn = " ";
        }
 
-       #
-       #  Remember if we did this.
-       #
-       if (/^END-VENDOR/) {
-           $begin_vendor = 0;
-       }
+       print "VALUE\t$attr$tabsa$name$tabsn$3$4\n";
+       next;
+    }
 
-       #
-       #  Everything else gets dumped out as-is.
-       #
-       push @output, $_;
+    #
+    #  Remember if we did this.
+    #
+    if (/^END-VENDOR/) {
+       $begin_vendor = 0;
     }
 
+    #
+    #  Everything else gets dumped out as-is.
+    #
+    print;
+}
+
 #
 #  If we changed the format, print the end vendor, too.
 #
-    if ($begin_vendor) {
-       push @output, "\nEND-VENDOR\t$vendor\n";
-    }
-
-    close FILE;
-
-    open FILE, ">$filename" or die "Failed to open $filename: $!\n";
-
-    print FILE @output;
-
-    close FILE;
+if ($begin_vendor) {
+    print "\nEND-VENDOR\t$vendor\n";
 }
index bfd5272..2e8fb1e 100644 (file)
@@ -9,7 +9,7 @@ include ../Make.inc
 SUBDIRS                = include lib modules main
 WHAT_TO_MAKE   = all
 
-all: freeradius-devel
+all:
        @$(MAKE) $(MFLAGS) WHAT_TO_MAKE=$@ common
 
 clean:
@@ -24,6 +24,3 @@ common:
                echo "Making $(WHAT_TO_MAKE) in $$dir..."; \
                $(MAKE) $(MFLAGS) -C $$dir $(WHAT_TO_MAKE) || exit $$?; \
        done
-
-freeradius-devel:
-       ln -s include freeradius-devel
index da38d60..c3a91b9 100644 (file)
@@ -63,18 +63,25 @@ CONFIGURATION
        "gw-accounting aaa"
        "radius-server vsa send"
 
+* In /etc/raddb/radiusd.conf set "with_cisco_vsa_hack = yes"
+
 * Create a Database to hold your billing records. ie:
        "createdb radius"
+* Add the plperl language to the database. ie:
+       "createlang plpgsql radius"
 
 * Import the SQL schema to your database. ie:
-       "psql radius < cisco_h323_db_schema-postgres.sql"
+       "psql radius < h323_db_postgresql.sql"
 
-* In /etc/raddb/radiusd.conf set "with_cisco_vsa_hack = yes"
+* Copy the custom SQL queries to raddb/ ie:
+       "cp pgsql-voip.conf /etc/raddb/"
 
 * In /etc/raddb/radiusd.conf add "$INCLUDE  ${confdir}/pgsql-voip.conf"
-  (You can find the correct section by searching for "sql.conf")
+  You can find the correct section by searching for "sql.conf"
+
 
-* In /etc/raddb/radiusd.conf add "pgsql-voip" to the "accounting { }" section.
+* In /etc/raddb/radiusd.conf add "pgsql-voip" to the "accounting {" section
+  just after the line "detail"
 
 * (re)Start radiusd
 
index c954c93..c9cef80 100644 (file)
@@ -1,8 +1,20 @@
--- Id: postgresql.conf,v 1.8.2.11 2003/07/15 11:15:43 pnixon Exp $
-
--- create plpgsql language
-CREATE FUNCTION "plpgsql_call_handler" () RETURNS LANGUAGE_HANDLER AS '$libdir/plpgsql' LANGUAGE C;
-CREATE TRUSTED LANGUAGE "plpgsql" HANDLER "plpgsql_call_handler";
+/*
+ * Id: postgresql.conf,v 1.8.2.11 2003/07/15 11:15:43 pnixon Exp $
+ *
+ * Old Function 'strip_dot' Now replaced by one written plpgsql
+ *
+ * Note: On SuSE Linux 8.0 and 8.1 you need to do the following from the command line before
+ *       plperl functions will work.
+ *
+ * # ln -s /usr/lib/perl5/5.8.0/i586-linux-thread-multi/CORE/libperl.so /usr/lib/libperl.so
+ * # createlang -U postgres plperl radius
+ *
+ *     CREATE OR REPLACE FUNCTION strip_dot_in_perl (text) returns timestamp AS '
+ *             my $datetime = $_[0];
+ *             $datetime =~ s/^\\.*//;
+ *             return $datetime;
+ *     ' language 'plperl';
+ */
 
 
 CREATE OR REPLACE FUNCTION chop_number(VARCHAR) RETURNS VARCHAR AS '
@@ -81,35 +93,14 @@ CREATE OR REPLACE FUNCTION chop_number_number(VARCHAR) RETURNS VARCHAR AS '
  END;
 ' LANGUAGE 'plpgsql';
 
--- Some sample database VIEWs to simplify billing queries.
-
-CREATE OR REPLACE VIEW StartVoIPd AS
-SELECT DISTINCT ON(h323SetupTime, CallID) * FROM StartVoIP;
-
-CREATE OR REPLACE VIEW StopVoIPd AS
-SELECT DISTINCT ON(h323SetupTime, CallID) * FROM StopVoIP;
-
-
-CREATE OR REPLACE VIEW call_history_csps2 AS
-SELECT StartVoIP.h323ConnectTime, StopVoIP.h323DisconnectTime, (EXTRACT(EPOCH FROM(StopVoIP.h323DisconnectTime - StartVoIP.h323ConnectTime)))::BIGINT AS CallLength, StopVoIP.CalledStationId AS Number, StopVoIP.UserName AS UserName, StopVoIP.CallingStationId AS CallerID, StopVoIP.CallID
-FROM StopVoIPd AS StopVoIP LEFT OUTER JOIN StartVoIPd AS StartVoIP
-ON (StopVoIP.CallID = StartVoIP.CallID)
-WHERE StopVoIP.NASIPAddress = '212.50.54.122'
-ORDER BY StartVoIP.h323ConnectTime;
-
-CREATE OR REPLACE VIEW call_history_csps AS
-SELECT CAST ((h323DisconnectTime::date AT TIME ZONE 'UTC') AS date) AS Date, CAST ((h323DisconnectTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, AcctSessionTime AS Length, CalledStationId AS Number, UserName AS UserName, CallingStationId AS CallerID, CallID
-FROM StopVoIP
-WHERE NASIPAddress = '212.50.54.122';
-
-CREATE OR REPLACE VIEW call_history AS
-SELECT CAST ((h323SetupTime::date AT TIME ZONE 'UTC') AS date) AS Date, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, AcctSessionTime AS Length, CalledStationId AS Number, UserName AS UserName, CallingStationId AS CallerID, H323RemoteAddress, NASIPAddress, CallID
-FROM StopVoIP;
+/*
+ * Some sample database VIEWs to simplify billing queries.
+ */
 
 CREATE OR REPLACE VIEW call_history AS
 SELECT CAST ((pots.h323SetupTime::date AT TIME ZONE 'UTC') AS date) AS Date, CAST ((pots.h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, pots.AcctSessionTime AS Length, pots.CalledStationId AS Number, ip.H323RemoteAddress AS cust_ip, ip.NASIPAddress AS gw_ip
 FROM StopTelephony AS pots LEFT OUTER JOIN StopVoIP AS ip
-ON (pots.CallID = ip.CallID);
+ON (pots.h323ConfID = ip.h323ConfID);
 
 CREATE OR REPLACE VIEW call_history_customer AS
 SELECT Date, Time, Length, Number, cust_ip, gw_ip, CustomerIP.Company AS Company
@@ -122,15 +113,15 @@ FROM customers  AS cust, cust_gw AS gw
 WHERE cust.cust_id = gw.cust_id;
 
 CREATE OR REPLACE VIEW VoIP AS
-SELECT RadAcctId AS ID, NASIPAddress AS GWIP, AcctSessionTime AS Call_Seconds, chop_number_country(CalledStationId) AS Country, chop_number_city(CalledStationId) AS City,chop_number_number(CalledStationId) AS Number, chop_number(CalledStationId) AS Original_Number, EXTRACT(YEAR FROM (h323setuptime AT TIME ZONE 'UTC')) AS Year, EXTRACT(MONTH FROM (h323setuptime AT TIME ZONE 'UTC')) AS Month, EXTRACT(DAY FROM (h323setuptime AT TIME ZONE 'UTC')) AS Day, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, h323DisconnectCause AS error_code, H323RemoteAddress AS Remote_IP, CallID
+SELECT RadAcctId AS ID, NASIPAddress AS GWIP, AcctSessionTime AS Call_Seconds, chop_number_country(CalledStationId) AS Country, chop_number_city(CalledStationId) AS City,chop_number_number(CalledStationId) AS Number, chop_number(CalledStationId) AS Original_Number, EXTRACT(YEAR FROM (h323setuptime AT TIME ZONE 'UTC')) AS Year, EXTRACT(MONTH FROM (h323setuptime AT TIME ZONE 'UTC')) AS Month, EXTRACT(DAY FROM (h323setuptime AT TIME ZONE 'UTC')) AS Day, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, h323DisconnectCause AS error_code, H323RemoteAddress AS Remote_IP, h323ConfID AS ConfID
 FROM StopVoIP;
 
 CREATE OR REPLACE VIEW Telephony AS
-SELECT RadAcctId AS ID, NASIPAddress AS GWIP, AcctSessionTime AS Call_Seconds, chop_number_country(CalledStationId) AS Country, chop_number_city(CalledStationId) AS City,chop_number_number(CalledStationId) AS Number, chop_number(CalledStationId) AS Original_Number, EXTRACT(YEAR FROM (h323setuptime AT TIME ZONE 'UTC')) AS Year, EXTRACT(MONTH FROM (h323setuptime AT TIME ZONE 'UTC')) AS Month, EXTRACT(DAY FROM (h323setuptime AT TIME ZONE 'UTC')) AS Day, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, h323DisconnectCause AS error_code, split_part(split_part(CiscoNASPort,':',1),' ',2) AS PRI, split_part(CiscoNASPort,':',3) AS PRI_channel, CiscoNASPort AS isdn_port, CallID AS ConfID
+SELECT RadAcctId AS ID, NASIPAddress AS GWIP, AcctSessionTime AS Call_Seconds, chop_number_country(CalledStationId) AS Country, chop_number_city(CalledStationId) AS City,chop_number_number(CalledStationId) AS Number, chop_number(CalledStationId) AS Original_Number, EXTRACT(YEAR FROM (h323setuptime AT TIME ZONE 'UTC')) AS Year, EXTRACT(MONTH FROM (h323setuptime AT TIME ZONE 'UTC')) AS Month, EXTRACT(DAY FROM (h323setuptime AT TIME ZONE 'UTC')) AS Day, CAST ((h323SetupTime AT TIME ZONE 'UTC') AS time without time zone) AS Time, h323DisconnectCause AS error_code, split_part(split_part(CiscoNASPort,':',1),' ',2) AS PRI, split_part(CiscoNASPort,':',3) AS PRI_channel, CiscoNASPort AS isdn_port, h323ConfID AS ConfID
 FROM StopTelephony;
 
 CREATE OR REPLACE VIEW calls AS
-SELECT Date, Time, Length, Number, cust_ip, gw_ip
+SELECT Date, Time, Length, Number, cust_ip, gw_ip 
 FROM call_history
 WHERE Length > 0
 ORDER BY Date, Time, Number, Length, cust_ip ASC;
@@ -150,6 +141,9 @@ ORDER BY H323ConnectTime, CalledStationId, H323RemoteAddress ASC;
 
 
 
+/*
+ * # createlang -U postgres plpgsql radius
+ */
 CREATE OR REPLACE FUNCTION VoIPInsertRecord(StopVoIP.UserName%TYPE, StopVoIP.NASIPAddress%TYPE, StopVoIP.AcctSessionTime%TYPE,
 StopVoIP.AcctInputOctets%TYPE, StopVoIP.AcctOutputOctets%TYPE, StopVoIP.CalledStationId%TYPE, StopVoIP.CallingStationId%TYPE,
 StopVoIP.AcctDelayTime%TYPE, StopVoIP.h323CallOrigin%TYPE, StopVoIP.h323SetupTime%TYPE, StopVoIP.h323ConnectTime%TYPE, StopVoIP.h323DisconnectTime%TYPE,
@@ -159,12 +153,12 @@ DECLARE
     key2 ALIAS FOR $2;
     key3 ALIAS FOR $16;
 BEGIN
-        PERFORM radacctid FROM StopVoIP WHERE h323SetupTime = $10 AND NASIPAddress = $2 AND CallID = $16;
+        PERFORM radacctid FROM StopVoIP WHERE h323SetupTime = $10 AND NASIPAddress = $2 AND h323confid = $16;
         IF NOT FOUND THEN
                INSERT into StopVoIP (
                 UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId,
                 AcctDelayTime, h323callorigin, h323setuptime, h323connecttime, h323disconnecttime, h323disconnectcause,
-               H323RemoteAddress, h323voicequality, CallID) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);
+               H323RemoteAddress, h323voicequality, h323confid) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);
        RETURN true;
         END IF;
         RETURN false;
@@ -174,16 +168,16 @@ END;
 CREATE OR REPLACE FUNCTION TelephonyInsertRecord(StopTelephony.UserName%TYPE, StopTelephony.NASIPAddress%TYPE, StopTelephony.AcctSessionTime%TYPE,
     StopTelephony.AcctInputOctets%TYPE, StopTelephony.AcctOutputOctets%TYPE, StopTelephony.CalledStationId%TYPE, StopTelephony.CallingStationId%TYPE,
     StopTelephony.AcctDelayTime%TYPE, StopTelephony.CiscoNASPort%TYPE, StopTelephony.h323CallOrigin%TYPE, StopTelephony.h323SetupTime%TYPE,
-    StopTelephony.h323ConnectTime%TYPE, StopTelephony.h323DisconnectTime%TYPE, StopTelephony.h323DisconnectCause%TYPE,
-    StopTelephony.H323VoiceQuality%TYPE, StopTelephony.CallID%TYPE) RETURNS BOOLEAN AS '
+    StopTelephony.h323ConnectTime%TYPE, StopTelephony.h323DisconnectTime%TYPE, StopTelephony.h323DisconnectCause%TYPE, 
+    StopTelephony.H323VoiceQuality%TYPE, StopTelephony.h323ConfID%TYPE) RETURNS BOOLEAN AS '
 DECLARE
 BEGIN
-        PERFORM radacctid FROM StopTelephony WHERE h323SetupTime = $11 AND NASIPAddress = $2 AND CallID = $16;
+        PERFORM radacctid FROM StopTelephony WHERE h323SetupTime = $11 AND NASIPAddress = $2 AND h323confid = $16;
         IF NOT FOUND THEN
                INSERT into StopTelephony (
                 UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId,
                 AcctDelayTime, CiscoNASPort, h323callorigin, h323setuptime, h323connecttime, h323disconnecttime, h323disconnectcause,
-               h323voicequality, CallID) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);
+               h323voicequality, h323confid) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);
        RETURN true;
         END IF;
         RETURN false;
index f5ec30b..ac232b1 100644 (file)
 
 CREATE TABLE StartVoIP (
        RadAcctId               BIGSERIAL PRIMARY KEY,
-       AcctTime                TIMESTAMP with time zone NOT NULL,
-       h323SetupTime           TIMESTAMP with time zone,
+       h323SetupTime           TIMESTAMP with time zone NOT NULL,
        H323ConnectTime         TIMESTAMP with time zone,
        UserName                VARCHAR(64),
        RadiusServerName        VARCHAR(32),
        NASIPAddress            INET NOT NULL,
+       AcctTime                TIMESTAMP with time zone,
        CalledStationId         VARCHAR(80),
        CallingStationId        VARCHAR(80),
        AcctDelayTime           INTEGER,
        H323GWID                VARCHAR(32),
        h323CallOrigin          VARCHAR(10),
-       CallID                  VARCHAR(80) NOT NULL,
+       CallID                  VARCHAR(50) NOT NULL,
        processed               BOOLEAN DEFAULT false
 );
-create index startvoipcombo on startvoip (AcctTime, nasipaddress);
+create index startvoipcombo on startvoip (h323SetupTime, nasipaddress);
 
 
 CREATE TABLE StartTelephony (
        RadAcctId               BIGSERIAL PRIMARY KEY,
-       AcctTime                TIMESTAMP with time zone NOT NULL,
-       h323SetupTime           TIMESTAMP with time zone,
+       h323SetupTime           TIMESTAMP with time zone NOT NULL,
        H323ConnectTime         TIMESTAMP with time zone,
        UserName                VARCHAR(64),
        RadiusServerName        VARCHAR(32),
        NASIPAddress            INET NOT NULL,
+       AcctTime                TIMESTAMP with time zone,
        CalledStationId         VARCHAR(80),
        CallingStationId        VARCHAR(80),
        AcctDelayTime           INTEGER,
        H323GWID                VARCHAR(32),
        h323CallOrigin          VARCHAR(10),
-       CallID                  VARCHAR(80) NOT NULL,
+       CallID                  VARCHAR(35) NOT NULL,
        processed               BOOLEAN DEFAULT false
 );
-create index starttelephonycombo on starttelephony (AcctTime, nasipaddress);
+create index starttelephonycombo on starttelephony (h323SetupTime, nasipaddress);
 
 
 
@@ -65,13 +65,13 @@ create index starttelephonycombo on starttelephony (AcctTime, nasipaddress);
  */
 CREATE TABLE StopVoIP (
        RadAcctId               BIGSERIAL PRIMARY KEY,
-       AcctTime                TIMESTAMP with time zone NOT NULL,
        H323SetupTime           TIMESTAMP with time zone,
        H323ConnectTime         TIMESTAMP with time zone,
-       H323DisconnectTime      TIMESTAMP with time zone,
+       H323DisconnectTime      TIMESTAMP with time zone NOT NULL,
        UserName                VARCHAR(32),
        RadiusServerName        VARCHAR(32),
        NASIPAddress            INET NOT NULL,
+       AcctTime                TIMESTAMP with time zone,
        AcctSessionTime         BIGINT,
        AcctInputOctets         BIGINT,
        AcctOutputOctets        BIGINT,
@@ -84,21 +84,28 @@ CREATE TABLE StopVoIP (
        H323DisconnectCause     VARCHAR(20),
        H323RemoteAddress       INET,
        H323VoiceQuality        INTEGER,
-       CallID                  VARCHAR(80) NOT NULL,
+       CallID                  VARCHAR(50) NOT NULL,
        processed               BOOLEAN DEFAULT false
 );
-create UNIQUE index stopvoipcombo on stopvoip (AcctTime, nasipaddress, CallID);
+create UNIQUE index stopvoipcombo on stopvoip (h323SetupTime, nasipaddress, CallID);
+/*
+ * Some Cisco CSPS do not have complete VSA details. If you have one of these you will want
+ * to use the following index, as the one above will drop records.
+ * 
+ *  create UNIQUE index stopvoipcombo on stopvoip (h323DisconnectTime, nasipaddress, CallID);
+ *
+ */
 
 
 CREATE TABLE StopTelephony (
        RadAcctId               BIGSERIAL PRIMARY KEY,
-       AcctTime                TIMESTAMP with time zone NOT NULL,
        H323SetupTime           TIMESTAMP with time zone NOT NULL,
        H323ConnectTime         TIMESTAMP with time zone NOT NULL,
        H323DisconnectTime      TIMESTAMP with time zone NOT NULL,
        UserName                VARCHAR(32) DEFAULT '' NOT NULL,
        RadiusServerName        VARCHAR(32),
        NASIPAddress            INET NOT NULL,
+       AcctTime                TIMESTAMP with time zone,
        AcctSessionTime         BIGINT,
        AcctInputOctets         BIGINT,
        AcctOutputOctets        BIGINT,
@@ -111,12 +118,12 @@ CREATE TABLE StopTelephony (
        H323DisconnectCause     VARCHAR(20),
        H323RemoteAddress       INET,
        H323VoiceQuality        INTEGER,
-       CallID                  VARCHAR(80) NOT NULL,
+       CallID                  VARCHAR(35) NOT NULL,
        processed               BOOLEAN DEFAULT false
 );
--- You can have more than one record that is identical except for CiscoNASPort if you have a dial peer hungroup
+-- You can have more than one record that is identical except for CiscoNASPort if you have a VoIP dial peer
 -- configured for multiple PRIs.
-create UNIQUE index stoptelephonycombo on stoptelephony (AcctTime, nasipaddress, CallID, CiscoNASPort);
+create UNIQUE index stoptelephonycombo on stoptelephony (h323SetupTime, nasipaddress, CallID, CiscoNASPort);
 
 /*
  * Table structure for 'gateways'
@@ -136,7 +143,7 @@ CREATE TABLE gateways (
 
 /*
  * Table structure for 'customers'
- *
+ * 
  * This table should list your Customers names and company
  * This can be used to make more useful reports.
  */
@@ -149,7 +156,7 @@ CREATE TABLE customers (
 
 /*
  * Table structure for 'cust_gw'
- *
+ * 
  * This table should list the IP addresses and Customer IDs of all your Customers gateways
  * This can be used to make more useful reports.
  */
@@ -165,10 +172,6 @@ CREATE VIEW customerip AS
     SELECT gw.cust_gw AS ipaddr, cust.company, cust.customer, gw."location" FROM customers cust, cust_gw gw WHERE (cust.cust_id = gw.cust_id);
 
 
--- create plpgsql language (You need to be a database superuser to be able to do this)
-CREATE FUNCTION "plpgsql_call_handler" () RETURNS LANGUAGE_HANDLER AS '$libdir/plpgsql' LANGUAGE C;
-CREATE TRUSTED LANGUAGE "plpgsql" HANDLER "plpgsql_call_handler";
-
 /*
  * Function 'strip_dot'
  * removes "." from the start of cisco timestamps
index 6076509..8d3050a 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 #
-# syslog2db - Extract Clarent VoIP CDRs from billing_record files and
-# insert them into a Postgresql database.
+# syslog2db - Extract Clarent VoIP CDRs from billing_record files and 
+# insert them into a Postgresql database. 
 #
 # Author:       Peter Nixon <codemonkey@peternixon.net>
 # Date:         2003-05-07
@@ -56,7 +56,7 @@ my $password    = "";
 # Defaults
 my $defaulttimezone = "UTC";
 my $defaultyear = 2003;
-my $dbh;
+my $dbh; 
 
 my %working_record = ();
 
@@ -170,7 +170,7 @@ sub record_match($) {
                if ($verbose > 1) { print "DEBUG: Clean Record: @callrecord\n"; }
                $recordno++; %working_record = ();
                $working_record{local_setuptime} = clarent2normaltime($callrecord[0]);
-                $working_record{start_time} = $callrecord[3];  # This is in Unix timetamp format, relative to the originating gateway.
+                $working_record{start_time} = $callrecord[3];  # This is in Unix timetamp format, relative to the originating gateway. 
                                                                # It is therefore useless unless ALL gateways are set with the same timezone,
                                                                # so I don't bother to convert it to datetime format.
                 $working_record{duration} = $callrecord[4];
@@ -287,14 +287,14 @@ sub main {
                        $file = @ARGV[0];
                                &file_read($file);
                }
-               if ($verbose >= 0) {
+               if ($verbose >= 0) { 
                        my $runtime = (time() - $starttime);
                        if ($runtime < 1) { $runtime = 0.5; }           # Prevent divide-by-zero errors
                        my $speed = ($recordno / $runtime);
-                       if ($fileno > 1) {
-                               print "\n$recordno records from $lineno lines in $fileno files were processed in ~$runtime seconds (~$speed records/sec)\n";
+                       if ($fileno > 1) { 
+                               print "\n$recordno records from $lineno lines in $fileno files were processed in ~$runtime seconds (~$speed records/sec)\n"; 
                        } else {
-                               print "\n$recordno records from $lineno lines in $file were processed in ~$runtime seconds (~$speed records/sec)\n";
+                               print "\n$recordno records from $lineno lines in $file were processed in ~$runtime seconds (~$speed records/sec)\n"; 
                        }
                }
 
index 28ff402..51a1650 100755 (executable)
@@ -1,16 +1,18 @@
 #!/usr/bin/perl
 #
 # Author:       Peter Nixon <codemonkey@peternixon.net>
+# Date:         August 2002 
 # Summary:      Extract information from Radius detail log and
 #              compare/insert/update a Postgresql database.
-# Copy Policy:  GNU Public Licence Version 2
+# Copy Policy:  GNU Public Licence Version 2 or later
 # URL:          http://www.peternixon.net/code/
-# Supported:    PostgreSQL (tested on version 7.2, 7.3, 7.4 and 8) and FreeRadius
-# Copyright:    2004 Peter Nixon http://www.petenixon.net
+# Supported:    PostgreSQL (tested on version 7.2 and 7.3.x) and FreeRadius
+# Copyright:    2002, 2003 Peter Nixon <codemonkey@petenixon.net>
 #
 # This program is free software; you can redistribute it and/or modify
-# it under the terms of Version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 #
 
 
-
 # Modules that we use to get things done.
 require DBI;
 require Getopt::Long;
 
 ## Program and File locations
-# gzcat - 'cat for .gz / gzip files'
+# gzcat - 'cat for .gz / gzip files' 
 # If you don't have gzcat and do have gzip then use: ln gzip gzcat
 $GZCAT = "/usr/bin/zcat";
 # zcat - 'cat for .Z / compressed files'
@@ -45,12 +46,12 @@ $password    = "";
 
 
 #### You should not have to modify anything below here
-$progname = "H323 Detail2DB";
-$version = 2.2;
+$progname = "H323 Detail to DB parser";
+$version = 2;
 
 # Set up some basic variables
-my $passno = 0; my $duplicates = 0; my $verbose = 0; my %duplicate_records = ();
-my $starttime = time();
+$passno = 0; $double_match_no = 0; $verbose = 0;
+$starttime = time();
 
 
 sub db_connect {
@@ -60,37 +61,28 @@ sub db_connect {
        if ($verbose > 1) { print "DEBUG: localhost connection so using UNIX socket instead of network socket.\n" }
                $dbh = DBI->connect("DBI:Pg:dbname=$database", "$user", "$password")
                        or die "Couldn't connect to database: " . DBI->errstr;
-       } else {
+       }
+       else {
                $dbh = DBI->connect("DBI:Pg:dbname=$database;host=$hostname", "$user", "$password")
                        or die "Couldn't connect to database: " . DBI->errstr;
        }
 }
 
 sub db_disconnect {
-       my $hostname = shift;
+       ### Now, disconnect from the database
        if ($verbose > 1) { print "DEBUG: Disconnecting from Database Host: $hostname\n" }
-       $dbh->disconnect                # Disconnect from the database
+       $dbh->disconnect
            or warn "Disconnection failed: $DBI::errstr\n";
 }
 
-sub process_duplicates {
-       if ($verbose > 1) { print "DEBUG: Now processing $duplicates duplicate records\n" }
-       foreach my $a1 ( keys %duplicate_records ) {
-               print "$a1:\n";
-               for my $a2 ( keys %{ $duplicate_records{$a1} } ) {
-                       print "\t$a2 = $duplicate_records{$a1}{$a2}\n";
-               }
-       print "\n";
-       }
-}
-
 
-sub procedure_insert {         # FIXME: Does not work with current SQL schema. Use standard method
+sub procedure_insert {
+       $passno++;
        if ($verbose > 0) { print "Record: $passno) Conf ID: $h323_conf_id   Setup Time: $h323_setup_time  Call Length: $AcctSessionTime   "; }
-       if ($h323_call_type eq 'VoIP') {
+       if ($h323_call_type eq 'VoIP') { 
         $sth2 = $dbh->prepare("SELECT VoIPInsertRecord('$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
                '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime', '$h323_call_origin', '$h323_setup_time',
-               '$h323_connect_time','$h323_disconnect_time', '$h323_disconnect_cause', (NULLIF('$h323_remote_address', '')::inet), '$h323_voice_quality', '$h323_conf_id')");
+               '$h323_connect_time','$h323_disconnect_time', '$h323_disconnect_cause', '$h323_remote_address', '$h323_voice_quality', '$h323_conf_id')");
        }
        elsif ($h323_call_type eq 'Telephony') {
         $sth2 = $dbh->prepare("SELECT TelephonyInsertRecord('$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
@@ -104,43 +96,36 @@ sub procedure_insert {             # FIXME: Does not work with current SQL schema. Use stan
 }
 
 sub db_insert {
-       if ($h323_call_type eq 'VoIP') {
-        $sth2 = $dbh->prepare("INSERT into StopVoIP (
-               AcctTime, UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets,
-               CalledStationId, CallingStationId, AcctDelayTime, H323RemoteAddress, h323gwid, h323callorigin,
-               callid, h323connecttime, h323disconnectcause, h323disconnecttime, h323setuptime, h323voicequality)
-               values(($Timestamp)::abstime, '$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets',
-               '$AcctOutputOctets', '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime',
-               NULLIF('$h323_remote_address', '')::INET, '$h323_gw_id','$h323_call_origin', '$h323_conf_id',
-               NULLIF('$h323_connect_time', '')::TIMESTAMPTZ, '$h323_disconnect_cause',
-               NULLIF('$h323_disconnect_time', '')::TIMESTAMPTZ, NULLIF('$h323_setup_time', '')::TIMESTAMPTZ,
-               NULLIF('$h323_voice_quality','')::INT4)");
-
+       if ($h323_call_type eq 'VoIP') { 
+        $sth2 = $dbh->prepare("INSERT into Stop$h323_call_type (
+               UserName, NASIPAddress, AcctSessionTime, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId,
+               AcctDelayTime, H323RemoteAddress, h323callorigin, h323confid,
+               h323connecttime, h323disconnectcause, h323disconnecttime, h323setuptime, h323voicequality)
+               values('$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
+               '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime', '$h323_remote_address',
+               '$h323_call_origin', '$h323_conf_id', '$h323_connect_time', '$h323_disconnect_cause', '$h323_disconnect_time', '$h323_setup_time', '$h323_voice_quality')");
        }
        elsif ($h323_call_type eq 'Telephony') {
-        $sth2 = $dbh->prepare("INSERT into StopTelephony (
-               AcctTime, UserName, NASIPAddress, AcctSessionTime,
+        $sth2 = $dbh->prepare("INSERT into StopTelephony (UserName, NASIPAddress, AcctSessionTime,
                 AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctDelayTime,
-                CiscoNASPort, h323callorigin, callid, h323connecttime, h323disconnectcause, h323disconnecttime, h323setuptime, h323voicequality)
-                values(($Timestamp)::abstime, '$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
+                CiscoNASPort, h323callorigin, h323confid, h323connecttime, h323disconnectcause, h323disconnecttime, h323setuptime, h323voicequality)
+                values('$UserName', '$NasIPAddress', '$AcctSessionTime', '$AcctInputOctets', '$AcctOutputOctets',
                 '$Called_Station_Id', '$Calling_Station_Id', '$AcctDelayTime', '$Cisco_NAS_Port', '$h323_call_origin', '$h323_conf_id',
                '$h323_connect_time', '$h323_disconnect_cause', '$h323_disconnect_time', '$h323_setup_time', '$h323_voice_quality')");
-       } else {
-               if ($h323_call_type) { print "ERROR: Unsupported h323calltype: \"$h323_call_type\"\n"; }
-               else { print "ERROR: Missing \"h323calltype\". This doesn't appear to be a VoIP record."; }
-               return;         # Not a VoIP record. Bailout
-        }
+       } else { print "ERROR: Unsupported h323calltype \"$h323_call_type\"\n" }
+
        $sth2->execute();
        #my $returned_rows = $sth2->rows;
        if ($verbose > 0) { print "added to DB\n"; }
        $sth2->finish();
+
 }
 
 ## This sub can be used to update data in an existing database if you have some fields not in the Database.
 sub db_update {
-       my $sth2= $dbh->prepare("UPDATE radacct SET CalledStationId = '$Called_Station_Id',
+       my $sth2= $dbh->prepare("UPDATE radacct SET CalledStationId = '$Called_Station_Id', 
                AcctTerminateCause = '$AcctTerminateCause', H323RemoteAddress = '$h323_remote_address',
-               AcctStatusType = '$AcctStatusType', callid = '$h323_conf_id', h323calltype = '$h323_call_type',
+               AcctStatusType = '$AcctStatusType', h323confid = '$h323_conf_id', h323calltype = '$h323_call_type',
                CiscoNASPort = '$Cisco_NAS_Port', h323disconnectcause = '$h323_disconnect_cause',
                h323connecttime = '$h323_connect_time', h323disconnecttime = '$h323_disconnect_time',
                h323setuptime = '$h323_setup_time' WHERE AcctSessionId = 'AcctSessionId' AND UserName = '$UserName'
@@ -153,61 +138,77 @@ sub db_update {
 }
 
 sub db_read {
-       if ($verbose > 0) { print "Record: $passno) ConfID: $h323_conf_id Timestamp: $radius_record_timestamp Length: $AcctSessionTime "; }
+       $passno++;
+       if ($verbose > 0) { print "Record: $passno) Conf ID: $h323_conf_id   Setup Time: $h323_setup_time  Call Length: $AcctSessionTime   "; }
        my $sth = $dbh->prepare("SELECT RadAcctId FROM Stop$h323_call_type
-               WHERE AcctTime = ($Timestamp)::abstime
+               WHERE h323SetupTime = '$h323_setup_time'
                AND NASIPAddress = '$NasIPAddress'
-               AND callid = '$h323_conf_id'")
-                or die "\nCouldn't prepare statement: " . $dbh->errstr . "\n";
+               AND h323confid = '$h323_conf_id'")
+                or die "Couldn't prepare statement: " . $dbh->errstr;
 
-       my @data;
-       $sth->execute()             # Execute the query
-               or die "\nCouldn't execute statement: " . $sth->errstr . "\n";
-       my $returned_rows = $sth->rows;
+          my @data;
+          $sth->execute()             # Execute the query
+            or die "Couldn't execute statement: " . $sth->errstr;
+           my $returned_rows = $sth->rows;
 
           if ($sth->rows == 0) {
-               &db_insert;     # It's a new record. All systems go.
+               &db_insert;
           } elsif ($sth->rows == 1) {
-                if ($verbose > 0) { print "already in DB.\n"; }
+                if ($verbose > 0) { print "Exists in DB.\n"; }
                # FIXME: Make updates an option!
                 #while (@data = $sth->fetchrow_array()) {
                 #my $dbAcctSessionId = $data[1];
                ##&db_update;
                 #}
           } else {
-               $duplicates++;   # FIXME: Log this somewhere!
+               $double_match_no++;
+               # FIXME: Log this somewhere!
                 print "********* More than One Match! We have a problem!\n";
           }
 
-       $sth->finish;
+        $sth->finish;
+
+}
+
+sub read_record {
+       my $keepreading = 1;
+       @record = ();
+       while ($keepreading) {
+               $_ = <DETAIL>;
+               print "$_" if ($verbose > 1);
+               if ( /^$/ ) {
+                       $keepreading = 0;
+               } else {
+                       $record[++$#record] = $_;
+               }
+       }
 }
 
 sub process_record {
-       $radius_record_timestamp = @record[0];
-       chomp $radius_record_timestamp;
-       if ($verbose > 1) { print "DEBUG: Processing new record with time: $radius_record_timestamp \n"; }
-       # Clear the variables we use so that we don't have rubbish from the last loop
-       $UserName=""; $NasPort=""; $NasPortType="";
-       $NasIPAddress = ""; $AcctStatusType=""; $AcctSessionTime="";
+       if ($verbose > 1) { print "DEBUG: Processing Record\n"; }
+       # Clear the variable we use.
+       $UserName = ""; $NasPort=""; $NasPortType="";
+        $NasIPAddress = ""; $AcctStatusType=""; $AcctSessionTime="";
        $AcctInputOctets=""; $AcctOutputOctets=""; $AcctTerminateCause="";
        $ServiceType=""; $FramedProtocol=""; $FramedIPAddress="";
-       $Timestamp=""; $AcctDelayTime=0; $ConnectInfo=""; $Called_Station_Id="";
+       $Timestamp=""; $AcctDelayTime=""; $ConnectInfo=""; $Called_Station_Id="";
        $SQL_User_Name=""; $Cisco_NAS_Port=""; $Client_IP_Address="";
        $h323_remote_address=""; $h323_disconnect_cause=""; $h323_gw_id="";
        $h323_conf_id=""; $h323_call_type=""; $h323_disconnect_time="";
        $h323_connect_time=""; $h323_setup_time=""; $Calling_Station_Id="";
-       $h323_call_origin=""; $h323_voice_quality=""; $h323_gw_id="";
+       $h323_call_origin=""; $h323_voice_quality="";
 
-       foreach (@record) {             # Parse the lines of data into variables.
+       foreach (@record) {             # Collect data
 
        # Initial cleanup of junk from the line of data
        s/^\s+//;       # Strip leading spaces.
-       s/^Quintum-//;  # Strip leading "Quintum-".
        chomp;          # Strip trailing CR
 
+       # Parse the line of data into variables.
        $AcctStatusType = $_ if s/Acct-Status-Type = //;
-       if ($AcctStatusType eq "Stop") {                # All the data we need is in Stop records.
-       } elsif ($AcctStatusType eq "Start") {
+
+       # All the data we need is in Stop records.
+       if ($AcctStatusType eq "Start") {
                if ($verbose > 1) { print "DEBUG: Skipping \"Start\" record\n"; }
                return;
        } elsif ($AcctStatusType eq "Alive"){
@@ -215,6 +216,12 @@ sub process_record {
                return;
        };
 
+       if (s/h323-call-type = \"h323-call-type=//) {
+                        $h323_call_type = substr($_, 0, -1);
+                } elsif (s/h323-call-type = //) {
+                        $h323_call_type = $_;
+            };
+
        $UserName = $_ if s/User-Name = //;
        $NasIPAddress = $_ if s/NAS-IP-Address = //;
        $AcctSessionTime = $_ if s/Acct-Session-Time = //;
@@ -224,12 +231,6 @@ sub process_record {
        $Called_Station_Id = $_ if s/Called-Station-Id = //;
        $Calling_Station_Id = $_ if s/Calling-Station-Id = //;
        $Cisco_NAS_Port = $_ if s/Cisco-NAS-Port = //;
-       $Timestamp = $_ if s/Timestamp = //;
-       if (s/h323-call-type = \"h323-call-type=//) {
-                        $h323_call_type = substr($_, 0, -1);
-                } elsif (s/h323-call-type = //) {
-                        $h323_call_type = $_;
-            };
        if (s/h323-remote-address = \"h323-remote-address=//) {
                        $h323_remote_address = $_;
                } elsif (s/h323-remote-address = //) {
@@ -265,11 +266,6 @@ sub process_record {
                 } elsif (s/h323-call-origin = //) {
                         $h323_call_origin = $_;
             };
-        if (s/h323-gw-id = \"h323-gw-id=//) {
-                        $h323_gw_id = substr($_, 0, -1);
-                } elsif (s/h323-gw-id = //) {
-                        $h323_gw_id = $_;
-            };
         if (s/h323-voice-quality = \"h323-voice-quality=//) {
                         $h323_voice_quality = substr($_, 0, -1);
                 } elsif (s/h323-voice-quality = //) {
@@ -299,43 +295,23 @@ sub process_record {
        $h323_connect_time =~ s/^\.*//;
        $h323_disconnect_time =~ s/^\.*//;
 
-       # Ignore broken fields from some stupid, non-cisco gateways (They shall remain nameless)
-       if ($h323_connect_time eq "0") { $h323_connect_time = "" };
-       if ($h323_disconnect_time eq "0") { $h323_disconnect_time = "" };
-
        # If its a valid record continue onto the database functions
        # FIXME: More checks needed here.
-       if ($h323_call_type) {
-               $passno++;
-               #@duplicate_records{$passno} += @record;
+       if ($h323_call_type) { 
                if (&procedure_get()) { &procedure_insert; }
                else { &db_read; }
        } else { if ($verbose > 1) { print "DEBUG: Skipping non-h323 record\n"; } }
 }
 
-sub read_record {
-       my $keepreading = 1;
-       @record = ();
-       while ($keepreading) {
-               $_ = <DETAIL>;
-               print "$_" if ($verbose > 1);
-               if ( /^$/ ) {
-                       $keepreading = 0;       # End of record
-               } else {
-                       $record[++$#record] = $_;
-               }
-       }
-       &process_record;
-}
-
 sub read_detailfile {
-       my $file_starttime = time(); my $filename = shift; my @record = (); my $record_no = 0;
+       my $filename = shift; my @record = ();
        if ($verbose > 1) { print "DEBUG: Reading detail file: $filename\n" }
-       if ((-r $filename) != 1) {              # test if the file exists and is readable
+       # test if the file exists and is readable
+       if ((-r $filename) != 1) { 
                if ($verbose >= 0) { print "INFO: Skipping file \"$filename\" as it is not readable or does not exist.\n" }
                return;
         }
-       if ( $filename =~ /.gz$/ ) {            # Deal with compressed files
+       if ( $filename =~ /.gz$/ ) {
                open (DETAIL, "$GZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
        } elsif ( $filename =~ /.Z$/ ) {
                open (DETAIL, "$ZCAT $filename |") || warn "read_detailfile(\"$filename\"): $!\n";
@@ -350,12 +326,13 @@ sub read_detailfile {
                $valid_input = 0 if (eof(DETAIL));
                if ($verbose > 1) { print "DEBUG: Reading Record\n"; }
                &read_record;
-               $record_no++;
+               &process_record;
        }
-       my $file_runtime = (time() - $file_starttime);
-       if ($file_runtime < 1) { $file_runtime = 1; }
-       my $file_speed = ($record_no / $file_runtime);
-        if ($verbose >= 0) { print "\n $record_no total records read from $filename were processed in $file_runtime seconds ($file_speed records/sec) \n"; }
+       my $runtime = (time() - $starttime);
+       if ($runtime > 0) { 
+       } else { $runtime = 1; }
+       my $speed = ($passno / $runtime); 
+        if ($verbose >= 0) { print "\n $passno records from $filename were processed in $runtime seconds ($speed records/sec) \n"; }
 }
 
 sub print_usage_info {
@@ -365,16 +342,14 @@ sub print_usage_info {
        $underbar =~ s/./-/g;
        print "$leader\n$underbar\n";
        print "\n";
-       print "  Syntax:   h323detail2db.pl [ options ] detailfile(s)\n";
+       print "  Syntax:   h323detail2db.pl [ options ] file\n";
        print "\n";
-       print "    -d --database                    Database to use\n";
        print "    -h --help                        Show this usage information\n";
-       print "    -H --host                        Database host to connect to (Default: localhost)\n";
-       print "    -p --procedure                   Use Postgresql stored procedure (BROKEN!)\n";
-       print "    -q --quiet                       Turn on quiet mode (No Output)\n";
        print "    -v --verbose                     Turn on verbose\n";
-       print "    -V --version                     Show version and copyright\n";
        print "    -x --debug                       Turn on debugging\n";
+       print "    -p --procedure                   Use Postgresql stored procedure (faster!)\n";
+       print "    -V --version                     Show version and copyright\n";
+       print "    -H --host                        Database host to connect to (Default: localhost)\n";
        print "\n";
 }
 
@@ -395,7 +370,7 @@ sub main {
        };
 
        # See the Getopt::Long man page for details on the syntax of this line
-       @valid_opts = ("h|help", "V|version", "f|file=s", "x|debug", "d|database=s", "v|verbose+" => \$verbose, "q|quiet+" => \$quiet, "D|date=s", "H|host=s", "p|procedure");
+       @valid_opts = ("h|help", "V|version", "f|file=s", "x|debug", "v|verbose+" => \$verbose, "q|quiet+" => \$quiet, "D|date=s", "H|host=s", "p|procedure");
        Getopt::Long::Configure("no_getopt_compat", "bundling", "no_ignore_case");
        Getopt::Long::GetOptions(@valid_opts);
 
@@ -410,8 +385,8 @@ sub main {
                $rcs_info =~ s/\$\s*Author: (\S+) \$ /$1/;
 
                print "\n";
-               print "$progname Version $version by Peter Nixon - http://www.peternixon.net/\n";
-               print "Copyright (c) 2002-2004 Peter Nixon\n";
+               print "$progname Version $version by Peter Nixon <codemonkey\@peternixon.net>\n";
+               print "Copyright (c) 2002-2003, 2003 Peter Nixon\n";
                print "  ($rcs_info)\n";
                print "\n";
                return SUCCESS;
@@ -420,33 +395,22 @@ sub main {
                exit(SUCCESS);
        }
 
-       if ($opt_x) {
-               print "DEBUG: Debug mode is enabled.\n";
+       if ($opt_x) { 
+               print "DEBUG: Debug mode is enabled.\n"; 
                $verbose = 2;
        } elsif ($quiet) { $verbose -= $quiet; }
        &procedure_set($opt_p);
-       if ($opt_d) {
-               if ($verbose > 0) { print "Using database \"$opt_d\" instead of default database \"$database\"\n"; }
-               $database = $opt_d;
-       }
 
        if (@ARGV) {
-               my $db_host;
-               if ($opt_H) { $db_host = $opt_H; }
-               else { $db_host = "localhost"; }
-               &db_connect($db_host);
+               if ($opt_H) { &db_connect($opt_H);
+               } else { &db_connect(localhost); }
 
                # Loop through the defined files
                foreach $file (@ARGV) {
                        &read_detailfile($file);
                }
-               &process_duplicates;
-               &db_disconnect($db_host);
 
-               my $runtime = (time() - $starttime);
-               if ($runtime < 1) { $runtime = 1; }
-               my $speed = ($passno / $runtime);
-               if ($verbose >= 0) { print "\n $passno valid records were processed in $runtime seconds ($speed records/sec) \n"; }
+               &db_disconnect;
        } else {
                print "ERROR: Please specify one or more detail file(s) to import.\n";
                exit(FAILURE);
index 80a5721..f34ea64 100644 (file)
@@ -18,16 +18,3 @@ distclean:
 clean:
 
 install:
-       $(INSTALL) -d -m 755 $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 hash.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 libradius.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 md4.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 md5.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 missing.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 packet.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 radius.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 radpaths.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 sha1.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 token.h $(R)$(includedir)/freeradius
-       $(INSTALL) -m 644 udpfromto.h $(R)$(includedir)/freeradius
-       sed -i 's/^#include <freeradius-devel/#include <freeradius/' $(R)$(includedir)/freeradius/libradius.h
index 5386e59..fb4cc17 100644 (file)
-/* src/include/autoconf.h.in.  Generated from configure.in by autoheader.  */
+/* src/include/autoconf.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Include support for Ascend binary filter attributes */
-#undef ASCEND_BINARY
-
-/* BSD-Style get*byaddr_r */
-#undef BSDSTYLE
-
-/* style of ctime_r function */
-#undef CTIMERSTYLE
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* style of gethostbyaddr_r functions */
-#undef GETHOSTBYADDRRSTYLE
+*/
 
-/* style of gethostbyname_r functions */
-#undef GETHOSTBYNAMERSTYLE
 
-/* GNU-Style get*byaddr_r */
-#undef GNUSTYLE
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
 
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
+/* Define to empty if the keyword does not work.  */
+#undef const
 
-/* Define if you have the <asn1.h>, <snmp_impl.h> and <snmp.h> header file. */
-#undef HAVE_ASN1_SNMP_SNMPIMPL_H
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef gid_t
 
-/* Define to 1 if you have the `closefrom' function. */
-#undef HAVE_CLOSEFROM
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
+#undef HAVE_SYS_WAIT_H
 
-/* Do we have the crypt function */
-#undef HAVE_CRYPT
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
 
-/* Define to 1 if you have the <crypt.h> header file. */
-#undef HAVE_CRYPT_H
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef pid_t
 
-/* Define to 1 if you have the `ctime_r' function. */
-#undef HAVE_CTIME_R
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
 
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
-   */
-#undef HAVE_DIRENT_H
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
 
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
 
-/* Define to 1 if you have the <errno.h> header file. */
-#undef HAVE_ERRNO_H
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
 
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef uid_t
 
-/* Define to 1 if you have the `getaddrinfo' function. */
-#undef HAVE_GETADDRINFO
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
 
-/* Define to 1 if you have the `getnameinfo' function. */
-#undef HAVE_GETNAMEINFO
+/* style of gethost*_r functions */
+#define GNUSTYLE 1
+#define SYSVSTYLE 2
+#define BSDSTYLE 3
+#undef GETHOSTBYADDRRSTYLE
+#undef GETHOSTBYNAMERSTYLE
 
-/* Define to 1 if you have the <getopt.h> header file. */
-#undef HAVE_GETOPT_H
+/* style of ctime_r function */
+#define POSIXSTYLE 1
+#define SOLARISSTYLE 2
+#undef CTIMERSTYLE
 
-/* Define to 1 if you have the `getopt_long' function. */
-#undef HAVE_GETOPT_LONG
+/* Do we have the crypt function ? */
+#undef HAVE_CRYPT
 
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
+/* Include support for Ascend binary filter attributes */
+#undef ASCEND_BINARY
 
-/* Define to 1 if you have the `getusershell' function. */
-#undef HAVE_GETUSERSHELL
+/* socklen_t is generally 'int' on systems which don't use it */
+#undef socklen_t
 
-/* Define to 1 if you have the `gmtime_r' function. */
-#undef HAVE_GMTIME_R
+/* uint8_t should be the canonical 'octet' for network traffic */
+#undef uint8_t
 
-/* Define to 1 if you have the <grp.h> header file. */
-#undef HAVE_GRP_H
+/* uint16_t should be the canonical '2 octets' for network traffic */
+#undef uint16_t
 
-/* define if you have IN6_PKTINFO (Linux) */
-#undef HAVE_IN6_PKTINFO
+/* uint32_t should be the canonical 'network integer' */
+#undef uint32_t
 
-/* Define to 1 if you have the `inet_aton' function. */
-#undef HAVE_INET_ATON
+/* Include SNMP subagent */
+#undef WITH_SNMP
 
-/* Define to 1 if you have the `inet_ntop' function. */
-#undef HAVE_INET_NTOP
+/* Define if you have the <ucd-snmp/asn1.h>, <ucd-snmp/snmp_impl.h> and <ucd-snmp/snmp.h> header file.  */
+#undef HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H
 
-/* Define to 1 if you have the `inet_pton' function. */
-#undef HAVE_INET_PTON
+/* Define if you have the <asn1.h>, <snmp_impl.h> and <snmp.h> header file.  */
+#undef HAVE_ASN1_SNMP_SNMPIMPL_H
 
-/* Define to 1 if you have the `initgroups' function. */
-#undef HAVE_INITGROUPS
+/* Define if you have the snmp library (-lsnmp).  */
+#undef HAVE_LIBSNMP
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+/* define this if we have the <regex.h> header file */
+#undef HAVE_REGEX_H
 
-/* define if you have IP_PKTINFO (Linux) */
-#undef HAVE_IP_PKTINFO
+/* define this if we have REG_EXTENDED (from <regex.h>) */
+#undef HAVE_REG_EXTENDED
 
-/* Define to 1 if you have the `crypto' library (-lcrypto). */
-#undef HAVE_LIBCRYPTO
+/* define to something if you don't have ut_xtime in struct utmpx */
+#undef ut_xtime
 
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
+/* define if you have OSFC2 authentication */
+#undef OSFC2
 
-/* Define to 1 if you have the `pcap' library (-lpcap). */
-#undef HAVE_LIBPCAP
+/* define if you have OSFSIA authentication */
+#undef OSFSIA
 
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-#undef HAVE_LIBRESOLV
+/* define if you have IP_PKTINFO (Linux) */
+#undef HAVE_IP_PKTINFO
 
-/* Define if you have the snmp library (-lsnmp). */
-#undef HAVE_LIBSNMP
+/* define if you want udpfromto */
+#undef WITH_UDPFROMTO
 
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
+/* Define if you have the closefrom function.  */
+#undef HAVE_CLOSEFROM
 
-/* Define to 1 if you have the `ssl' library (-lssl). */
-#undef HAVE_LIBSSL
+/* Define if you have the ctime_r function.  */
+#undef HAVE_CTIME_R
 
-/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
-#undef HAVE_LIBWS2_32
+/* Define if you have the gethostname function.  */
+#undef HAVE_GETHOSTNAME
 
-/* Define to 1 if you have the `localtime_r' function. */
-#undef HAVE_LOCALTIME_R
+/* Define if you have the getopt_long function.  */
+#undef HAVE_GETOPT_LONG
 
-/* Define to 1 if you have the `lockf' function. */
-#undef HAVE_LOCKF
+/* Define if you have the getusershell function.  */
+#undef HAVE_GETUSERSHELL
 
-/* Define to 1 if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
+/* Define if you have the gmtime_r function.  */
+#undef HAVE_GMTIME_R
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+/* Define if you have the inet_aton function.  */
+#undef HAVE_INET_ATON
 
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-#undef HAVE_NDIR_H
+/* Define if you have the inet_ntop function.  */
+#undef HAVE_INET_NTOP
 
-/* Define to 1 if you have the <netdb.h> header file. */
-#undef HAVE_NETDB_H
+/* Define if you have the inet_pton function.  */
+#undef HAVE_INET_PTON
 
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#undef HAVE_NETINET_IN_H
+/* Define if you have the initgroups function.  */
+#undef HAVE_INITGROUPS
 
-/* Define to 1 if you have the <net/if.h> header file. */
-#undef HAVE_NET_IF_H
+/* Define if you have the localtime_r function.  */
+#undef HAVE_LOCALTIME_R
 
-/* Define to 1 if you have the <openssl/crypto.h> header file. */
-#undef HAVE_OPENSSL_CRYPTO_H
+/* Define if you have the lockf function.  */
+#undef HAVE_LOCKF
 
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-#undef HAVE_OPENSSL_ENGINE_H
+/* Define if you have the pthread_sigmask function.  */
+#undef HAVE_PTHREAD_SIGMASK
 
-/* Define to 1 if you have the <openssl/err.h> header file. */
-#undef HAVE_OPENSSL_ERR_H
+/* Define if you have the setlinebuf function.  */
+#undef HAVE_SETLINEBUF
 
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-#undef HAVE_OPENSSL_SSL_H
+/* Define if you have the setsid function.  */
+#undef HAVE_SETSID
 
-/* Define to 1 if you have the <pcap.h> header file. */
-#undef HAVE_PCAP_H
+/* Define if you have the setvbuf function.  */
+#undef HAVE_SETVBUF
 
-/* Define to 1 if you have the <prot.h> header file. */
-#undef HAVE_PROT_H
+/* Define if you have the sigaction function.  */
+#undef HAVE_SIGACTION
 
-/* Define to 1 if you have the <pthread.h> header file. */
-#undef HAVE_PTHREAD_H
+/* Define if you have the sigprocmask function.  */
+#undef HAVE_SIGPROCMASK
 
-/* Define to 1 if you have the `pthread_sigmask' function. */
-#undef HAVE_PTHREAD_SIGMASK
+/* Define if you have the snprintf function.  */
+#undef HAVE_SNPRINTF
 
-/* Define to 1 if you have the <pwd.h> header file. */
-#undef HAVE_PWD_H
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
 
-/* define this if we have the <regex.h> header file */
-#undef HAVE_REGEX_H
+/* Define if you have the strncasecmp function.  */
+#undef HAVE_STRNCASECMP
 
-/* define this if we have REG_EXTENDED (from <regex.h>) */
-#undef HAVE_REG_EXTENDED
+/* Define if you have the strsep function.  */
+#undef HAVE_STRSEP
 
-/* Define to 1 if you have the <resource.h> header file. */
-#undef HAVE_RESOURCE_H
+/* Define if you have the strsignal function.  */
+#undef HAVE_STRSIGNAL
 
-/* Define to 1 if you have the <semaphore.h> header file. */
-#undef HAVE_SEMAPHORE_H
+/* Define if you have the vsnprintf function.  */
+#undef HAVE_VSNPRINTF
 
-/* Define to 1 if you have the `setlinebuf' function. */
-#undef HAVE_SETLINEBUF
+/* Define if you have the <arpa/inet.h> header file.  */
+#undef HAVE_ARPA_INET_H
 
-/* Define to 1 if you have the `setsid' function. */
-#undef HAVE_SETSID
+/* Define if you have the <crypt.h> header file.  */
+#undef HAVE_CRYPT_H
 
-/* Define to 1 if you have the `setvbuf' function. */
-#undef HAVE_SETVBUF
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
 
-/* Define to 1 if you have the <siad.h> header file. */
-#undef HAVE_SIAD_H
+/* Define if you have the <dlfcn.h> header file.  */
+#undef HAVE_DLFCN_H
 
-/* Define to 1 if you have the <sia.h> header file. */
-#undef HAVE_SIA_H
+/* Define if you have the <errno.h> header file.  */
+#undef HAVE_ERRNO_H
 
-/* Define to 1 if you have the `sigaction' function. */
-#undef HAVE_SIGACTION
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
 
-/* Define to 1 if you have the <signal.h> header file. */
-#undef HAVE_SIGNAL_H
+/* Define if you have the <getopt.h> header file.  */
+#undef HAVE_GETOPT_H
 
-/* Define to 1 if you have the `sigprocmask' function. */
-#undef HAVE_SIGPROCMASK
+/* Define if you have the <inttypes.h> header file.  */
+#undef HAVE_INTTYPES_H
 
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
+/* Define if you have the <malloc.h> header file.  */
+#undef HAVE_MALLOC_H
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
 
-/* Define to 1 if you have the <stdio.h> header file. */
-#undef HAVE_STDIO_H
+/* Define if you have the <netdb.h> header file.  */
+#undef HAVE_NETDB_H
 
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
+/* Define if you have the <netinet/in.h> header file.  */
+#undef HAVE_NETINET_IN_H
 
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
+/* Define if you have the <openssl/crypto.h> header file.  */
+#undef HAVE_OPENSSL_CRYPTO_H
 
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
+/* Define if you have the <openssl/engine.h> header file.  */
+#undef HAVE_OPENSSL_ENGINE_H
 
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
+/* Define if you have the <openssl/err.h> header file.  */
+#undef HAVE_OPENSSL_ERR_H
 
-/* Define to 1 if you have the `strlcat' function. */
-#undef HAVE_STRLCAT
+/* Define if you have the <openssl/ssl.h> header file.  */
+#undef HAVE_OPENSSL_SSL_H
 
-/* Define to 1 if you have the `strlcpy' function. */
-#undef HAVE_STRLCPY
+/* Define if you have the <prot.h> header file.  */
+#undef HAVE_PROT_H
 
-/* Define to 1 if you have the `strncasecmp' function. */
-#undef HAVE_STRNCASECMP
+/* Define if you have the <pthread.h> header file.  */
+#undef HAVE_PTHREAD_H
 
-/* Define to 1 if you have the `strsep' function. */
-#undef HAVE_STRSEP
+/* Define if you have the <resource.h> header file.  */
+#undef HAVE_RESOURCE_H
 
-/* Define to 1 if you have the `strsignal' function. */
-#undef HAVE_STRSIGNAL
+/* Define if you have the <semaphore.h> header file.  */
+#undef HAVE_SEMAPHORE_H
 
-/* Generic DNS lookups */
-#undef HAVE_STRUCT_ADDRINFO
+/* Define if you have the <sia.h> header file.  */
+#undef HAVE_SIA_H
 
-/* IPv6 address structure */
-#undef HAVE_STRUCT_IN6_ADDR
+/* Define if you have the <siad.h> header file.  */
+#undef HAVE_SIAD_H
 
-/* IPv6 socket addresses */
-#undef HAVE_STRUCT_SOCKADDR_IN6
+/* Define if you have the <signal.h> header file.  */
+#undef HAVE_SIGNAL_H
 
-/* Generic socket addresses */
-#undef HAVE_STRUCT_SOCKADDR_STORAGE
+/* Define if you have the <stdint.h> header file.  */
+#undef HAVE_STDINT_H
 
-/* Define to 1 if you have the <syslog.h> header file. */
-#undef HAVE_SYSLOG_H
+/* Define if you have the <stdio.h> header file.  */
+#undef HAVE_STDIO_H
 
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
-   */
+/* Define if you have the <sys/dir.h> header file.  */
 #undef HAVE_SYS_DIR_H
 
-/* Define to 1 if you have the <sys/fcntl.h> header file. */
+/* Define if you have the <sys/fcntl.h> header file.  */
 #undef HAVE_SYS_FCNTL_H
 
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
-   */
+/* Define if you have the <sys/ndir.h> header file.  */
 #undef HAVE_SYS_NDIR_H
 
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#undef HAVE_SYS_RESOURCE_H
+/* Define if you have the <sys/prctl.h> header file.  */
+#undef HAVE_SYS_PRCTL_H
 
-/* Define to 1 if you have the <sys/security.h> header file. */
+/* Define if you have the <sys/security.h> header file.  */
 #undef HAVE_SYS_SECURITY_H
 
-/* Define to 1 if you have the <sys/select.h> header file. */
+/* Define if you have the <sys/select.h> header file.  */
 #undef HAVE_SYS_SELECT_H
 
-/* Define to 1 if you have the <sys/socket.h> header file. */
+/* Define if you have the <sys/socket.h> header file.  */
 #undef HAVE_SYS_SOCKET_H
 
-/* Define to 1 if you have the <sys/stat.h> header file. */
+/* Define if you have the <sys/stat.h> header file.  */
 #undef HAVE_SYS_STAT_H
 
-/* Define to 1 if you have the <sys/time.h> header file. */
+/* Define if you have the <sys/time.h> header file.  */
 #undef HAVE_SYS_TIME_H
 
-/* Define to 1 if you have the <sys/types.h> header file. */
+/* Define if you have the <sys/types.h> header file.  */
 #undef HAVE_SYS_TYPES_H
 
-/* Define to 1 if you have the <sys/wait.h> header file. */
+/* Define if you have the <sys/wait.h> header file.  */
 #undef HAVE_SYS_WAIT_H
 
-/* Define if you have the <ucd-snmp/asn1.h>, <ucd-snmp/snmp_impl.h> and
-   <ucd-snmp/snmp.h> header file. */
-#undef HAVE_UCD_SNMP_ASN1_SNMP_SNMPIMPL_H
+/* Define if you have the <syslog.h> header file.  */
+#undef HAVE_SYSLOG_H
 
-/* Define to 1 if you have the <unistd.h> header file. */
+/* Define if you have the <unistd.h> header file.  */
 #undef HAVE_UNISTD_H
 
-/* Define to 1 if you have the <utmpx.h> header file. */
-#undef HAVE_UTMPX_H
-
-/* Define to 1 if you have the <utmp.h> header file. */
+/* Define if you have the <utmp.h> header file.  */
 #undef HAVE_UTMP_H
 
-/* Define to 1 if you have the `vsnprintf' function. */
-#undef HAVE_VSNPRINTF
-
-/* Define to 1 if you have the <winsock.h> header file. */
-#undef HAVE_WINSOCK_H
-
-/* define if you have OSFC2 authentication */
-#undef OSFC2
-
-/* define if you have OSFSIA authentication */
-#undef OSFSIA
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Posix-Style ctime_r */
-#undef POSIXSTYLE
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Solaris-Style ctime_r */
-#undef SOLARISSTYLE
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* SYSV-Style get*byaddr_r */
-#undef SYSVSTYLE
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Include SNMP subagent */
-#undef WITH_SNMP
-
-/* define if you want udpfromto */
-#undef WITH_UDPFROMTO
-
-/* Define to 1 if your processor stores words with the most significant byte
-   first (like Motorola and SPARC, unlike Intel and VAX). */
-#undef WORDS_BIGENDIAN
-
-/* Define to 1 if on AIX 3.
-   System headers sometimes define this.
-   We just want to avoid a redefinition error message.  */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Define for large files, on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define to `long int' if <sys/types.h> does not define. */
-#undef off_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
+/* Define if you have the <utmpx.h> header file.  */
+#undef HAVE_UTMPX_H
 
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#undef size_t
+/* Define if you have the nsl library (-lnsl).  */
+#undef HAVE_LIBNSL
 
-/* socklen_t is generally 'int' on systems which don't use it */
-#undef socklen_t
+/* Define if you have the resolv library (-lresolv).  */
+#undef HAVE_LIBRESOLV
 
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
+/* Define if you have the socket library (-lsocket).  */
+#undef HAVE_LIBSOCKET
 
-/* uint16_t should be the canonical '2 octets' for network traffic */
-#undef uint16_t
+/* Define to 1 if you have the crypto library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
 
-/* uint32_t should be the canonical 'network integer */
-#undef uint32_t
+/* Define to 1 if you have the ssl library (-lssl). */
+#undef HAVE_LIBSSL
 
-/* uint8_t should be the canonical 'octet' for network traffic */
-#undef uint8_t
+/* Some versions of glibc need this defined for pread/pwrite. */
+#undef _GNU_SOURCE
 
-/* define to something if you don't have ut_xtime in struct utmpx */
-#undef ut_xtime
index 385d5bb..4e9e9f6 100644 (file)
@@ -8,11 +8,8 @@
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(conffile_h, "$Id$")
-
 #include <stddef.h>
-#include <freeradius-devel/token.h>
+#include "token.h"
 
 /*
  * Export the minimum amount of information about these structs
@@ -20,7 +17,6 @@ RCSIDH(conffile_h, "$Id$")
 typedef struct conf_item CONF_ITEM;
 typedef struct conf_pair CONF_PAIR;
 typedef struct conf_part CONF_SECTION;
-typedef struct conf_data CONF_DATA;
 
 /*
  *  Instead of putting the information into a configuration structure,
@@ -30,7 +26,6 @@ typedef struct conf_data CONF_DATA;
 #define PW_TYPE_STRING_PTR     100
 #define PW_TYPE_BOOLEAN                101
 #define PW_TYPE_SUBSECTION     102
-#define PW_TYPE_FILENAME       103
 
 typedef struct CONF_PARSER {
   const char *name;
@@ -50,27 +45,22 @@ typedef struct CONF_PARSER {
 
 void           cf_pair_free(CONF_PAIR **cp);
 void           cf_section_free(CONF_SECTION **cp);
-int            cf_item_parse(CONF_SECTION *cs, const char *name,
-                             int type, void *data, const char *dflt);
-int            cf_section_parse(CONF_SECTION *, void *base,
-                                const CONF_PARSER *variables);
-CONF_SECTION   *cf_file_read(const char *file);
-int            cf_file_include(const char *file, CONF_SECTION *cs);
+int            cf_section_parse(CONF_SECTION *cs, void *base, const CONF_PARSER *variables);
 
-CONF_PAIR      *cf_pair_find(const CONF_SECTION *, const char *name);
-CONF_PAIR      *cf_pair_find_next(const CONF_SECTION *, const CONF_PAIR *, const char *name);
-CONF_SECTION   *cf_section_find(const char *name);
-CONF_SECTION   *cf_section_sub_find(const CONF_SECTION *, const char *name);
-CONF_SECTION   *cf_section_sub_find_name2(const CONF_SECTION *, const char *name1, const char *name2);
-char           *cf_section_value_find(const CONF_SECTION *, const char *attr);
+CONF_SECTION *conf_read(const char *fromfile, int fromline,
+                       const char *conffile, CONF_SECTION *parent);
 
-void *cf_data_find(CONF_SECTION *, const char *);
-int cf_data_add(CONF_SECTION *, const char *, void *, void (*)(void *));
+
+CONF_PAIR      *cf_pair_find(CONF_SECTION *section, const char *name);
+CONF_PAIR      *cf_pair_find_next(CONF_SECTION *section, CONF_PAIR *pair, const char *name);
+CONF_SECTION   *cf_section_find(const char *name);
+CONF_SECTION   *cf_section_sub_find(CONF_SECTION *section, const char *name);
+char           *cf_section_value_find(CONF_SECTION *section, const char *attr);
 
 char *cf_pair_attr(CONF_PAIR *pair);
 char *cf_pair_value(CONF_PAIR *pair);
-const char *cf_section_name1(const CONF_SECTION *);
-const char *cf_section_name2(const CONF_SECTION *);
+char *cf_section_name1(CONF_SECTION *section);
+char *cf_section_name2(CONF_SECTION *section);
 int dump_config(void);
 CONF_SECTION *cf_subsection_find_next(CONF_SECTION *section,
                                      CONF_SECTION *subsection,
@@ -84,11 +74,4 @@ CONF_PAIR *cf_itemtopair(CONF_ITEM *item);
 CONF_SECTION *cf_itemtosection(CONF_ITEM *item);
 CONF_ITEM *cf_pairtoitem(CONF_PAIR *cp);
 CONF_ITEM *cf_sectiontoitem(CONF_SECTION *cs);
-int cf_section_template(CONF_SECTION *cs, CONF_SECTION *template);
-
-/*
- *     Big magic.
- */
-int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src);
-
 #endif /* _CONFFILE_H */
diff --git a/src/include/event.h b/src/include/event.h
deleted file mode 100644 (file)
index 7d0aa4a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef LRAD_EVENT_H
-#define LRAD_EVENT_H
-
-/*
- * event.h     Simple event queue
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2007 The FreeRADIUS server project
- * Copyright 2007 Alan DeKok <aland@deployingradius.com>
- */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(event_h, "$Id$")
-
-typedef struct lrad_event_list_t lrad_event_list_t;
-typedef struct lrad_event_t lrad_event_t;
-
-typedef        void (*lrad_event_callback_t)(void *);
-
-lrad_event_list_t *lrad_event_list_create(void);
-void lrad_event_list_free(lrad_event_list_t *el);
-
-int lrad_event_list_num_elements(lrad_event_list_t *el);
-
-int lrad_event_insert(lrad_event_list_t *el,
-                     lrad_event_callback_t callback,
-                     void *ctx, struct timeval *when, lrad_event_t **ev_p);
-int lrad_event_delete(lrad_event_list_t *el, lrad_event_t **ev_p);
-
-int lrad_event_run(lrad_event_list_t *el, struct timeval *when);
-
-int lrad_event_now(lrad_event_list_t *el, struct timeval *when);
-
-#endif /* LRAD_HASH_H */
diff --git a/src/include/hash.h b/src/include/hash.h
deleted file mode 100644 (file)
index 4f21954..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef LRAD_HASH_H
-#define LRAD_HASH_H
-
-/*
- * hash.h      Structures and prototypes
- *             for fast hashing.
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2005,2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(hash_h, "$Id$")
-
-/*
- *     Fast hash, which isn't too bad.  Don't use for cryptography,
- *     just for hashing internal data.
- */
-uint32_t lrad_hash(const void *, size_t);
-uint32_t lrad_hash_update(const void *data, size_t size, uint32_t hash);
-uint32_t lrad_hash_string(const char *p);
-
-/*
- *     If you need fewer than 32-bits of hash, use this macro to get
- *     the number of bits in the hash you need.  The upper bits of the
- *     hash will be set to zero.
- */
-uint32_t lrad_hash_fold(uint32_t hash, int bits);
-
-typedef struct lrad_hash_table_t lrad_hash_table_t;
-typedef void (*lrad_hash_table_free_t)(void *);
-typedef uint32_t (*lrad_hash_table_hash_t)(const void *);
-typedef int (*lrad_hash_table_cmp_t)(const void *, const void *);
-typedef int (*lrad_hash_table_walk_t)(void * /* ctx */, void * /* data */);
-
-lrad_hash_table_t *lrad_hash_table_create(lrad_hash_table_hash_t hashNode,
-                                         lrad_hash_table_cmp_t cmpNode,
-                                         lrad_hash_table_free_t freeNode);
-void           lrad_hash_table_free(lrad_hash_table_t *ht);
-int            lrad_hash_table_insert(lrad_hash_table_t *ht, void *data);
-int            lrad_hash_table_delete(lrad_hash_table_t *ht, const void *data);
-void           *lrad_hash_table_yank(lrad_hash_table_t *ht, const void *data);
-int            lrad_hash_table_replace(lrad_hash_table_t *ht, void *data);
-void           *lrad_hash_table_finddata(lrad_hash_table_t *ht, const void *data);
-int            lrad_hash_table_num_elements(lrad_hash_table_t *ht);
-int            lrad_hash_table_walk(lrad_hash_table_t *ht,
-                                    lrad_hash_table_walk_t callback,
-                                    void *ctx);
-#endif /* LRAD_HASH_H */
index 2d16a30..bcefff0 100644 (file)
@@ -7,39 +7,45 @@
  *
  * Version:    $Id$
  *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2001,2002,2003,2004,2005,2006  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(libradius_h, "$Id$")
+#include "autoconf.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
 
-#include <freeradius-devel/missing.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
 
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
 
-#include <freeradius-devel/radius.h>
-#include <freeradius-devel/token.h>
-#include <freeradius-devel/hash.h>
+/*
+ *  Check for inclusion of <time.h>, versus <sys/time.h>
+ *  Taken verbatim from the autoconf manual.
+ */
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#include "radius.h"
+#include "token.h"
 
 #ifdef SIZEOF_UNSIGNED_INT
 #if SIZEOF_UNSIGNED_INT != 4
@@ -50,8 +56,8 @@ RCSIDH(libradius_h, "$Id$")
 /*
  *  Include for modules.
  */
-#include <freeradius-devel/sha1.h>
-#include <freeradius-devel/md4.h>
+#include <sha1.h>
+#include <md4.h>
 
 #define EAP_START               2
 
@@ -59,7 +65,7 @@ RCSIDH(libradius_h, "$Id$")
 #define CHAP_VALUE_LENGTH       16
 #define MAX_STRING_LEN         254     /* RFC2138: string 0-253 octets */
 
-#  define VENDOR(x)            ((x >> 16) & 0x7fff)
+#  define VENDOR(x)            ((x >> 16) & 0xffff)
 
 #ifdef _LIBRADIUS
 #  define AUTH_HDR_LEN         20
@@ -74,7 +80,7 @@ RCSIDH(libradius_h, "$Id$")
                                     } \
                                } while(0)
 #  define TAG_VALID(x)          ((x) > 0 && (x) < 0x20)
-#  define TAG_VALID_ZERO(x)     ((x) < 0x20)
+#  define TAG_VALID_ZERO(x)     ((x) >= 0 && (x) < 0x20)
 #  define TAG_ANY               -128   /* minimum signed char */
 #endif
 
@@ -91,16 +97,12 @@ RCSIDH(libradius_h, "$Id$")
 #endif
 
 typedef struct attr_flags {
-       unsigned int            addport : 1;  /* add NAS-Port to IP address */
-       unsigned int            has_tag : 1;  /* tagged attribute */
-       unsigned int            do_xlat : 1;  /* strvalue is dynamic */
-       unsigned int            caseless : 1; /* case insensitive compares */
-       unsigned int            array : 1; /* pack multiples into 1 attr */
-       unsigned int            has_value : 1; /* has a value */
-       unsigned int            has_value_alias : 1; /* has a value alias */
-
-       int8_t                  tag;          /* tag for tunneled attributes */
-       uint8_t                 encrypt;      /* encryption method */
+       char                    addport;        /* Add port to IP address */
+       char                    has_tag;        /* attribute allows tags */
+       signed char             len_disp;       /* length displacement */
+       char                    do_xlat;
+       signed char             tag;
+       uint8_t                 encrypt;        /* encryption method */
 } ATTR_FLAGS;
 
 /*
@@ -132,59 +134,17 @@ typedef struct dict_vendor {
        char                    name[1];
 } DICT_VENDOR;
 
-typedef union value_pair_data {
-       char                    strvalue[MAX_STRING_LEN];
-       uint8_t                 octets[MAX_STRING_LEN];
-       struct in_addr          ipaddr;
-       struct in6_addr         ipv6addr;
-       uint32_t                date;
-       uint32_t                integer;
-       uint8_t                 filter[32];
-       uint8_t                 ifid[8]; /* struct? */
-       uint8_t                 ipv6prefix[18]; /* struct? */
-} VALUE_PAIR_DATA;
-
 typedef struct value_pair {
        char                    name[40];
        int                     attribute;
-       int                     vendor;
        int                     type;
-       int                     length; /* of data */
+       int                     length; /* of strvalue */
+       uint32_t                lvalue;
        LRAD_TOKEN              operator;
+       uint8_t                 strvalue[MAX_STRING_LEN];
         ATTR_FLAGS              flags;
        struct value_pair       *next;
-       uint32_t                lvalue;
-       VALUE_PAIR_DATA         data;
 } VALUE_PAIR;
-#define vp_strvalue   data.strvalue
-#define vp_octets     data.octets
-#define vp_ipv6addr   data.ipv6addr
-#define vp_ifid       data.ifid
-#define vp_ipv6prefix data.ipv6prefix
-#define vp_filter     data.filter
-
-#if 0
-#define vp_ipaddr     data.ipaddr.s_addr
-#define vp_date       data.date
-#define vp_integer    data.integer
-#else
-/*
- *     These are left as lvalue until we audit the source for code
- *     that prints to vp_strvalue for integer/ipaddr/date types.
- */
-#define vp_ipaddr     lvalue
-#define vp_date       lvalue
-#define vp_integer    lvalue
-#endif
-
-
-typedef struct lrad_ipaddr_t {
-       int             af;     /* address family */
-       union {
-               struct in_addr  ip4addr;
-               struct in6_addr ip6addr; /* maybe defined in missing.h */
-       } ipaddr;
-} lrad_ipaddr_t;
 
 /*
  *     vector:         Request authenticator from access-request packet
@@ -197,19 +157,18 @@ typedef struct lrad_ipaddr_t {
  */
 typedef struct radius_packet {
        int                     sockfd;
-       lrad_ipaddr_t           src_ipaddr;
-        lrad_ipaddr_t          dst_ipaddr;
-       uint16_t                src_port;
-       uint16_t                dst_port;
+       uint32_t                src_ipaddr;
+       uint32_t                dst_ipaddr;
+       u_short                 src_port;
+       u_short                 dst_port;
        int                     id;
        unsigned int            code;
-       uint32_t                hash;
        uint8_t                 vector[AUTH_VECTOR_LEN];
        time_t                  timestamp;
+       int                     verified;
        uint8_t                 *data;
        int                     data_len;
        VALUE_PAIR              *vps;
-       ssize_t                 offset;
 } RADIUS_PACKET;
 
 /*
@@ -237,6 +196,13 @@ DICT_VALUE *dict_valbyname(int attr, const char *val);
 int            dict_vendorbyname(const char *name);
 DICT_VENDOR    *dict_vendorbyvalue(int vendor);
 
+/*
+ *  Compatibility
+ */
+#define dict_vendorcode
+#define dict_vendorpec
+
+
 #if 1 /* FIXME: compat */
 #define dict_attrget   dict_attrbyvalue
 #define dict_attrfind  dict_attrbyname
@@ -257,53 +223,39 @@ DICT_VENDOR       *dict_vendorbyvalue(int vendor);
 
 /* md5.c */
 
-void           librad_md5_calc(uint8_t *, const uint8_t *, unsigned int);
+void           librad_md5_calc(u_char *, u_char *, u_int);
 
 /* hmac.c */
 
-void lrad_hmac_md5(const uint8_t *text, int text_len,
-                  const uint8_t *key, int key_len,
+void lrad_hmac_md5(const unsigned char *text, int text_len,
+                  const unsigned char *key, int key_len,
                   unsigned char *digest);
 
 /* hmacsha1.c */
 
-void lrad_hmac_sha1(const uint8_t *text, int text_len,
-                   const uint8_t *key, int key_len,
-                   uint8_t *digest);
+void lrad_hmac_sha1(const unsigned char *text, int text_len,
+                   const unsigned char *key, int key_len,
+                   unsigned char *digest);
 
 /* radius.c */
 int            rad_send(RADIUS_PACKET *, const RADIUS_PACKET *, const char *secret);
-int            rad_packet_ok(RADIUS_PACKET *packet);
 RADIUS_PACKET  *rad_recv(int fd);
-ssize_t rad_recv_header(int sockfd, lrad_ipaddr_t *src_ipaddr, int *src_port,
-                       int *code);
-void           rad_recv_discard(int sockfd);
-int            rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
-                          const char *secret);
+int            rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secret);
 int            rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, const char *secret);
-int            rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
-                          const char *secret);
-int            rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
-                        const char *secret);
-
 RADIUS_PACKET  *rad_alloc(int newvector);
 void           rad_free(RADIUS_PACKET **);
-int            rad_pwencode(char *encpw, int *len, const char *secret,
-                            const uint8_t *vector);
-int            rad_pwdecode(char *encpw, int len, const char *secret,
-                            const uint8_t *vector);
-int            rad_tunnel_pwencode(char *encpw, int *len, const char *secret,
-                                   const uint8_t *vector);
-int            rad_tunnel_pwdecode(uint8_t *encpw, int *len,
-                                   const char *secret, const uint8_t *vector);
-int            rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output,
-                               int id, VALUE_PAIR *password);
-VALUE_PAIR     *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
-                            const char *secret, int attribute, int length,
-                            const uint8_t *data);
+int            rad_pwencode(char *encpw, int *len, const char *secret, const char *vector);
+int            rad_pwdecode(char *encpw, int len, const char *secret, const char *vector);
+int            rad_tunnel_pwencode(char *encpw, int *len, const char *secret, const char *vector);
+int            rad_tunnel_pwdecode(uint8_t *encpw, int *len, const char *secret, const char *vector);
+int            rad_chap_encode(RADIUS_PACKET *packet, char *output, int id, VALUE_PAIR *password);
 int            rad_vp2attr(const RADIUS_PACKET *packet,
                            const RADIUS_PACKET *original, const char *secret,
                            const VALUE_PAIR *vp, uint8_t *ptr);
+int            rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
+                          const char *secret);
+int            rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
+                        const char *secret);
 
 /* valuepair.c */
 VALUE_PAIR     *paircreate(int attr, int type);
@@ -313,7 +265,6 @@ VALUE_PAIR  *pairfind(VALUE_PAIR *, int);
 void           pairdelete(VALUE_PAIR **, int);
 void           pairadd(VALUE_PAIR **, VALUE_PAIR *);
 void            pairreplace(VALUE_PAIR **first, VALUE_PAIR *add);
-int            paircmp(VALUE_PAIR *check, VALUE_PAIR *data);
 VALUE_PAIR     *paircopy(VALUE_PAIR *vp);
 VALUE_PAIR     *paircopy2(VALUE_PAIR *vp, int attr);
 void           pairmove(VALUE_PAIR **to, VALUE_PAIR **from);
@@ -347,36 +298,41 @@ extern int        librad_max_attributes; /* per incoming packet */
 /*
  *     Several handy miscellaneous functions.
  */
-const char *   ip_ntoa(char *, uint32_t);
+char *         ip_hostname (char *buf, size_t buflen, uint32_t ipaddr);
+uint32_t       ip_getaddr (const char *);
+char *         ip_ntoa(char *, uint32_t);
+uint32_t       ip_addr(const char *);
 char           *ifid_ntoa(char *buffer, size_t size, uint8_t *ifid);
 uint8_t                *ifid_aton(const char *ifid_str, uint8_t *ifid);
+const char     *ipv6_ntoa(char *buffer, size_t size, void *ip6addr);
+int            ipv6_addr(const char *ip6_str, void *ip6addr);
+char           *strNcpy(char *dest, const char *src, int n);
+void           rad_lowercase(char *str);
+void           rad_rmspace(char *str);
 int            rad_lockfd(int fd, int lock_len);
 int            rad_lockfd_nonblock(int fd, int lock_len);
 int            rad_unlockfd(int fd, int lock_len);
 void           lrad_bin2hex(const uint8_t *bin, char *hex, int len);
 int            lrad_hex2bin(const char *hex, uint8_t *bin, int len);
-#ifndef HAVE_INET_PTON
-int            inet_pton(int af, const char *src, void *dst);
-#endif
-#ifndef HAVE_INET_NTOP
-const char     *inet_ntop(int af, const void *src, char *dst, size_t cnt);
-#endif
 #ifndef HAVE_CLOSEFROM
 int            closefrom(int fd);
 #endif
-int lrad_ipaddr_cmp(const lrad_ipaddr_t *a, const lrad_ipaddr_t *b);
-
-int            ip_hton(const char *src, int af, lrad_ipaddr_t *dst);
-const char     *ip_ntoh(const lrad_ipaddr_t *src, char *dst, size_t cnt);
-
-
 
 #ifdef ASCEND_BINARY
 /* filters.c */
 int            ascend_parse_filter(VALUE_PAIR *pair);
-void           print_abinary(VALUE_PAIR *vp, char *buffer, int len);
+void           print_abinary(VALUE_PAIR *vp, u_char *buffer, int len);
 #endif /*ASCEND_BINARY*/
 
+/* snprintf.c */
+#ifndef HAVE_VSNPRINTF
+#include <stdarg.h>
+int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
+#endif
+#ifndef HAVE_SNPRINTF
+int snprintf(char *str, size_t count, const char *fmt, ...);
+#endif
+
 /* random numbers in isaac.c */
 /* context of random number generator */
 typedef struct lrad_randctx {
@@ -393,7 +349,6 @@ void lrad_randinit(lrad_randctx *ctx, int flag);
 uint32_t lrad_rand(void);      /* like rand(), but better. */
 void lrad_rand_seed(const void *, size_t ); /* seed the random pool */
 
-
 /* crypt wrapper from crypt.c */
 int lrad_crypt_check(const char *key, const char *salt);
 
@@ -406,43 +361,49 @@ rbtree_t       *rbtree_create(int (*Compare)(const void *, const void *),
                               int replace_flag);
 void           rbtree_free(rbtree_t *tree);
 int            rbtree_insert(rbtree_t *tree, void *Data);
-rbnode_t       *rbtree_insertnode(rbtree_t *tree, void *Data);
 void           rbtree_delete(rbtree_t *tree, rbnode_t *Z);
-int            rbtree_deletebydata(rbtree_t *tree, const void *data);
 rbnode_t       *rbtree_find(rbtree_t *tree, const void *Data);
 void          *rbtree_finddata(rbtree_t *tree, const void *Data);
 int            rbtree_num_elements(rbtree_t *tree);
-void          *rbtree_min(rbtree_t *tree);
 void          *rbtree_node2data(rbtree_t *tree, rbnode_t *node);
+int            rbtree_deletebydata(rbtree_t *tree, const void *data);
 
 /* callback order for walking  */
 typedef enum { PreOrder, InOrder, PostOrder } RBTREE_ORDER;
+int rbtree_walk(rbtree_t *tree, RBTREE_ORDER order, int (*callback)(void *, void *), void *context);
 
 /*
- *     The callback should be declared as:
- *     int callback(void *context, void *data)
- *
- *     The "context" is some user-defined context.
- *     The "data" is the pointer to the user data in the node,
- *       NOT the node itself.
- *
- *     It should return 0 if all is OK, and !0 for any error.
- *     The walking will stop on any error.
+ *     Fast hash, which isn't too bad.  Don't use for cryptography,
+ *     just for hashing internal data.
  */
-int rbtree_walk(rbtree_t *tree, RBTREE_ORDER order, int (*callback)(void *, void *), void *context);
+uint32_t lrad_hash(const void *, size_t);
+uint32_t lrad_hash_update(const void *data, size_t size, uint32_t hash);
+uint32_t lrad_hash_string(const char *p);
 
 /*
- *     FIFOs
+ *     If you need fewer than 32-bits of hash, use this macro to get
+ *     the number of bits in the hash you need.  The upper bits of the
+ *     hash will be set to zero.
  */
-typedef struct lrad_fifo_t lrad_fifo_t;
-typedef void (*lrad_fifo_free_t)(void *);
-lrad_fifo_t *lrad_fifo_create(int max_entries, lrad_fifo_free_t freeNode);
-void lrad_fifo_free(lrad_fifo_t *fi);
-int lrad_fifo_push(lrad_fifo_t *fi, void *data);
-void *lrad_fifo_pop(lrad_fifo_t *fi);
-void *lrad_fifo_peek(lrad_fifo_t *fi);
-int lrad_fifo_num_elements(lrad_fifo_t *fi);
-
-#include <freeradius-devel/packet.h>
-
+uint32_t lrad_hash_fold(uint32_t hash, int bits);
+
+typedef struct lrad_hash_table_t lrad_hash_table_t;
+typedef void (*lrad_hash_table_free_t)(void *);
+typedef uint32_t (*lrad_hash_table_hash_t)(const void *);
+typedef int (*lrad_hash_table_cmp_t)(const void *, const void *);
+typedef int (*lrad_hash_table_walk_t)(void * /* ctx */, void * /* data */);
+
+lrad_hash_table_t *lrad_hash_table_create(lrad_hash_table_hash_t hashNode,
+                                         lrad_hash_table_cmp_t cmpNode,
+                                         lrad_hash_table_free_t freeNode);
+void           lrad_hash_table_free(lrad_hash_table_t *ht);
+int            lrad_hash_table_insert(lrad_hash_table_t *ht, void *data);
+int            lrad_hash_table_delete(lrad_hash_table_t *ht, const void *data);
+void           *lrad_hash_table_yank(lrad_hash_table_t *ht, const void *data);
+int            lrad_hash_table_replace(lrad_hash_table_t *ht, void *data);
+void           *lrad_hash_table_finddata(lrad_hash_table_t *ht, const void *data);
+int            lrad_hash_table_num_elements(lrad_hash_table_t *ht);
+int            lrad_hash_table_walk(lrad_hash_table_t *ht,
+                                    lrad_hash_table_walk_t callback,
+                                    void *ctx);
 #endif /*LIBRADIUS_H*/
index f26b513..9d17a47 100644 (file)
@@ -6,11 +6,11 @@
  *
  */
 
+
 #ifndef _LRAD_MD4_H
 #define _LRAD_MD4_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(md4_h, "$Id$")
+#include "autoconf.h"
 
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
index 0e15b0c..8a5ed05 100644 (file)
@@ -9,8 +9,7 @@
 #ifndef _LRAD_MD5_H
 #define _LRAD_MD5_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(md5_h, "$Id$")
+#include "autoconf.h"
 
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
@@ -29,12 +28,11 @@ RCSIDH(md5_h, "$Id$")
  *  FreeRADIUS defines to ensure globally unique MD5 function names,
  *  so that we don't pick up vendor-specific broken MD5 libraries.
  */
-#define MD5_CTX                lrad_MD5_CTX
-#define MD5Init                lrad_MD5Init
-#define MD5Update      lrad_MD5Update
-#define MD5Final       lrad_MD5Final
-#define MD5Transform   lrad_MD5Transform
-
+#define MD5_CTX                librad_MD5_CTX
+#define MD5Init                librad_MD5Init
+#define MD5Update      librad_MD5Update
+#define MD5Final       librad_MD5Final
+#define MD5Transform   librad_MD5Transform
 
 /*  The below was retrieved from
  *  http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.h?rev=1.1
@@ -58,21 +56,21 @@ RCSIDH(md5_h, "$Id$")
 #define        MD5_BLOCK_LENGTH                64
 #define        MD5_DIGEST_LENGTH               16
 
-typedef struct lrad_MD5Context {
+typedef struct MD5Context {
        uint32_t state[4];                      /* state */
        uint32_t count[2];                      /* number of bits, mod 2^64 */
        uint8_t buffer[MD5_BLOCK_LENGTH];       /* input buffer */
-} lrad_MD5_CTX;
+} MD5_CTX;
 
 /* include <sys/cdefs.h> */
 
 /* __BEGIN_DECLS */
-void    lrad_MD5Init(lrad_MD5_CTX *);
-void    lrad_MD5Update(lrad_MD5_CTX *, const uint8_t *, size_t)
+void    MD5Init(MD5_CTX *);
+void    MD5Update(MD5_CTX *, const uint8_t *, size_t)
 /*             __attribute__((__bounded__(__string__,2,3)))*/;
-void    lrad_MD5Final(uint8_t [MD5_DIGEST_LENGTH], lrad_MD5_CTX *)
+void    MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *)
 /*             __attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)))*/;
-void    lrad_MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH])
+void    MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH])
 /*             __attribute__((__bounded__(__minbytes__,1,4)))*/
 /*             __attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH)))*/;
 /* __END_DECLS */
index 0e3b3c9..caa7d3f 100644 (file)
@@ -8,75 +8,6 @@
  * Version:    $Id$
  *
  */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(missing_h, "$Id$")
-
-#include <freeradius-devel/autoconf.h>
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include       <netinet/in.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include       <arpa/inet.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-/*
- *  Check for inclusion of <time.h>, versus <sys/time.h>
- *  Taken verbatim from the autoconf manual.
- */
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#ifdef HAVE_WINSOCK_H
-#include <winsock.h>
-#endif
-
-/*
- *     Functions from missing.c
- */
-
 #ifndef HAVE_STRNCASECMP
 extern int strncasecmp(char *s1, char *s2, int n);
 #endif
@@ -90,7 +21,6 @@ extern char *strsep(char **stringp, const char *delim);
 #endif
 
 #ifndef HAVE_LOCALTIME_R
-struct tm;
 struct tm *localtime_r(const time_t *l_clock, struct tm *result);
 #endif
 
@@ -115,6 +45,10 @@ struct in_addr;
 int inet_aton(char *cp, struct in_addr *inp);
 #endif
 
+#ifdef NEED_DECLARATION_GETHOSTNAME
+int gethostname(char *name, int len);
+#endif
+
 #ifndef HAVE_SETLINEBUF
 #ifdef HAVE_SETVBUF
 #define setlinebuf(x) setvbuf(x, NULL, _IOLBF, 0)
@@ -147,218 +81,4 @@ void endusershell(void);
 #define INADDR_NONE     ((uint32_t) 0xffffffff)
 #endif
 
-#ifndef INADDRSZ
-#define INADDRSZ 4
-#endif
-
-#ifndef INET_ADDRSTRLEN
-#define INET_ADDRSTRLEN 16
-#endif
-
-#ifndef AF_UNSPEC
-#define AF_UNSPEC 0
-#endif
-
-#ifndef AF_INET6
-#define AF_INET6 10
-#endif
-
-#ifndef HAVE_STRUCT_IN6_ADDR
-struct in6_addr
-{
-       union {
-               uint8_t u6_addr8[16];
-               uint16_t u6_addr16[8];
-               uint32_t u6_addr32[4];
-       } in6_u;
-#define s6_addr                        in6_u.u6_addr8
-#define s6_addr16              in6_u.u6_addr16
-#define s6_addr32              in6_u.u6_addr32
-};
-
-#ifndef IN6ADDRSZ
-#define IN6ADDRSZ 16
-#endif
-
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif
-
-#ifndef IN6ADDR_ANY_INIT
-#define IN6ADDR_ANY_INIT       {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
-#endif
-
-#ifndef IN6ADDR_LOOPBACK_INIT
-#define IN6ADDR_LOOPBACK_INIT  {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
-#endif
-
-#ifndef IN6_IS_ADDR_UNSPECIFIED
-#define IN6_IS_ADDR_UNSPECIFIED(a) \
-       (((__const uint32_t *) (a))[0] == 0                                   \
-        && ((__const uint32_t *) (a))[1] == 0                                \
-        && ((__const uint32_t *) (a))[2] == 0                                \
-        && ((__const uint32_t *) (a))[3] == 0)
-#endif
-
-#ifndef IN6_IS_ADDR_LOOPBACK
-#define IN6_IS_ADDR_LOOPBACK(a) \
-       (((__const uint32_t *) (a))[0] == 0                                   \
-        && ((__const uint32_t *) (a))[1] == 0                                \
-        && ((__const uint32_t *) (a))[2] == 0                                \
-        && ((__const uint32_t *) (a))[3] == htonl (1))
-#endif
-
-#ifndef IN6_IS_ADDR_MULTICAST
-#define IN6_IS_ADDR_MULTICAST(a) (((__const uint8_t *) (a))[0] == 0xff)
-#endif
-
-#ifndef IN6_IS_ADDR_LINKLOCAL
-#define IN6_IS_ADDR_LINKLOCAL(a) \
-       ((((__const uint32_t *) (a))[0] & htonl (0xffc00000))                 \
-        == htonl (0xfe800000))
-#endif
-
-#ifndef IN6_IS_ADDR_SITELOCAL
-#define IN6_IS_ADDR_SITELOCAL(a) \
-       ((((__const uint32_t *) (a))[0] & htonl (0xffc00000))                 \
-        == htonl (0xfec00000))
-#endif
-
-#ifndef IN6_IS_ADDR_V4MAPPED
-#define IN6_IS_ADDR_V4MAPPED(a) \
-       ((((__const uint32_t *) (a))[0] == 0)                                 \
-        && (((__const uint32_t *) (a))[1] == 0)                              \
-        && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
-#endif
-
-#ifndef IN6_IS_ADDR_V4COMPAT
-#define IN6_IS_ADDR_V4COMPAT(a) \
-       ((((__const uint32_t *) (a))[0] == 0)                                 \
-        && (((__const uint32_t *) (a))[1] == 0)                              \
-        && (((__const uint32_t *) (a))[2] == 0)                              \
-        && (ntohl (((__const uint32_t *) (a))[3]) > 1))
-#endif
-
-#ifndef IN6_ARE_ADDR_EQUAL
-#define IN6_ARE_ADDR_EQUAL(a,b) \
-       ((((__const uint32_t *) (a))[0] == ((__const uint32_t *) (b))[0])     \
-        && (((__const uint32_t *) (a))[1] == ((__const uint32_t *) (b))[1])  \
-        && (((__const uint32_t *) (a))[2] == ((__const uint32_t *) (b))[2])  \
-        && (((__const uint32_t *) (a))[3] == ((__const uint32_t *) (b))[3]))
-#endif
-
-#endif /* HAVE_STRUCT_IN6_ADDR */
-
-/*
- *     Functions from getaddrinfo.c
- */
-
-#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
-struct sockaddr_storage
-{
-    uint16_t ss_family;        /* Address family, etc.  */
-    char ss_padding[128 - (sizeof(uint16_t))];
-};
-#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
-
-#ifndef HAVE_STRUCT_ADDRINFO
-
-/* for old netdb.h */
-#ifndef EAI_SERVICE
-#define EAI_MEMORY      2
-#define EAI_FAMILY      5    /* ai_family not supported */
-#define EAI_NONAME      8    /* hostname nor servname provided, or not known */
-#define EAI_SERVICE     9   /* servname not supported for ai_socktype */
-#endif
-
-/* dummy value for old netdb.h */
-#ifndef AI_PASSIVE
-#define AI_PASSIVE      1
-#define AI_CANONNAME    2
-#define AI_NUMERICHOST  4
-#define NI_NUMERICHOST  2
-#define NI_NAMEREQD     4
-#define NI_NUMERICSERV  8
-
-struct addrinfo
-{
-  int ai_flags;                        /* Input flags.  */
-  int ai_family;               /* Protocol family for socket.  */
-  int ai_socktype;             /* Socket type.  */
-  int ai_protocol;             /* Protocol for socket.  */
-  socklen_t ai_addrlen;                /* Length of socket address.  */
-  struct sockaddr *ai_addr;    /* Socket address for socket.  */
-  char *ai_canonname;          /* Canonical name for service location.  */
-  struct addrinfo *ai_next;    /* Pointer to next in list.  */
-};
-
-#endif /* AI_PASSIVE */
-
-#endif /* HAVE_STRUCT_ADDRINFO */
-
-/* Translate name of a service location and/or a service name to set of
-   socket addresses. */
-#ifndef HAVE_GETADDRINFO
-extern int getaddrinfo (const char *__name,
-                       const char *__service,
-                       const struct addrinfo *__req,
-                       struct addrinfo **__pai);
-
-/* Free `addrinfo' structure AI including associated storage.  */
-extern void freeaddrinfo (struct addrinfo *__ai);
-
-/* Convert error return from getaddrinfo() to a string.  */
-extern char *gai_strerror (int __ecode);
-#endif
-
-/* Translate a socket address to a location and service name. */
-#ifndef HAVE_GETNAMEINFO
-extern int getnameinfo (const struct sockaddr *__sa,
-                       socklen_t __salen, char *__host,
-                       size_t __hostlen, char *__serv,
-                       size_t __servlen, unsigned int __flags);
-#endif
-
-/*
- *     Functions from snprintf.c
- */
-
-#ifndef HAVE_VSNPRINTF
-#include <stdarg.h>
-extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
-#endif
-
-#ifndef HAVE_SNPRINTF
-extern int snprintf(char *str, size_t count, const char *fmt, ...);
-#endif
-
-/*
- *     Functions from strl{cat,cpy}.c
- */
-
-#ifndef HAVE_STRLCPY
-extern size_t strlcpy(char *dst, const char *src, size_t siz);
-#endif
-
-#ifndef HAVE_STRLCAT
-extern size_t strlcat(char *dst, const char *src, size_t siz);
-#endif
-
-#ifndef INT16SZ
-#define INT16SZ (2)
-#endif
-
-#ifndef HAVE_GMTIME_R
-struct tm *gmtime_r(const time_t *l_clock, struct tm *result);
-#endif
-
-#ifndef HAVE_GETTIMEOFDAY
-int gettimeofday (struct timeval *tv, void *tz);
-#endif
-
-#ifdef WIN32
-#undef mkdir
-#define mkdir(_d, _p) mkdir(_d)
-#endif
-
 #endif /* _FR_MISSING_H */
index daf63a8..adb472f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Version: $Id$ */
 
-#include <freeradius-devel/conffile.h> /* Need CONF_* definitions */
+#include "conffile.h" /* Need CONF_* definitions */
 
 /*
  *     For each authorize/authtype/etc, we have an ordered
@@ -17,19 +17,18 @@ int modcall(int component, modcallable *c, REQUEST *request);
 
 /* Parse a module-method's config section (e.g. authorize{}) into a tree that
  * may be called with modcall() */
-modcallable *compile_modgroup(modcallable *parent,
-                             int component, CONF_SECTION *cs,
-                             const char *filename);
+modcallable *compile_modgroup(int component, CONF_SECTION *cs,
+               const char *filename);
 
 /* Create a single modcallable node that references a module instance. This
  * may be a CONF_SECTION containing action specifiers like "notfound = return"
  * or a simple CONF_PAIR, in which case the default actions are used. */
-modcallable *compile_modsingle(modcallable *parent, int component, CONF_ITEM *ci,
-                              const char *filename, const char **modname);
+modcallable *compile_modsingle(int component, CONF_ITEM *ci,
+               const char *filename, const char **modname);
 
 /* Add an entry to the end of a modgroup, creating it first if necessary */
 void add_to_modcallable(modcallable **parent, modcallable *this,
-                       int component, const char *name);
+               int component, char *name);
 
 /* Free a tree returned by compile_modgroup or compile_modsingle */
 void modcallable_free(modcallable **pc);
index a85c5ff..0aef7ff 100644 (file)
@@ -2,18 +2,19 @@
  * accessed from anywhere else.
  *
  * Version: $Id$ */
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "radiusd.h"
+#include "modules.h"
 #include "ltdl.h"
 
 /*
  *     Keep track of which modules we've loaded.
  */
-typedef struct module_entry_t {
+typedef struct module_list_t {
+       struct module_list_t    *next;
        char                    name[MAX_STRING_LEN];
-       const module_t          *module;
+       module_t                *module;
        lt_dlhandle             handle;
-} module_entry_t;
+} module_list_t;
 
 /*
  *     Per-instance data structure, to correlate the modules
@@ -21,12 +22,13 @@ typedef struct module_entry_t {
  *     and the per-instance data structures.
  */
 typedef struct module_instance_t {
+       struct module_instance_t *next;
        char                    name[MAX_STRING_LEN];
-       module_entry_t          *entry;
+       module_list_t           *entry;
        void                    *insthandle;
 #ifdef HAVE_PTHREAD_H
        pthread_mutex_t         *mutex;
 #endif
 } module_instance_t;
 
-module_instance_t *find_module_instance(CONF_SECTION *, const char *instname);
+module_instance_t *find_module_instance(const char *instname);
index 0b3942b..0d65f98 100644 (file)
@@ -7,11 +7,7 @@
 
 #ifndef RADIUS_MODULES_H
 #define RADIUS_MODULES_H
-
-#include <freeradius-devel/ident.h>
-RCSIDH(modules_h, "$Id$")
-
-#include <freeradius-devel/conffile.h>
+#include "conffile.h"
 
 typedef int (*packetmethod)(void *instance, REQUEST *request);
 
@@ -30,18 +26,18 @@ enum {
 #define RLM_TYPE_THREAD_SAFE   (0 << 0)
 #define RLM_TYPE_THREAD_UNSAFE (1 << 0)
 
-#define RLM_MODULE_MAGIC_NUMBER ((uint32_t) (0xf4ee4ad2))
-#define RLM_MODULE_INIT RLM_MODULE_MAGIC_NUMBER
-
 typedef struct module_t {
-       uint32_t        magic;  /* may later be opaque struct */
        const char      *name;
-       int             type;
-       int             (*instantiate)(CONF_SECTION *mod_cs, void **instance);
-       int             (*detach)(void *instance);
+       int     type;                   /* reserved */
+       int     (*init)(void);
+       int     (*instantiate)(CONF_SECTION *mod_cs, void **instance);
        packetmethod    methods[RLM_COMPONENT_COUNT];
+       int     (*detach)(void *instance);
+       int     (*destroy)(void);
 } module_t;
 
+extern const char *component_names[RLM_COMPONENT_COUNT];
+
 enum {
        RLM_MODULE_REJECT,      /* immediately reject the request */
        RLM_MODULE_FAIL,        /* module failed, don't reply */
@@ -55,7 +51,7 @@ enum {
        RLM_MODULE_NUMCODES     /* How many return codes there are */
 };
 
-int setup_modules(int);
+int setup_modules(void);
 int detach_modules(void);
 int module_authorize(int type, REQUEST *request);
 int module_authenticate(int type, REQUEST *request);
diff --git a/src/include/packet.h b/src/include/packet.h
deleted file mode 100644 (file)
index 120dd68..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef LRAD_PACKET_H
-#define LRAD_PACKET_H
-
-/*
- * packet.h    Structures and prototypes
- *             for packet manipulation
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2001,2002,2003,2004,2005,2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(packet_h, "$Id$")
-
-uint32_t lrad_request_packet_hash(const RADIUS_PACKET *packet);
-uint32_t lrad_reply_packet_hash(const RADIUS_PACKET *packet);
-int lrad_packet_cmp(const RADIUS_PACKET *a, const RADIUS_PACKET *b);
-void lrad_request_from_reply(RADIUS_PACKET *request,
-                            const RADIUS_PACKET *reply);
-int lrad_socket(lrad_ipaddr_t *ipaddr, int port);
-
-typedef struct lrad_packet_list_t lrad_packet_list_t;
-
-lrad_packet_list_t *lrad_packet_list_create(int alloc_id);
-void lrad_packet_list_free(lrad_packet_list_t *pl);
-int lrad_packet_list_insert(lrad_packet_list_t *pl,
-                           RADIUS_PACKET **request_p);
-
-RADIUS_PACKET **lrad_packet_list_find(lrad_packet_list_t *pl,
-                                     RADIUS_PACKET *request);
-RADIUS_PACKET **lrad_packet_list_find_byreply(lrad_packet_list_t *pl,
-                                             RADIUS_PACKET *reply);
-RADIUS_PACKET **lrad_packet_list_yank(lrad_packet_list_t *pl,
-                                     RADIUS_PACKET *request);
-int lrad_packet_list_num_elements(lrad_packet_list_t *pl);
-int lrad_packet_list_id_alloc(lrad_packet_list_t *pl,
-                             RADIUS_PACKET *request);
-int lrad_packet_list_id_free(lrad_packet_list_t *pl,
-                            RADIUS_PACKET *request);
-int lrad_packet_list_socket_add(lrad_packet_list_t *pl, int sockfd);
-int lrad_packet_list_socket_remove(lrad_packet_list_t *pl, int sockfd);
-int lrad_packet_list_walk(lrad_packet_list_t *pl, void *ctx,
-                         lrad_hash_table_walk_t callback);
-int lrad_packet_list_fd_set(lrad_packet_list_t *pl, fd_set *set);
-RADIUS_PACKET *lrad_packet_list_recv(lrad_packet_list_t *pl, fd_set *set);
-
-int lrad_packet_list_num_incoming(lrad_packet_list_t *pl);
-int lrad_packet_list_num_outgoing(lrad_packet_list_t *pl);
-
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-/*
- *     "find" returns a pointer to the RADIUS_PACKET* member in the
- *     caller's structure.  In order to get the pointer to the *top*
- *     of the caller's structure, you have to subtract the offset to
- *     the member from the returned pointer, and cast it to the
- *     required type.
- */
-# define lrad_packet2myptr(TYPE, MEMBER, PTR) (TYPE *) (((char *)PTR) - offsetof(TYPE, MEMBER))
-#endif /* LRAD_PACKET_H */
index 677f842..91e361e 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2001,2006  The FreeRADIUS server project
+ * Copyright 2000,2001  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rad_assert_h, "$Id$")
-
 extern void rad_assert_fail (const char *file, unsigned int line);
 
 #ifdef NDEBUG
        #define rad_assert(expr) ((void) (0))
 #else
        #define rad_assert(expr) \
-               ((void) ((expr) ? (void) 0 : \
-                       (void) rad_assert_fail (__FILE__, __LINE__)))
+               ((void) ((expr) ? 0 : \
+                       rad_assert_fail (__FILE__, __LINE__)))
 #endif
 
 #endif
index a519668..188df8f 100644 (file)
@@ -15,8 +15,6 @@
 #define PW_TYPE_IFID                   6
 #define PW_TYPE_IPV6ADDR               7
 #define PW_TYPE_IPV6PREFIX             8
-#define PW_TYPE_BYTE                   9
-#define PW_TYPE_SHORT                  10
 
 #define        PW_AUTHENTICATION_REQUEST       1
 #define        PW_AUTHENTICATION_ACK           2
 #define PW_FRAMED_POOL                 88
 #define PW_NAS_IPV6_ADDRESS            95
 
-#define PW_EXTENDED_ATTRIBUTE          192
-
 #define PW_DIGEST_RESPONSE             206
 #define PW_DIGEST_ATTRIBUTES           207
 
 #define PW_FALL_THROUGH                        500
+#define PW_ADD_PORT_TO_IP_ADDRESS      501
 #define PW_EXEC_PROGRAM                        502
 #define PW_EXEC_PROGRAM_WAIT           503
 
 #define PW_PACKET_DST_PORT             1087
 #define PW_PACKET_AUTHENTICATION_VECTOR        1088
 #define PW_TIME_OF_DAY                 1089
-#define PW_REQUEST_PROCESSING_STAGE    1090
-#define PW_CACHE_NO_CACHING            1091
-#define PW_CACHE_DELETE_CACHE          1092
 
 #define PW_SHA_PASSWORD                        1093
 #define PW_SSHA_PASSWORD               1094
 #define PW_MD5_PASSWORD                        1095
 #define PW_SMD5_PASSWORD               1096
-
-#define PW_PACKET_SRC_IPV6_ADDRESS     1097
-#define PW_PACKET_DST_IPV6_ADDRESS     1098
-#define PW_SERVER_IDENTITY             1099
 #define PW_CLEARTEXT_PASSWORD          1100
 #define PW_PASSWORD_WITH_HEADER                1101
 
+
 /*
  *     Integer Translations
  */
index 3448aec..1ef2b85 100644 (file)
@@ -3,10 +3,6 @@
 /*
  * Version:    $Id$
  */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(radius_snmp_h, "$Id$")
-
 #ifdef WITH_SNMP
 
 typedef enum smux_event_t {
@@ -45,7 +41,7 @@ typedef struct rad_snmp_server_t {
 typedef struct rad_snmp_t {
        rad_snmp_server_t auth;
        rad_snmp_server_t acct;
-       smux_event_t      smux_event;
+       smux_event_t      smux_event;
        const char        *smux_password;
        int               snmp_write_access;
        int               smux_fd;
@@ -56,21 +52,28 @@ typedef struct rad_snmp_t {
 /*
  *  Taken from RFC 2619 and RFC 2621
  */
-struct rad_snmp_client_entry_t {
+typedef struct rad_snmp_client_entry_t {
        int             index;
        /* IP address */
        /* Client ID (string ) */
-       uint32_t        requests;
-       uint32_t        dup_requests;
-       uint32_t        responses;
-       uint32_t        accepts;
-       uint32_t        rejects;
-       uint32_t        challenges;
-       uint32_t        malformed_requests;
-       uint32_t        bad_authenticators;
-       uint32_t        packets_dropped;
-       uint32_t        unknown_types;
-};
+       int             access_requests;
+       int             dup_access_requests;
+       int             access_accepts;
+       int             access_rejects;
+       int             access_challenges;
+       int             auth_malformed_requests;
+       int             auth_bad_authenticators;
+       int             auth_packets_dropped;
+       int             auth_unknown_types;
+       int             acct_packets_dropped;
+       int             acct_requests;
+       int             acct_dup_requests;
+       int             acct_responses;
+       int             acct_bad_authenticators;
+       int             acct_malformed_requests;
+       int             acct_no_records;
+       int             acct_unknown_types;
+} rad_snmp_client_entry_t;
 
 extern rad_snmp_t      rad_snmp;
 
@@ -79,19 +82,12 @@ extern rad_snmp_t   rad_snmp;
                                      if (_listener->type == RAD_LISTEN_AUTH) { \
                                        rad_snmp.auth._x++; \
                                     } else { if (_listener->type == RAD_LISTEN_ACCT) \
-                                       rad_snmp.acct._x++; } }
-
-#define RAD_SNMP_CLIENT_INC(_listener, _client, _x) if (mainconfig.do_snmp) { \
-                                     if (_listener->type == RAD_LISTEN_AUTH) { \
-                                       _client->auth->_x++; \
-                                    } else { if (_listener->type == RAD_LISTEN_ACCT) \
-                                       _client->acct->_x++; } }
+                                       rad_snmp.acct._x++; } } \
 
 
 #else
 #define  RAD_SNMP_INC(_x)
 #define RAD_SNMP_TYPE_INC(_listener, _x)
-#define RAD_SNMP_CLIENT_INC(_listener, _client, _x)
 
 #endif /* WITH_SNMP */
 
index 205a026..a966950 100644 (file)
@@ -7,19 +7,16 @@
  * Version:    $Id$
  *
  */
+#include "libradius.h"
+#include "radpaths.h"
+#include "conf.h"
+#include "conffile.h"
 
-#include <freeradius-devel/ident.h>
-RCSIDH(radiusd_h, "$Id$")
+#include <stdarg.h>
 
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/radpaths.h>
-#include <freeradius-devel/conf.h>
-#include <freeradius-devel/conffile.h>
-#include <freeradius-devel/event.h>
-
-typedef struct auth_req REQUEST;
-
-#include <freeradius-devel/realms.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 #ifdef HAVE_PTHREAD_H
 #include       <pthread.h>
@@ -30,6 +27,16 @@ typedef pid_t child_pid_t;
 #define child_kill kill
 #endif
 
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "missing.h"
+
 #define NO_SUCH_CHILD_PID (child_pid_t) (0)
 
 #ifndef NDEBUG
@@ -41,48 +48,10 @@ typedef pid_t child_pid_t;
  */
 typedef struct request_data_t request_data_t;
 
-typedef struct rad_snmp_client_entry_t rad_snmp_client_entry_t;
-
-typedef struct radclient {
-       lrad_ipaddr_t           ipaddr;
-       int                     prefix;
-       char                    *longname;
-       char                    *secret;
-       char                    *shortname;
-       char                    *nastype;
-       char                    *login;
-       char                    *password;
-       int                     number; /* internal use only */
-#ifdef WITH_SNMP
-       rad_snmp_client_entry_t *auth, *acct;
-#endif
-} RADCLIENT;
-
-/*
- *     Types of listeners.
- *
- *     Ordered by priority!
- */
-typedef enum RAD_LISTEN_TYPE {
-       RAD_LISTEN_NONE = 0,
-       RAD_LISTEN_PROXY,
-       RAD_LISTEN_AUTH,
-       RAD_LISTEN_ACCT,
-       RAD_LISTEN_DETAIL,
-       RAD_LISTEN_SNMP,
-       RAD_LISTEN_MAX
-} RAD_LISTEN_TYPE;
-
-
-/*
- *     For listening on multiple IP's and ports.
- */
-typedef struct rad_listen_t rad_listen_t;
-
 #define REQUEST_DATA_REGEX (0xadbeef00)
 #define REQUEST_MAX_REGEX (8)
 
-struct auth_req {
+typedef struct auth_req {
 #ifndef NDEBUG
        uint32_t                magic; /* for debugging only */
 #endif
@@ -93,155 +62,160 @@ struct auth_req {
        VALUE_PAIR              *config_items;
        VALUE_PAIR              *username;
        VALUE_PAIR              *password;
-
        request_data_t          *data;
-       RADCLIENT               *client;
+       char                    secret[32];
        child_pid_t             child_pid;
        time_t                  timestamp;
        int                     number; /* internal server number */
 
-       rad_listen_t            *listener;
-       rad_listen_t            *proxy_listener;
+       /*
+        *      We could almost keep a const char here instead of a
+        *      _copy_ of the secret... but what if the RADCLIENT
+        *      structure is freed because it was taken out of the
+        *      config file and SIGHUPed?
+        */
+       char                    proxysecret[32];
+       int                     proxy_try_count;
+       int                     proxy_outstanding;
+       time_t                  proxy_next_try;
 
        int                     simul_max;
        int                     simul_count;
        int                     simul_mpp; /* WEIRD: 1 is false, 2 is true */
 
+       int                     finished;
        int                     options; /* miscellanous options */
-       const char              *module; /* for debugging unresponsive children */
-       const char              *component; /* ditto */
-
-       struct timeval          received;
-       struct timeval          when;           /* to wake up */
-       int                     delay;
-
-       int                     master_state;
-       int                     child_state;
-       RAD_LISTEN_TYPE         priority;
-
-       lrad_event_t            *ev;
-       struct timeval          next_when;
-       lrad_event_callback_t   next_callback;
-
-       int                     in_request_hash;
-       int                     in_proxy_hash;
-
-       home_server             *home_server;
-       home_pool_t             *home_pool; /* for dynamic failover */
-
-       struct timeval          proxy_when;
-
-       int                     num_proxied_requests;
-       int                     num_proxied_responses;
-};                             /* REQUEST typedef */
+       void                    *container;
+} REQUEST;
 
 #define RAD_REQUEST_OPTION_NONE            (0)
-
-#define REQUEST_ACTIVE                 (1)
-#define REQUEST_STOP_PROCESSING (2)
-#define REQUEST_COUNTED                (3)
-
-#define REQUEST_QUEUED         (1)
-#define REQUEST_RUNNING                (2)
-#define REQUEST_PROXIED                (3)
-#define REQUEST_REJECT_DELAY   (4)
-#define REQUEST_CLEANUP_DELAY  (5)
-#define REQUEST_DONE           (6)
+#define RAD_REQUEST_OPTION_LOGGED_CHILD    (1 << 0)
+#define RAD_REQUEST_OPTION_DELAYED_REJECT  (1 << 1)
+#define RAD_REQUEST_OPTION_DONT_CACHE      (1 << 2)
+#define RAD_REQUEST_OPTION_FAKE_REQUEST    (1 << 3)
+#define RAD_REQUEST_OPTION_REJECTED        (1 << 4)
+#define RAD_REQUEST_OPTION_PROXIED         (1 << 5)
 
 /*
  *  Function handler for requests.
  */
 typedef                int (*RAD_REQUEST_FUNP)(REQUEST *);
 
-typedef struct radclient_list RADCLIENT_LIST;
+typedef struct radclient {
+       uint32_t                ipaddr;
+       uint32_t                netmask;
+       char                    longname[256];
+       u_char                  secret[32];
+       char                    shortname[32];
+       char                    nastype[32];
+       char                    login[32];
+       char                    password[32];
+       struct radclient        *next;
+} RADCLIENT;
+
+typedef struct nas {
+       uint32_t                ipaddr;
+       char                    longname[256];
+       char                    shortname[32];
+       char                    nastype[32];
+       struct nas              *next;
+} NAS;
+
+typedef struct _realm {
+       char                    realm[64];
+       char                    server[64];
+       char                    acct_server[64];
+       uint32_t                ipaddr; /* authentication */
+       uint32_t                acct_ipaddr;
+       u_char                  secret[32];
+       time_t                  last_reply; /* last time we saw a packet */
+       int                     auth_port;
+       int                     acct_port;
+       int                     striprealm;
+       int                     trusted; /* old */
+       int                     notrealm;
+       int                     active; /* is it dead? */
+       time_t                  wakeup; /* when we should try it again */
+       int                     acct_active;
+       time_t                  acct_wakeup;
+       int                     ldflag;
+       struct _realm           *next;
+} REALM;
 
 typedef struct pair_list {
        char                    *name;
        VALUE_PAIR              *check;
        VALUE_PAIR              *reply;
        int                     lineno;
-       int                     order;
        struct pair_list        *next;
        struct pair_list        *lastdefault;
 } PAIR_LIST;
 
 
-typedef int (*rad_listen_recv_t)(rad_listen_t *, RAD_REQUEST_FUNP *, REQUEST **);
-typedef int (*rad_listen_send_t)(rad_listen_t *, REQUEST *);
-typedef int (*rad_listen_print_t)(rad_listen_t *, char *, size_t);
-typedef int (*rad_listen_encode_t)(rad_listen_t *, REQUEST *);
-typedef int (*rad_listen_decode_t)(rad_listen_t *, REQUEST *);
+/*
+ *     Types of listeners.
+ */
+typedef enum RAD_LISTEN_TYPE {
+       RAD_LISTEN_NONE = 0,
+       RAD_LISTEN_AUTH,
+       RAD_LISTEN_ACCT,
+       RAD_LISTEN_PROXY
+} RAD_LISTEN_TYPE;
 
-struct rad_listen_t {
-       struct rad_listen_t *next; /* should be rbtree stuff */
 
-       /*
-        *      For normal sockets.
-        */
+/*
+ *     For listening on multiple IP's and ports.
+ */
+typedef struct rad_listen_t {
+       struct rad_listen_t *next; /* could be rbtree stuff */
+       uint32_t        ipaddr;
        RAD_LISTEN_TYPE type;
+       int             port;
        int             fd;
-       const char      *identity;
-
-       rad_listen_recv_t recv;
-       rad_listen_send_t send;
-       rad_listen_encode_t encode;
-       rad_listen_decode_t decode;
-       rad_listen_print_t print;
-
-       void            *data;
-};
+} rad_listen_t;
 
 
-typedef enum radlog_dest_t {
-  RADLOG_STDOUT = 0,
-  RADLOG_FILES,
-  RADLOG_SYSLOG,
-  RADLOG_STDERR,
-  RADLOG_NULL,
-  RADLOG_NUM_DEST
-} radlog_dest_t;
-
 typedef struct main_config_t {
        struct main_config *next;
        time_t          config_dead_time;
-       lrad_ipaddr_t   myip;   /* from the command-line only */
-       int             port;   /* from the command-line only */
+       uint32_t        myip;
        int             log_auth;
        int             log_auth_badpass;
        int             log_auth_goodpass;
+       int             do_usercollide;
 #ifdef WITH_SNMP
        int             do_snmp;
 #endif
        int             allow_core_dumps;
        int             debug_level;
        int             proxy_requests;
+       int             post_proxy_authorize;
        int             wake_all_if_all_dead;
        int             proxy_synchronous;
        int             proxy_dead_time;
        int             proxy_retry_count;
        int             proxy_retry_delay;
        int             proxy_fallback;
-       const char      *proxy_fail_type;
        int             reject_delay;
        int             status_server;
        int             max_request_time;
        int             cleanup_delay;
        int             max_requests;
-#ifdef DELETE_BLOCKED_REQUESTS
        int             kill_unresponsive_children;
-#endif
+       char            *do_lower_user;
+       char            *do_lower_pass;
+       char            *do_nospace_user;
+       char            *do_nospace_pass;
+       char            *nospace_time;
        char            *log_file;
        char            *checkrad;
        const char      *pid_file;
        const char      *uid_name;
        const char      *gid_name;
        rad_listen_t    *listen;
-       int             syslog_facility;
-       int             radlog_fd;
-       radlog_dest_t   radlog_dest;
        CONF_SECTION    *config;
-       RADCLIENT_LIST  *clients;
-       const char      *radiusd_conf;
+       RADCLIENT       *clients;
+       REALM           *realms;
 } MAIN_CONFIG_T;
 
 #define DEBUG  if(debug_flag)log_debug
@@ -261,7 +235,6 @@ typedef struct main_config_t {
 #define L_INFO                 3
 #define L_ERR                  4
 #define L_PROXY                        5
-#define L_ACCT                 6
 #define L_CONS                 128
 
 #ifndef FALSE
@@ -279,19 +252,13 @@ typedef struct main_config_t {
 /* for paircompare_register */
 typedef int (*RAD_COMPARE_FUNC)(void *instance, REQUEST *,VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **);
 
-typedef enum request_fail_t {
-  REQUEST_FAIL_UNKNOWN = 0,
-  REQUEST_FAIL_NO_THREADS,     /* no threads to handle it */
-  REQUEST_FAIL_DECODE,         /* rad_decode didn't like it */
-  REQUEST_FAIL_PROXY,          /* call to proxy modules failed */
-  REQUEST_FAIL_PROXY_SEND,     /* proxy_send didn't like it */
-  REQUEST_FAIL_NO_RESPONSE,    /* we weren't told to respond, so we reject */
-  REQUEST_FAIL_HOME_SERVER,    /* the home server didn't respond */
-  REQUEST_FAIL_HOME_SERVER2,   /* another case of the above */
-  REQUEST_FAIL_HOME_SERVER3,   /* another case of the above */
-  REQUEST_FAIL_NORMAL_REJECT,  /* authentication failure */
-  REQUEST_FAIL_SERVER_TIMEOUT  /* the server took too long to process the request */
-} request_fail_t;
+typedef enum radlog_dest_t {
+  RADLOG_FILES = 0,
+  RADLOG_SYSLOG,
+  RADLOG_STDOUT,
+  RADLOG_STDERR,
+  RADLOG_NULL
+} radlog_dest_t;
 
 /*
  *     Global variables.
@@ -300,23 +267,18 @@ typedef enum request_fail_t {
  */
 extern const char      *progname;
 extern int             debug_flag;
+extern int             syslog_facility;
 extern const char      *radacct_dir;
 extern const char      *radlog_dir;
 extern const char      *radlib_dir;
 extern const char      *radius_dir;
 extern const char      *radius_libdir;
+extern radlog_dest_t   radlog_dest;
 extern uint32_t                expiration_seconds;
 extern int             log_stripped_names;
 extern int             log_auth_detail;
+extern int             acct_port;
 extern const char      *radiusd_version;
-void                   radius_signal_self(int flag);
-
-#define RADIUS_SIGNAL_SELF_NONE                (0)
-#define RADIUS_SIGNAL_SELF_HUP         (1 << 0)
-#define RADIUS_SIGNAL_SELF_TERM                (1 << 1)
-#define RADIUS_SIGNAL_SELF_EXIT                (1 << 2)
-#define RADIUS_SIGNAL_SELF_DETAIL      (1 << 3)
-
 
 /*
  *     Function prototypes.
@@ -331,13 +293,14 @@ int               rad_check_ts(uint32_t nasaddr, unsigned int port, const char *user,
 int            session_zap(REQUEST *request, uint32_t nasaddr,
                            unsigned int port, const char *user,
                            const char *sessionid, uint32_t cliaddr,
-                           char proto,int session_time);
+                           char proto);
 
 /* radiusd.c */
 #ifndef _LIBRADIUS
 void           debug_pair(FILE *, VALUE_PAIR *);
 #endif
 int            log_err (char *);
+int            rad_respond(REQUEST *, RAD_REQUEST_FUNP fun);
 
 /* util.c */
 void (*reset_signal(int signo, void (*func)(int)))(int);
@@ -345,6 +308,7 @@ void                request_free(REQUEST **request);
 int            rad_mkdir(char *directory, int mode);
 int            rad_checkfilename(const char *filename);
 void           *rad_malloc(size_t size); /* calls exit(1) on error! */
+void           xfree(const char *ptr);
 REQUEST                *request_alloc(void);
 REQUEST                *request_alloc_fake(REQUEST *oldreq);
 int            request_data_add(REQUEST *request,
@@ -352,35 +316,33 @@ int               request_data_add(REQUEST *request,
                                 void *opaque, void (*free_opaque)(void *));
 void           *request_data_get(REQUEST *request,
                                  void *unique_ptr, int unique_int);
-void           *request_data_reference(REQUEST *request,
-                                 void *unique_ptr, int unique_int);
-int            rad_copy_string(char *dst, const char *src);
-int            rad_copy_variable(char *dst, const char *from);
-
-/* request_process.c */
-int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun);
-void           request_reject(REQUEST *request, request_fail_t reason);
+void           request_reject(REQUEST *request);
+void           rfc_clean(RADIUS_PACKET *packet);
 
 /* client.c */
-RADCLIENT_LIST *clients_init(void);
-void           clients_free(RADCLIENT_LIST *clients);
-RADCLIENT_LIST *clients_parse_section(const char *filename,
-                                      CONF_SECTION *section);
-void           client_free(RADCLIENT *client);
-int            client_add(RADCLIENT_LIST *clients, RADCLIENT *client);
-RADCLIENT      *client_find(const RADCLIENT_LIST *clients,
-                            const lrad_ipaddr_t *ipaddr);
-const char     *client_name(const RADCLIENT_LIST *clients,
-                            const lrad_ipaddr_t *ipaddr);
-RADCLIENT      *client_findbynumber(const RADCLIENT_LIST *clients,
-                                    int number);
-RADCLIENT      *client_find_old(const lrad_ipaddr_t *ipaddr);
-const char     *client_name_old(const lrad_ipaddr_t *ipaddr);
+int            read_clients_file(const char *file);
+RADCLIENT      *client_find(uint32_t ipno);
+const char     *client_name(uint32_t ipno);
+void           client_walk(void);
+void           clients_free(RADCLIENT *cl);
 
 /* files.c */
+REALM          *realm_find(const char *, int);
+REALM          *realm_findbyaddr(uint32_t ipno, int port);
+void           realm_free(REALM *cl);
+void           realm_disable(uint32_t ipno, int port);
 int            pairlist_read(const char *file, PAIR_LIST **list, int complain);
 void           pairlist_free(PAIR_LIST **);
 int            read_config_files(void);
+int            read_realms_file(const char *file);
+
+/* nas.c */
+int            read_naslist_file(char *);
+NAS            *nas_find(uint32_t ipno);
+const char     *nas_name(uint32_t ipno);
+const char     *nas_name2(RADIUS_PACKET *r);
+char  *                nas_name3(char *buf, size_t buflen, uint32_t ipno);
+NAS            *nas_findbyname(char *nasname);
 
 /* version.c */
 void           version(void);
@@ -399,7 +361,6 @@ int         log_debug(const char *, ...)
 ;
 void           vp_listdebug(VALUE_PAIR *vp);
 
-
 /* proxy.c */
 int proxy_receive(REQUEST *request);
 int proxy_send(REQUEST *request);
@@ -407,14 +368,14 @@ int proxy_send(REQUEST *request);
 /* auth.c */
 char   *auth_name(char *buf, size_t buflen, REQUEST *request, int do_cli);
 int            rad_authenticate (REQUEST *);
+int            rad_check_password(REQUEST *request);
 int            rad_postauth(REQUEST *);
 
 /* exec.c */
 int            radius_exec_program(const char *,  REQUEST *, int,
                                    char *user_msg, int msg_len,
                                    VALUE_PAIR *input_pairs,
-                                   VALUE_PAIR **output_pairs,
-                                       int shell_escape);
+                                   VALUE_PAIR **output_pairs);
 
 /* timestr.c */
 int            timestr_match(char *, time_t);
@@ -424,15 +385,11 @@ int               paircompare_register(int attr, int otherattr,
                                     RAD_COMPARE_FUNC func,
                                     void *instance);
 void           paircompare_unregister(int attr, RAD_COMPARE_FUNC func);
-int            paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
-                           VALUE_PAIR **reply);
+int            paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
+                       VALUE_PAIR **reply);
+int            simplepaircmp(REQUEST *, VALUE_PAIR *, VALUE_PAIR *);
+void           pair_builtincompare_init(void);
 void           pairxlatmove(REQUEST *, VALUE_PAIR **to, VALUE_PAIR **from);
-int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp);
-int radius_callback_compare(REQUEST *req, VALUE_PAIR *request,
-                           VALUE_PAIR *check, VALUE_PAIR *check_pairs,
-                           VALUE_PAIR **reply_pairs);
-VALUE_PAIR     *radius_paircreate(REQUEST *request, VALUE_PAIR **vps,
-                                 int attribute, int type);
 
 /* xlat.c */
 typedef int (*RADIUS_ESCAPE_STRING)(char *out, int outlen, const char *in);
@@ -442,10 +399,10 @@ int            radius_xlat(char * out, int outlen, const char *fmt,
 typedef int (*RAD_XLAT_FUNC)(void *instance, REQUEST *, char *, char *, size_t, RADIUS_ESCAPE_STRING func);
 int            xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance);
 void           xlat_unregister(const char *module, RAD_XLAT_FUNC func);
-void           xlat_free(void);
+
 
 /* threads.c */
-extern         int thread_pool_init(int spawn_flag);
+extern         int thread_pool_init(void);
 extern         int thread_pool_clean(time_t now);
 extern         int thread_pool_addrequest(REQUEST *, RAD_REQUEST_FUNP);
 extern         pid_t rad_fork(void);
@@ -454,29 +411,14 @@ extern          int total_active_threads(void);
 
 #ifndef HAVE_PTHREAD_H
 #define rad_fork(n) fork()
-#define rad_waitpid(a,b) waitpid(a,b, 0)
+#define rad_waitpid(a,b) waitpid(a,b,0)
 #endif
 
-/* mainconfig.c */
+/* mainconfig.h */
 /* Define a global config structure */
 extern struct main_config_t mainconfig;
 
 int read_mainconfig(int reload);
 int free_mainconfig(void);
-
-/* listen.c */
-void listen_free(rad_listen_t **head);
-int listen_init(const char *filename, rad_listen_t **head);
-rad_listen_t *proxy_new_listener(void);
-
-/* event.c */
-int radius_event_init(int spawn_flag);
-void radius_event_free(void);
-int radius_event_process(struct timeval **pptv);
-void radius_handle_request(REQUEST *request, RAD_REQUEST_FUNP fun);
-int received_request(rad_listen_t *listener,
-                    RADIUS_PACKET *packet, REQUEST **prequest,
-                    RADCLIENT *client);
-REQUEST *received_proxy_response(RADIUS_PACKET *packet);
-
+CONF_SECTION *read_radius_conf_file(void); /* for radwho and friends. */
 #endif /*RADIUSD_H*/
diff --git a/src/include/radsniff.h b/src/include/radsniff.h
deleted file mode 100644 (file)
index 22adaa0..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *  radsniff.h Structures and defines for the RADIUS sniffer.
- *
- *  Version:    $Id$
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *  Copyright 2006  The FreeRADIUS server project
- *  Copyright 2006  Nicolas Baradakis <nicolas.baradakis@cegetel.net>
- */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(radsniff_h, "$Id$")
-
-#include <sys/types.h>
-#include <netinet/in.h>
-
-/*
- *     The number of bytes in an ethernet (MAC) address.
- */
-#define ETHER_ADDR_LEN         6
-
-/*
- *     Structure of a DEC/Intel/Xerox or 802.3 Ethernet header.
- */
-struct  ethernet_header {
-        u_int8_t       ethernet_dhost[ETHER_ADDR_LEN];
-        u_int8_t       ethernet_shost[ETHER_ADDR_LEN];
-        u_int16_t      ethernet_type;
-};
-
-/*
- *     Length of a DEC/Intel/Xerox or 802.3 Ethernet header.
- *     Note that some compilers may pad "struct ether_header" to
- *     a multiple of 4 *bytes, for example, so "sizeof (struct
- *     ether_header)" may not give the right answer.
- */
-#define ETHER_HDRLEN           14
-
-/*
- *     Structure of an internet header, naked of options.
- */
-struct ip_header {
-        u_int8_t        ip_vhl;         /* header length, version */
-#define IP_V(ip)        (((ip)->ip_vhl & 0xf0) >> 4)
-#define IP_HL(ip)       ((ip)->ip_vhl & 0x0f)
-        u_int8_t        ip_tos;         /* type of service */
-        u_int16_t       ip_len;         /* total length */
-        u_int16_t       ip_id;          /* identification */
-        u_int16_t       ip_off;         /* fragment offset field */
-#define IP_DF 0x4000                    /* dont fragment flag */
-#define IP_MF 0x2000                    /* more fragments flag */
-#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
-        u_int8_t        ip_ttl;         /* time to live */
-        u_int8_t        ip_p;           /* protocol */
-        u_int16_t       ip_sum;         /* checksum */
-        struct in_addr  ip_src,ip_dst;  /* source and dest address */
-};
-
-/*
- *     UDP protocol header.
- *     Per RFC 768, September, 1981.
- */
-struct udp_header {
-        u_int16_t       udp_sport;               /* source port */
-        u_int16_t       udp_dport;               /* destination port */
-        u_int16_t       udp_ulen;                /* udp length */
-        u_int16_t       udp_sum;                 /* udp checksum */
-};
-
-/*
- *     RADIUS packet length.
- *     RFC 2865, Section 3., subsection 'length' says:
- *     " ... and maximum length is 4096."
- */
-#define MAX_RADIUS_LEN 4096
-#define MIN_RADIUS_LEN 20
-#define SNAPLEN (sizeof(struct ethernet_header) + sizeof(struct ip_header) + sizeof(struct udp_header) + MAX_RADIUS_LEN)
-
-typedef struct radius_packet_t {
-       uint8_t       code;
-       uint8_t       id;
-       uint8_t       length[2];
-       uint8_t       vector[AUTH_VECTOR_LEN];
-       uint8_t       data[1];
-} radius_packet_t;
-
-#define AUTH_HDR_LEN 20
index 997c9ea..3b9c015 100644 (file)
@@ -7,9 +7,6 @@
 #ifndef _RADUTMP_H
 #define _RADUTMP_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(radutmp_h, "$Id$")
-
 /*
  *      Types of connection.
  */
diff --git a/src/include/realms.h b/src/include/realms.h
deleted file mode 100644 (file)
index 9a11eb9..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef REALMS_H
-#define REALMS_H
-
-/*
- * realms.h    Structures, prototypes and global variables
- *             for realms
- *
- * Version:    $Id$
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSIDH(realms_h, "$Id$")
-
-#define HOME_TYPE_AUTH (1)
-#define HOME_TYPE_ACCT (2)
-
-#define HOME_PING_CHECK_NONE           (0)
-#define HOME_PING_CHECK_STATUS_SERVER  (1)
-#define HOME_PING_CHECK_REQUEST                (2)
-
-#define HOME_STATE_ALIVE               (0)
-#define HOME_STATE_ZOMBIE              (1)
-#define HOME_STATE_IS_DEAD             (2)
-
-typedef struct home_server {
-       const char      *name;
-
-       const char      *hostname;
-
-       lrad_ipaddr_t   ipaddr;
-
-
-       int             port;
-       int             type;           /* auth/acct */
-
-       /*
-        *      Maybe also have list of source IP/ports, && socket?
-        */
-
-       const char      *secret;
-
-       lrad_event_t    *ev;
-       struct timeval  when;
-
-       int             response_window;
-       int             max_outstanding; /* don't overload it */
-       int             currently_outstanding;
-
-       struct timeval  zombie_period_start;
-       int             zombie_period; /* unresponsive for T, mark it dead */
-
-       int             state;
-
-       int             ping_check;
-       const char      *ping_user_name;
-       const char      *ping_user_password;
-
-       int             ping_interval;
-       int             num_pings_to_alive;
-       int             num_received_pings;
-       int             ping_timeout;
-
-       int             revive_interval; /* if it doesn't support pings */
-} home_server;
-
-
-typedef enum home_pool_type_t {
-       HOME_POOL_INVALID = 0,
-       HOME_POOL_LOAD_BALANCE,
-       HOME_POOL_FAIL_OVER,
-       HOME_POOL_CLIENT_BALANCE,
-       HOME_POOL_CLIENT_PORT_BALANCE
-} home_pool_type_t;
-
-
-typedef struct home_pool_t {
-       const char              *name;
-       home_pool_type_t        type;
-
-       int                     server_type;
-
-       int                     num_home_servers;
-       home_server             *servers[1];
-} home_pool_t;
-
-
-typedef struct _realm {
-       const char              *name;
-
-       int                     striprealm;
-
-       home_pool_t             *auth_pool;
-       home_pool_t             *acct_pool;
-} REALM;
-
-int realms_init(const char *filename);
-void realms_free(void);
-int realm_add(const char *filename, CONF_SECTION *cs);
-REALM *realm_find(const char *name);
-
-home_server *home_server_ldb(const char *realmname, home_pool_t *pool, REQUEST *request);
-home_server *home_server_find(lrad_ipaddr_t *ipaddr, int port);
-
-#endif /* REALMS_H */
diff --git a/src/include/request_list.h b/src/include/request_list.h
new file mode 100644 (file)
index 0000000..c639867
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _REQUEST_LIST_H
+#define _REQUEST_LIST_H
+/*
+ * request_list.h      Hide the handling of the REQUEST list from
+ *                     the main server.
+ *
+ * Version:    $Id$
+ *
+ */
+
+extern int rl_init(void);
+extern void rl_delete(REQUEST *request);
+extern void rl_add(REQUEST *request);
+extern REQUEST *rl_find(RADIUS_PACKET *packet);
+extern int rl_add_proxy(REQUEST *request);
+extern REQUEST *rl_find_proxy(RADIUS_PACKET *packet);
+extern REQUEST *rl_next(REQUEST *request);
+extern int rl_num_requests(void);
+
+#define RL_WALK_CONTINUE (0)
+#define RL_WALK_STOP     (-1)
+
+typedef int (*RL_WALK_FUNC)(REQUEST *, void *);
+
+extern int rl_walk(RL_WALK_FUNC walker, void *data);
+extern struct timeval *rl_clean_list(time_t now);
+
+#endif /* _REQUEST_LIST_H */
index 1248962..0b29e9f 100644 (file)
@@ -2,27 +2,15 @@
  * Copyright (C) 2000 Jochen Friedrich <jochen@scram.de>
  * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ * along with GNU Zebra; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
  */
 
 #ifndef _SMUX_H
 #define _SMUX_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(smux_h, "$Id$")
-
 #ifdef HAVE_ASN1_SNMP_SNMPIMPL_H
 #include <asn1.h>
 #include <snmp.h>
@@ -59,7 +47,7 @@ RCSIDH(smux_h, "$Id$")
 
 struct variable;
 
-#define SMUX_REGISTER_MIB(descr, var, vartype, theoid)         \
+#define REGISTER_MIB(descr, var, vartype, theoid)              \
     smux_register_mib(descr, (struct variable *)var, sizeof(struct vartype), \
     sizeof(var)/sizeof(struct vartype),                        \
     theoid, sizeof(theoid)/sizeof(oid))
index f56e5d6..8243714 100644 (file)
@@ -7,9 +7,6 @@
 #ifndef SYSUTMP_H_INCLUDED
 #define SYSUTMP_H_INCLUDED
 
-#include <freeradius-devel/ident.h>
-RCSIDH(sysutmp_h, "$Id$")
-
 /*
  *  If we have BOTH utmp.h and utmpx.h, then
  *  we prefer to use utmp.h, but only on systems other than Solaris.
index 1c77147..1cda314 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(token_h, "$Id$")
-
 typedef enum lrad_token_t {
-  T_OP_INVALID = 0,            /* invalid token */
+  T_INVALID = 0,               /* invalid token */
   T_EOL,                       /* end of line */
   T_LCBRACE,                   /* { */
   T_RCBRACE,                   /* } */
   T_LBRACE,                    /* ( */
-  T_RBRACE,                    /* )             5 */
+  T_RBRACE,                    /* ) */
   T_COMMA,                     /* , */
   T_SEMICOLON,                 /* ; */
 
   T_OP_ADD,                    /* += */
   T_OP_SUB,                    /* -= */
-  T_OP_SET,                    /* :=           10 */
+  T_OP_SET,                    /* := */
   T_OP_EQ,                     /* = */
   T_OP_NE,                     /* != */
   T_OP_GE,                     /* >= */
   T_OP_GT,                     /* > */
-  T_OP_LE,                     /* <=           15 */
+  T_OP_LE,                     /* <= */
   T_OP_LT,                     /* < */
   T_OP_REG_EQ,                 /* =~ */
   T_OP_REG_NE,                 /* !~ */
   T_OP_CMP_TRUE,                /* =* */
-  T_OP_CMP_FALSE,               /* !*          20 */
+  T_OP_CMP_FALSE,               /* !* */
   T_OP_CMP_EQ,                 /* == */
   T_HASH,                      /* # */
   T_BARE_WORD,                 /* bare word */
   T_DOUBLE_QUOTED_STRING,      /* "foo" */
-  T_SINGLE_QUOTED_STRING,      /* 'foo'        25 */
+  T_SINGLE_QUOTED_STRING,      /* 'foo' */
   T_BACK_QUOTED_STRING,                /* `foo` */
   T_TOKEN_LAST
 } LRAD_TOKEN;
index 1c37048..a95e055 100644 (file)
@@ -5,13 +5,8 @@
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(udpfromtoh, "$Id$")
+#include <sys/socket.h>
 
-#include <freeradius-devel/autoconf.h>
-#include <freeradius-devel/libradius.h>
-
-#ifdef WITH_UDPFROMTO
 int udpfromto_init(int s);
 int recvfromto(int s, void *buf, size_t len, int flags,
               struct sockaddr *from, socklen_t *fromlen,
@@ -19,6 +14,5 @@ int recvfromto(int s, void *buf, size_t len, int flags,
 int sendfromto(int s, void *buf, size_t len, int flags,
               struct sockaddr *from, socklen_t fromlen,
               struct sockaddr *to, socklen_t tolen);
-#endif
 
 #endif
diff --git a/src/lib/LICENSE b/src/lib/LICENSE
deleted file mode 100644 (file)
index 8add30a..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-                 GNU LESSER GENERAL PUBLIC LICENSE
-                      Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
-                 GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-\f
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                           NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
index 4bdf974..7339fdf 100644 (file)
@@ -6,18 +6,17 @@
 
 include ../../Make.inc
 
-SRCS           = dict.c filters.c hash.c hmac.c hmacsha1.c isaac.c log.c \
-                 misc.c missing.c md4.c md5.c print.c radius.c rbtree.c \
-                 sha1.c snprintf.c strlcat.c strlcpy.c token.c udpfromto.c \
-                 valuepair.c fifo.c packet.c event.c getaddrinfo.c
+SRCS           = crypt.c dict.c filters.c hash.c hmac.c hmacsha1.c \
+                 isaac.c log.c misc.c missing.c md4.c md5.c print.c \
+                 radius.c rbtree.c sha1.c snprintf.c token.c udpfromto.c \
+                 valuepair.c
 
 LT_OBJS                = $(SRCS:.c=.lo)
 
 INCLUDES       = ../include/radius.h ../include/libradius.h \
-                 ../include/missing.h ../include/autoconf.h \
-                 ../include/ident.h
+                 ../include/missing.h ../include/autoconf.h
 
-CFLAGS         += -D_LIBRADIUS -I$(top_builddir)/src
+CFLAGS         += -D_LIBRADIUS -I../include
 
 # if you have problems with things that need SHA1-HMAC, this will
 # dump the key and the input to the hash so you can compare to what
@@ -40,7 +39,7 @@ all: $(TARGET).la
 
 $(TARGET).la: $(LT_OBJS)
        $(LIBTOOL) --mode=link $(CC) -release $(RADIUSD_VERSION) \
-       $(LDFLAGS) $(LINK_MODE) -o $@ -rpath $(libdir) $^
+       $(LDFLAGS) $(LINK_MODE) -o $@ -rpath $(libdir) $^ $(LCRYPT)
 
 $(LT_OBJS): $(INCLUDES)
 
diff --git a/src/lib/README b/src/lib/README
deleted file mode 100644 (file)
index 1c1da3a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-  The files in this directory are placed under the LGPL, as given
-in the LICENSE file in this directory.
similarity index 65%
rename from src/main/crypt.c
rename to src/lib/crypt.c
index 38c6a08..5334841 100644 (file)
@@ -1,30 +1,30 @@
 /*
  * crypt.c     A thread-safe crypt wrapper
  *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2.1 of the License, or (at your option) any later version.
  *
- *   This program is distributed in the hope that it will be useful,
+ *   This library is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *   Lesser General Public License for more details.
  *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000-2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
+#include "autoconf.h"
+#include <string.h>
 
 #ifdef HAVE_CRYPT_H
 #include <crypt.h>
+#else
+#include <unistd.h>
 #endif
 
 #ifdef HAVE_PTHREAD_H
@@ -37,6 +37,7 @@ static int lrad_crypt_init = 0;
 static pthread_mutex_t lrad_crypt_mutex;
 #endif
 
+#include "libradius.h"
 
 /*
  * performs a crypt password check in an thread-safe way.
index 62d06d4..b964099 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/libradius.h>
+#include       "autoconf.h"
 
+#include       <stdlib.h>
 #include       <ctype.h>
+#include       <string.h>
 
 #ifdef HAVE_MALLOC_H
 #include       <malloc.h>
@@ -35,6 +36,11 @@ RCSID("$Id$")
 #include       <sys/stat.h>
 #endif
 
+#include       <unistd.h>
+
+#include       "missing.h"
+#include       "libradius.h"
+
 #define DICT_VALUE_MAX_NAME_LEN (128)
 #define DICT_VENDOR_MAX_NAME_LEN (128)
 
@@ -47,8 +53,6 @@ static lrad_hash_table_t *attributes_byvalue = NULL;
 static lrad_hash_table_t *values_byvalue = NULL;
 static lrad_hash_table_t *values_byname = NULL;
 
-static DICT_ATTR *dict_base_attrs[256];
-
 /*
  *     For faster HUP's, we cache the stat information for
  *     files we've $INCLUDEd
@@ -87,8 +91,6 @@ static const LRAD_NAME_NUMBER type_table[] = {
        { "ifid",       PW_TYPE_IFID },
        { "ipv6addr",   PW_TYPE_IPV6ADDR },
        { "ipv6prefix", PW_TYPE_IPV6PREFIX },
-       { "byte",       PW_TYPE_BYTE },
-       { "short",      PW_TYPE_SHORT },
        { NULL, 0 }
 };
 
@@ -113,7 +115,7 @@ static uint32_t dict_hashname(const char *name)
                hash *= FNV_MAGIC_PRIME;
                hash ^= (uint32_t ) (c & 0xff);
        }
-
+       
        return hash;
 }
 
@@ -136,11 +138,8 @@ static int dict_attr_name_cmp(const void *one, const void *two)
 
 static uint32_t dict_attr_value_hash(const void *data)
 {
-       uint32_t hash;
-       const DICT_ATTR *attr = data;
-
-       hash = lrad_hash(&attr->vendor, sizeof(attr->vendor));
-       return lrad_hash_update(&attr->attr, sizeof(attr->attr), hash);
+       return lrad_hash(&((const DICT_ATTR *)data)->attr,
+                        sizeof(((const DICT_ATTR *)data)->attr));
 }
 
 static int dict_attr_value_cmp(const void *one, const void *two)
@@ -148,9 +147,6 @@ static int dict_attr_value_cmp(const void *one, const void *two)
        const DICT_ATTR *a = one;
        const DICT_ATTR *b = two;
 
-       if (a->vendor < b->vendor) return -1;
-       if (a->vendor > b->vendor) return +1;
-
        return a->attr - b->attr;
 }
 
@@ -324,8 +320,6 @@ void dict_free(void)
        values_byname = NULL;
        values_byvalue = NULL;
 
-       memset(dict_base_attrs, 0, sizeof(dict_base_attrs));
-
        dict_stat_free();
 }
 
@@ -338,7 +332,7 @@ int dict_addvendor(const char *name, int value)
        size_t length;
        DICT_VENDOR *dv;
 
-       if (value >= 32767) {
+       if (value >= (1 << 16)) {
                librad_log("dict_addvendor: Cannot handle vendor ID larger than 65535");
                return -1;
        }
@@ -347,7 +341,7 @@ int dict_addvendor(const char *name, int value)
                librad_log("dict_addvendor: vendor name too long");
                return -1;
        }
-
+       
        if ((dv = malloc(sizeof(*dv) + length)) == NULL) {
                librad_log("dict_addvendor: out of memory");
                return -1;
@@ -453,8 +447,9 @@ int dict_addattr(const char *name, int vendor, int type, int value,
                }
 
                /*
-                *      FIXME: Switch over dv->type, and limit things
-                *      properly.
+                *      With a few exceptions, attributes can only be
+                *      1..255.  The check above catches the less than
+                *      zero case.
                 */
                if ((dv->type == 1) && (value >= 256)) {
                        librad_log("dict_addattr: ATTRIBUTE has invalid number (larger than 255).");
@@ -473,7 +468,6 @@ int dict_addattr(const char *name, int vendor, int type, int value,
        strcpy(attr->name, name);
        attr->attr = value;
        attr->attr |= (vendor << 16); /* FIXME: hack */
-       attr->vendor = vendor;
        attr->type = type;
        attr->flags = flags;
        attr->vendor = vendor;
@@ -504,7 +498,6 @@ int dict_addattr(const char *name, int vendor, int type, int value,
                         */
                }
 
-
                lrad_hash_table_delete(attributes_byvalue, a);
 
                if (!lrad_hash_table_replace(attributes_byname, attr)) {
@@ -528,10 +521,6 @@ int dict_addattr(const char *name, int vendor, int type, int value,
                return -1;
        }
 
-       if (!vendor && (value > 0) && (value < 256)) {
-                dict_base_attrs[value] = attr;
-       }
-
        return 0;
 }
 
@@ -545,11 +534,6 @@ int dict_addvalue(const char *namestr, const char *attrstr, int value)
        DICT_ATTR       *dattr;
        DICT_VALUE      *dval;
 
-       if (!*namestr) {
-               librad_log("dict_addvalue: empty names are not permitted");
-               return -1;
-       }
-
        if ((length = strlen(namestr)) >= DICT_VALUE_MAX_NAME_LEN) {
                librad_log("dict_addvalue: value name too long");
                return -1;
@@ -570,54 +554,22 @@ int dict_addvalue(const char *namestr, const char *attrstr, int value)
         */
        dattr = dict_attrbyname(attrstr);
        if (dattr) {
-               if (dattr->flags.has_value_alias) {
-                       librad_log("dict_addvalue: Cannot add VALUE for ATTRIBUTE \"%s\": It already has a VALUE-ALIAS", attrstr);
-                       return -1;
-               }
-
                dval->attr = dattr->attr;
 
                /*
-                *      Enforce valid values
-                *
-                *      Don't worry about fixups...
+                *      Octets is allowed as a work-around for the
+                *      fact that branch_1_1 doesn't have BYTE or SHORT
                 */
-               switch (dattr->type) {
-                       case PW_TYPE_BYTE:
-                               if (value > 255) {
-                                       free(dval);
-                                       librad_log("dict_addvalue: ATTRIBUTEs of type 'byte' cannot have VALUEs larger than 255");
-                                       return -1;
-                               }
-                               break;
-                       case PW_TYPE_SHORT:
-                               if (value > 65535) {
-                                       free(dval);
-                                       librad_log("dict_addvalue: ATTRIBUTEs of type 'short' cannot have VALUEs larger than 65535");
-                                       return -1;
-                               }
-                               break;
-
-                               /*
-                                *      Allow octets for now, because
-                                *      of dictionary.cablelabs
-                                */
-                       case PW_TYPE_OCTETS:
-
-                       case PW_TYPE_INTEGER:
-                               break;
-
-                       default:
-                               free(dval);
-                               librad_log("dict_addvalue: VALUEs cannot be defined for attributes of type '%s'",
-                                          lrad_int2str(type_table, dattr->type, "?Unknown?"));
-                               return -1;
+               if ((dattr->type != PW_TYPE_INTEGER) &&
+                   (dattr->type != PW_TYPE_OCTETS)) {
+                       free(dval);
+                       librad_log("dict_addvalue: VALUEs can only be defined for'integer' types");
+                       return -1;
                }
 
-               dattr->flags.has_value = 1;
        } else {
                value_fixup_t *fixup;
-
+               
                fixup = (value_fixup_t *) malloc(sizeof(*fixup));
                if (!fixup) {
                        free(dval);
@@ -626,9 +578,9 @@ int dict_addvalue(const char *namestr, const char *attrstr, int value)
                }
                memset(fixup, 0, sizeof(*fixup));
 
-               strlcpy(fixup->attrstr, attrstr, sizeof(fixup->attrstr));
+               strNcpy(fixup->attrstr, attrstr, sizeof(fixup->attrstr));
                fixup->dval = dval;
-
+               
                /*
                 *      Insert to the head of the list.
                 */
@@ -644,7 +596,7 @@ int dict_addvalue(const char *namestr, const char *attrstr, int value)
        if (!lrad_hash_table_insert(values_byname, dval)) {
                if (dattr) {
                        DICT_VALUE *old;
-
+                       
                        /*
                         *      Suppress duplicates with the same
                         *      name and value.  There are lots in
@@ -719,9 +671,6 @@ static int process_attribute(const char* fn, const int line,
         */
        memset(&flags, 0, sizeof(flags));
        if (argc == 4) {
-               /*
-                *      FIXME: replace strtok with str2argv
-                */
                s = strtok(argv[3], ",");
                while (s) {
                        if (strcmp(s, "has_tag") == 0 ||
@@ -729,7 +678,7 @@ static int process_attribute(const char* fn, const int line,
                                /* Boolean flag, means this is a
                                   tagged attribute */
                                flags.has_tag = 1;
-
+                               
                        } else if (strncmp(s, "encrypt=", 8) == 0) {
                                /* Encryption method, defaults to 0 (none).
                                   Currently valid is just type 2,
@@ -741,39 +690,16 @@ static int process_attribute(const char* fn, const int line,
                                                    fn, line, s);
                                        return -1;
                                }
-
-                       } else if (strncmp(s, "array", 8) == 0) {
-                               flags.array = 1;
-
-                               switch (type) {
-                                       case PW_TYPE_IPADDR:
-                                       case PW_TYPE_BYTE:
-                                       case PW_TYPE_SHORT:
-                                       case PW_TYPE_INTEGER:
-                                       case PW_TYPE_DATE:
-                                               break;
-
-                                       default:
-                                               librad_log( "dict_init: %s[%d] Only IP addresses can have the \"array\" flag set.",
-                                                           fn, line);
-                                               return -1;
-                               }
-
-                       } else if (block_vendor) {
-                               librad_log( "dict_init: %s[%d]: unknown option \"%s\"",
-                                           fn, line, s);
-                               return -1;
-
                        } else {
                                /* Must be a vendor 'flag'... */
                                if (strncmp(s, "vendor=", 7) == 0) {
                                        /* New format */
                                        s += 7;
                                }
-
+                               
                                vendor = dict_vendorbyname(s);
                                if (!vendor) {
-                                       librad_log( "dict_init: %s[%d]: unknown vendor \"%s\"",
+                                       librad_log( "dict_init: %s[%d]: unknown vendor %s",
                                                    fn, line, s);
                                        return -1;
                                }
@@ -808,7 +734,7 @@ static int process_attribute(const char* fn, const int line,
                                   fn, line,
                                   lrad_int2str(type_table, type, "?Unknown?"));
                        return -1;
-
+                       
                }
        }
 
@@ -865,89 +791,6 @@ static int process_value(const char* fn, const int line, char **argv,
 
 
 /*
- *     Process the VALUE-ALIAS command
- *
- *     This allows VALUE mappings to be shared among multiple
- *     attributes.
- */
-static int process_value_alias(const char* fn, const int line, char **argv,
-                              int argc)
-{
-       DICT_ATTR *my_da, *da;
-       DICT_VALUE *dval;
-
-       if (argc != 2) {
-               librad_log("dict_init: %s[%d]: invalid VALUE-ALIAS line",
-                       fn, line);
-               return -1;
-       }
-
-       my_da = dict_attrbyname(argv[0]);
-       if (!my_da) {
-               librad_log("dict_init: %s[%d]: ATTRIBUTE \"%s\" does not exist",
-                          fn, line, argv[1]);
-               return -1;
-       }
-
-       if (my_da->flags.has_value) {
-               librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" with pre-existing VALUE",
-                          fn, line, argv[0]);
-               return -1;
-       }
-
-       if (my_da->flags.has_value_alias) {
-               librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" with pre-existing VALUE-ALIAS",
-                          fn, line, argv[0]);
-               return -1;
-       }
-
-       da = dict_attrbyname(argv[1]);
-       if (!da) {
-               librad_log("dict_init: %s[%d]: Cannot find ATTRIBUTE \"%s\" for alias",
-                          fn, line, argv[1]);
-               return -1;
-       }
-
-       if (!da->flags.has_value) {
-               librad_log("dict_init: %s[%d]: VALUE-ALIAS cannot refer to ATTRIBUTE %s: It has no values",
-                          fn, line, argv[1]);
-               return -1;
-       }
-
-       if (da->flags.has_value_alias) {
-               librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" which itself has a VALUE-ALIAS",
-                          fn, line, argv[1]);
-               return -1;
-       }
-
-       if (my_da->type != da->type) {
-               librad_log("dict_init: %s[%d]: Cannot add VALUE-ALIAS between attributes of differing type",
-                          fn, line);
-               return -1;
-       }
-
-       if ((dval = malloc(sizeof(*dval))) == NULL) {
-               librad_log("dict_addvalue: out of memory");
-               return -1;
-       }
-       memset(dval, 0, sizeof(*dval));
-
-       dval->name[0] = '\0';   /* empty name */
-       dval->attr = my_da->attr;
-       dval->value = da->attr;
-
-       if (!lrad_hash_table_insert(values_byname, dval)) {
-               librad_log("dict_init: %s[%d]: Error create alias",
-                          fn, line);
-               free(dval);
-               return -1;
-       }
-
-       return 0;
-}
-
-
-/*
  *     Process the VENDOR command
  */
 static int process_vendor(const char* fn, const int line, char **argv,
@@ -1008,7 +851,7 @@ static int process_vendor(const char* fn, const int line, char **argv,
                }
 
                p = format + 7;
-               if ((strlen(p) != 3) ||
+               if ((strlen(p) != 3) || 
                    !isdigit((int) p[0]) ||
                    (p[1] != ',') ||
                    !isdigit((int) p[2])) {
@@ -1104,8 +947,13 @@ static int my_dict_init(const char *dir, const char *fn,
        char    *argv[MAX_ARGV];
        int     argc;
 
-       if (strlen(fn) >= sizeof(dirtmp) / 2 ||
-           strlen(dir) >= sizeof(dirtmp) / 2) {
+       if (!dir) {
+               librad_log("dict_init: No directory specified");
+               return -1;
+       }
+
+       if ((strlen(fn) >= sizeof(dirtmp) / 2) ||
+           (strlen(dir) >= sizeof(dirtmp) / 2)) {
                librad_log("dict_init: filename name too long");
                return -1;
        }
@@ -1118,7 +966,8 @@ static int my_dict_init(const char *dir, const char *fn,
                strcpy(dirtmp, fn);
                dirtmp[p - fn] = 0;
                dir = dirtmp;
-       } else if (dir && dir[0] && strcmp(dir, ".") != 0) {
+
+       } else if (dir[0] && strcmp(dir, ".") != 0) {
                snprintf(dirtmp, sizeof(dirtmp), "%s/%s", dir, fn);
                fn = dirtmp;
        }
@@ -1139,21 +988,19 @@ static int my_dict_init(const char *dir, const char *fn,
                fclose(fp);
                librad_log("dict_init: Dictionary \"%s\" is not a regular file",
                           fn);
-               return -1;
+               return -1;        
        }
 
        /*
         *      Globally writable dictionaries means that users can control
         *      the server configuration with little difficulty.
         */
-#ifdef S_IWOTH
        if ((statbuf.st_mode & S_IWOTH) != 0) {
                fclose(fp);
                librad_log("dict_init: Dictionary \"%s\" is globally writable.  Refusing to start due to insecure configuration.",
                           fn);
                return -1;
        }
-#endif
 
        dict_stat_add(fn, &statbuf);
 
@@ -1231,15 +1078,6 @@ static int my_dict_init(const char *dir, const char *fn,
                        continue;
                }
 
-               if (strcasecmp(argv[0], "VALUE-ALIAS") == 0) {
-                       if (process_value_alias(fn, line,
-                                               argv + 1, argc - 1) == -1) {
-                               fclose(fp);
-                               return -1;
-                       }
-                       continue;
-               }
-
                /*
                 *      Process VENDOR lines.
                 */
@@ -1334,6 +1172,8 @@ static int null_callback(void *ctx, void *data)
  */
 int dict_init(const char *dir, const char *fn)
 {
+       if (!dir) return -1;
+
        /*
         *      Check if we need to change anything.  If not, don't do
         *      anything.
@@ -1443,7 +1283,7 @@ int dict_init(const char *dir, const char *fn)
                                librad_log("dict_addvalue: Duplicate value name %s for attribute %s", this->dval->name, a->name);
                                return -1;
                        }
-
+                       
                        /*
                         *      Allow them to use the old name, but
                         *      prefer the new name when printing
@@ -1473,7 +1313,7 @@ int dict_init(const char *dir, const char *fn)
 
        lrad_hash_table_walk(attributes_byname, null_callback, NULL);
        lrad_hash_table_walk(attributes_byvalue, null_callback, NULL);
-
+       
        lrad_hash_table_walk(values_byvalue, null_callback, NULL);
        lrad_hash_table_walk(values_byname, null_callback, NULL);
 
@@ -1487,10 +1327,7 @@ DICT_ATTR *dict_attrbyvalue(int attr)
 {
        DICT_ATTR dattr;
 
-       if ((attr > 0) && (attr < 256)) return dict_base_attrs[attr];
-
        dattr.attr = attr;
-       dattr.vendor = VENDOR(attr) & 0x7fff;
 
        return lrad_hash_table_finddata(attributes_byvalue, &dattr);
 }
@@ -1504,7 +1341,7 @@ DICT_ATTR *dict_attrbyname(const char *name)
 
        if (!name) return NULL;
 
-       strlcpy(dattr.name, name, sizeof(dattr.name));
+       strNcpy(dattr.name, name, sizeof(dattr.name));
 
        return lrad_hash_table_finddata(attributes_byname, &dattr);
 }
@@ -1514,23 +1351,11 @@ DICT_ATTR *dict_attrbyname(const char *name)
  */
 DICT_VALUE *dict_valbyattr(int attr, int value)
 {
-       DICT_VALUE dval, *dv;
+       DICT_VALUE dval;
 
-       /*
-        *      First, look up aliases.
-        */
        dval.attr = attr;
-       dval.name[0] = '\0';
-
-       /*
-        *      Look up the attribute alias target, and use
-        *      the correct attribute number if found.
-        */
-       dv = lrad_hash_table_finddata(values_byname, &dval);
-       if (dv) dval.attr = dv->value;
-
        dval.value = value;
-
+       
        return lrad_hash_table_finddata(values_byvalue, &dval);
 }
 
@@ -1539,25 +1364,16 @@ DICT_VALUE *dict_valbyattr(int attr, int value)
  */
 DICT_VALUE *dict_valbyname(int attr, const char *name)
 {
-       DICT_VALUE *my_dv, *dv;
-       uint32_t buffer[(sizeof(*my_dv) + DICT_VALUE_MAX_NAME_LEN + 3)/4];
+       DICT_VALUE *dv;
+       uint32_t buffer[(sizeof(*dv) + DICT_VALUE_MAX_NAME_LEN + 3)/4];
 
        if (!name) return NULL;
 
-       my_dv = (DICT_VALUE *) buffer;
-       my_dv->attr = attr;
-       my_dv->name[0] = '\0';
+       dv = (DICT_VALUE *) buffer;
+       dv->attr = attr;
+       strNcpy(dv->name, name, DICT_VALUE_MAX_NAME_LEN);
 
-       /*
-        *      Look up the attribute alias target, and use
-        *      the correct attribute number if found.
-        */
-       dv = lrad_hash_table_finddata(values_byname, my_dv);
-       if (dv) my_dv->attr = dv->value;
-
-       strlcpy(my_dv->name, name, DICT_VALUE_MAX_NAME_LEN);
-
-       return lrad_hash_table_finddata(values_byname, my_dv);
+       return lrad_hash_table_finddata(values_byname, dv);
 }
 
 /*
@@ -1573,8 +1389,8 @@ int dict_vendorbyname(const char *name)
        if (!name) return 0;
 
        dv = (DICT_VENDOR *) buffer;
-       strlcpy(dv->name, name, DICT_VENDOR_MAX_NAME_LEN);
-
+       strNcpy(dv->name, name, DICT_VENDOR_MAX_NAME_LEN);
+       
        dv = lrad_hash_table_finddata(vendors_byname, dv);
        if (!dv) return 0;
 
diff --git a/src/lib/event.c b/src/lib/event.c
deleted file mode 100644 (file)
index 9690bd8..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * event.c     Non-thread-safe event handling, specific to a RADIUS
- *             server.
- *
- * Version:    $Id$
- *
- *   This library is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU Lesser General Public
- *   License as published by the Free Software Foundation; either
- *   version 2.1 of the License, or (at your option) any later version.
- *
- *   This library is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *   Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public
- *   License along with this library; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *  Copyright 2007  The FreeRADIUS server project
- *  Copyright 2007  Alan DeKok <aland@ox.org>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/event.h>
-
-typedef struct lrad_event_fd_t {
-       int                     fd;
-       int                     priority;
-       lrad_event_callback_t   callback;
-       void                    *ctx;
-       struct lrad_event_fd_t  *next;
-} lrad_event_fd_t;
-
-struct lrad_event_list_t {
-       rbtree_t        *times;
-
-       lrad_event_fd_t *fds;
-       int             maxfd;
-       fd_set          readfds;
-
-       int             exit;
-
-       struct timeval  now;
-       int             dispatch;
-};
-
-/*
- *     Internal structure for managing events.
- */
-struct lrad_event_t {
-       lrad_event_callback_t   callback;
-       void                    *ctx;
-       struct timeval          when;
-       lrad_event_t            **ev_p;
-       rbnode_t                *node;
-};
-
-
-static int lrad_event_list_time_cmp(const void *one, const void *two)
-{
-       const lrad_event_t *a = one;
-       const lrad_event_t *b = two;
-
-       if (a->when.tv_sec < b->when.tv_sec) return -1;
-       if (a->when.tv_sec > b->when.tv_sec) return +1;
-
-       if (a->when.tv_usec < b->when.tv_usec) return -1;
-       if (a->when.tv_usec > b->when.tv_usec) return +1;
-
-       return 0;
-}
-
-
-void lrad_event_list_free(lrad_event_list_t *el)
-{
-       if (!el) return;
-
-       rbtree_free(el->times);
-       free(el);
-}
-
-
-lrad_event_list_t *lrad_event_list_create(void)
-{
-       lrad_event_list_t *el;
-
-       el = malloc(sizeof(*el));
-       if (!el) return NULL;
-       memset(el, 0, sizeof(*el));
-
-       el->times = rbtree_create(lrad_event_list_time_cmp,
-                                 free, 0);
-       if (!el->times) {
-               lrad_event_list_free(el);
-               return NULL;
-       }
-
-       return el;
-}
-
-int lrad_event_list_num_elements(lrad_event_list_t *el)
-{
-       if (!el) return 0;
-
-       return rbtree_num_elements(el->times);
-}
-
-
-int lrad_event_delete(lrad_event_list_t *el, lrad_event_t **ev_p)
-{
-       lrad_event_t *ev;
-
-       if (!el || !ev_p || !*ev_p) return 0;
-
-       ev = *ev_p;
-       *(ev->ev_p) = NULL;
-
-       rbtree_delete(el->times, ev->node);
-
-       return 1;
-}
-
-
-int lrad_event_insert(lrad_event_list_t *el,
-                     lrad_event_callback_t callback,
-                     void *ctx, struct timeval *when,
-                     lrad_event_t **ev_p)
-{
-       lrad_event_t *ev;
-
-       if (!el || !callback | !when || !ev_p) return 0;
-
-       if (*ev_p) lrad_event_delete(el, ev_p);
-
-       ev = malloc(sizeof(*ev));
-       if (!ev) return 0;
-       memset(ev, 0, sizeof(*ev));
-
-       ev->callback = callback;
-       ev->ctx = ctx;
-       ev->when = *when;
-       ev->ev_p = ev_p;
-
-       /*
-        *      There's a tiny chance that two events will be
-        *      scheduled at the same time.  If this happens, we
-        *      increase the usec counter by 1, in order to avoid the
-        *      duplicate.  If we can't insert it after 10 tries, die.
-        */
-       ev->node = rbtree_insertnode(el->times, ev);
-       if (!ev->node) {
-               if (rbtree_finddata(el->times, ev)) {
-                       int i;
-
-                       for (i = 0; i < 10; i++) {
-                               ev->when.tv_usec++;
-                               if (ev->when.tv_usec >= 1000000) {
-                                       ev->when.tv_usec = 0;
-                                       ev->when.tv_sec++;
-                               }
-
-                               if (rbtree_finddata(el->times, ev)) {
-                                       continue;
-                               }
-
-                               ev->node = rbtree_insertnode(el->times, ev);
-                               if (!ev->node) { /* error */
-                                       break;
-                               }
-
-                               *ev_p = ev;
-                               return 1;
-                       }
-
-               }
-               free(ev);
-               return 0;
-       }
-
-       *ev_p = ev;
-       return 1;
-}
-
-typedef struct lrad_event_walk_t {
-       lrad_event_t *ev;
-       struct timeval when;
-} lrad_event_walk_t;
-
-
-static int lrad_event_find_earliest(void *ctx, void *data)
-{
-       lrad_event_t *ev = data;
-       lrad_event_walk_t *w = ctx;
-
-       if (ev->when.tv_sec > w->when.tv_sec) {
-               w->when = ev->when;
-               return 1;
-       }
-
-       if ((ev->when.tv_sec == w->when.tv_sec) &&
-           (ev->when.tv_usec > w->when.tv_usec)) {
-               w->when = ev->when;
-               return 1;
-       }
-
-       w->ev = ev;
-       return 1;
-}
-
-
-int lrad_event_run(lrad_event_list_t *el, struct timeval *when)
-{
-       lrad_event_callback_t callback;
-       void *ctx;
-       lrad_event_t *ev;
-
-       if (!el) return 0;
-
-       if (rbtree_num_elements(el->times) == 0) {
-               when->tv_sec = 0;
-               when->tv_usec = 0;
-               return 0;
-       }
-
-       ev = rbtree_min(el->times);
-       if (!ev) {
-               when->tv_sec = 0;
-               when->tv_usec = 0;
-               fprintf(stderr, "FATAL ERROR!\n");
-               return 0;
-       }
-
-       /*
-        *      See if it's time to do this one.
-        */
-       if ((ev->when.tv_sec > when->tv_sec) ||
-           ((ev->when.tv_sec == when->tv_sec) &&
-            (ev->when.tv_usec > when->tv_usec))) {
-               *when = ev->when;
-               return 0;
-       }
-
-       callback = ev->callback;
-       ctx = ev->ctx;
-
-       /*
-        *      Delete the event before calling it.
-        */
-       lrad_event_delete(el, ev->ev_p);
-
-       callback(ctx);
-       return 1;
-}
-
-
-int lrad_event_now(lrad_event_list_t *el, struct timeval *when)
-{
-       if (!el || !when || !el->dispatch) return 0;
-
-       *when = el->now;
-       return 1;
-}
-
-#ifdef TESTING
-
-/*
- *  cc -g -I .. -c rbtree.c -o rbtree.o && cc -g -I .. -c isaac.c -o isaac.o && cc -DTESTING -I .. -c event.c  -o event_mine.o && cc event_mine.o rbtree.o isaac.o -o event
- *
- *  ./event
- *
- *  And hit CTRL-S to stop the output, CTRL-Q to continue.
- *  It normally alternates printing the time and sleeping,
- *  but when you hit CTRL-S/CTRL-Q, you should see a number
- *  of events run right after each other.
- *
- *  OR
- *
- *   valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./event
- */
-
-static void print_time(void *ctx)
-{
-       struct timeval *when = ctx;
-
-       printf("%d.%06d\n", when->tv_sec, when->tv_usec);
-       fflush(stdout);
-}
-
-static lrad_randctx rand_pool;
-
-static uint32_t event_rand(void)
-{
-       uint32_t num;
-
-       num = rand_pool.randrsl[rand_pool.randcnt++];
-       if (rand_pool.randcnt == 256) {
-               lrad_isaac(&rand_pool);
-               rand_pool.randcnt = 0;
-       }
-
-       return num;
-}
-
-
-#define MAX 100
-int main(int argc, char **argv)
-{
-       int i, rcode;
-       struct timeval array[MAX];
-       struct timeval now, when;
-       lrad_event_list_t *el;
-
-       el = lrad_event_list_create();
-       if (!el) exit(1);
-
-       memset(&rand_pool, 0, sizeof(rand_pool));
-       rand_pool.randrsl[1] = time(NULL);
-
-       lrad_randinit(&rand_pool, 1);
-       rand_pool.randcnt = 0;
-
-       gettimeofday(&array[0], NULL);
-       for (i = 1; i < MAX; i++) {
-               array[i] = array[i - 1];
-
-               array[i].tv_usec += event_rand() & 0xffff;
-               if (array[i].tv_usec > 1000000) {
-                       array[i].tv_usec -= 1000000;
-                       array[i].tv_sec++;
-               }
-               lrad_event_insert(el, print_time, &array[i], &array[i]);
-       }
-
-       while (lrad_event_list_num_elements(el)) {
-               gettimeofday(&now, NULL);
-               when = now;
-               if (!lrad_event_run(el, &when)) {
-                       int delay = (when.tv_sec - now.tv_sec) * 1000000;
-                       delay += when.tv_usec;
-                       delay -= now.tv_usec;
-
-                       printf("\tsleep %d\n", delay);
-                       fflush(stdout);
-                       usleep(delay);
-               }
-       }
-
-       lrad_event_list_free(el);
-
-       return 0;
-}
-#endif
diff --git a/src/lib/fifo.c b/src/lib/fifo.c
deleted file mode 100644 (file)
index a783f72..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * fifo.c      Non-thread-safe fifo (FIFO) implementation, based
- *             on hash tables.
- *
- * Version:    $Id$
- *
- *   This library is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU Lesser General Public
- *   License as published by the Free Software Foundation; either
- *   version 2.1 of the License, or (at your option) any later version.
- *
- *   This library is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *   Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public
- *   License along with this library; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *  Copyright 2005,2006  The FreeRADIUS server project
- *  Copyright 2005  Alan DeKok <aland@ox.org>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
-
-typedef struct lrad_fifo_entry_t {
-       struct lrad_fifo_entry_t *next;
-       void                    *data;
-} lrad_fifo_entry_t;
-
-struct lrad_fifo_t {
-       lrad_fifo_entry_t *head, **tail;
-       lrad_fifo_entry_t *freelist;
-
-       int num_elements;
-       int max_entries;
-       lrad_fifo_free_t freeNode;
-};
-
-
-lrad_fifo_t *lrad_fifo_create(int max_entries, lrad_fifo_free_t freeNode)
-{
-       lrad_fifo_t *fi;
-
-       if ((max_entries < 2) || (max_entries > (1024 * 1024))) return NULL;
-
-       fi = malloc(sizeof(*fi));
-       if (!fi) return NULL;
-
-       memset(fi, 0, sizeof(*fi));
-
-       fi->max_entries = max_entries;
-       fi->freeNode = freeNode;
-
-       return fi;
-}
-
-static void lrad_fifo_free_entries(lrad_fifo_t *fi, lrad_fifo_entry_t *head)
-{
-       lrad_fifo_entry_t *next;
-
-       while (head) {
-               next = head->next;
-
-               if (fi->freeNode && head->data) fi->freeNode(head->data);
-               free(head);
-
-               head = next;
-       }
-}
-
-void lrad_fifo_free(lrad_fifo_t *fi)
-{
-       if (!fi) return;
-
-       lrad_fifo_free_entries(fi, fi->head);
-       lrad_fifo_free_entries(fi, fi->freelist);
-
-       free(fi);
-}
-
-static lrad_fifo_entry_t *lrad_fifo_alloc_entry(lrad_fifo_t *fi)
-{
-       lrad_fifo_entry_t *entry;
-
-       if (fi->freelist) {
-               entry = fi->freelist;
-               fi->freelist = entry->next;
-       } else {
-               entry = malloc(sizeof(*entry));
-               if (!entry) return NULL;
-       }
-
-       memset(entry, 0, sizeof(*entry));
-       return entry;
-}
-
-int lrad_fifo_push(lrad_fifo_t *fi, void *data)
-{
-       lrad_fifo_entry_t *entry;
-
-       if (!fi || !data) return 0;
-
-       if (fi->num_elements >= fi->max_entries) return 0;
-
-       entry = lrad_fifo_alloc_entry(fi);
-       if (!entry) return 0;
-       entry->data = data;
-
-       if (!fi->head) {
-               fi->head = entry;
-       } else {
-               *fi->tail = entry;
-       }
-       fi->tail = &(entry->next);
-
-       fi->num_elements++;
-
-       return 1;
-}
-
-static void lrad_fifo_free_entry(lrad_fifo_t *fi, lrad_fifo_entry_t *entry)
-{
-       entry->data = NULL;
-       entry->next = fi->freelist;
-       fi->freelist = entry->next;
-}
-
-
-void *lrad_fifo_pop(lrad_fifo_t *fi)
-{
-       void *data;
-       lrad_fifo_entry_t *entry;
-
-       if (!fi || !fi->head) return NULL;
-
-       entry = fi->head;
-       fi->head = entry->next;
-
-       data = entry->data;
-       lrad_fifo_free_entry(fi, entry);
-
-       fi->num_elements--;
-
-       if (!fi->head) {
-               fi->tail = NULL;
-               fi->num_elements = 0;
-       }
-
-       return data;
-}
-
-void *lrad_fifo_peek(lrad_fifo_t *fi)
-{
-       void *data;
-       lrad_fifo_entry_t *entry;
-
-       if (!fi || !fi->head) return NULL;
-
-       return fi->head->data;
-}
-
-int lrad_fifo_num_elements(lrad_fifo_t *fi)
-{
-       if (!fi) return 0;
-
-       return fi->num_elements;
-}
-
-#ifdef TESTING
-
-/*
- *  cc -DTESTING -I .. fifo.c -o fifo
- *
- *  ./fifo
- */
-
-#define MAX 1024
-int main(int argc, char **argv)
-{
-       int i, array[MAX];
-       lrad_fifo_t *fi;
-
-       fi = lrad_fifo_create(MAX, NULL);
-       if (!fi) exit(1);
-
-       for (i = 0; i < MAX; i++) {
-               array[i] = i;
-
-               if (!lrad_fifo_push(fi, &array[i])) exit(2);
-       }
-
-       for (i = 0; i < MAX; i++) {
-               int *p;
-
-               p = lrad_fifo_pop(fi);
-               if (!p) {
-                       fprintf(stderr, "No pop at %d\n", i);
-                       exit(3);
-               }
-
-               if (*p != i) exit(4);
-       }
-
-       exit(0);
-}
-#endif
index ab984bb..57f737a 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
+static const char rcsid[] = "$Id$";
 
+#include <string.h>
 #include <ctype.h>
+#include <stdlib.h>
+
+#include "libradius.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
 
 /*
  * Two types of filters are supported, GENERIC and IP.  The identifiers
@@ -53,7 +58,6 @@ RCSID("$Id$")
 # define TRUE          (! FALSE)
 #endif
 
-
 /*
  *     ascend_ip_filter_t
  *
@@ -208,16 +212,9 @@ typedef struct ascend_filter_t {
                ascend_ip_filter_t       ip;
                ascend_ipx_filter_t      ipx;
                ascend_generic_filter_t generic;
-               uint8_t                 data[28]; /* ensure it's 32 bytes */
        } u;
 } ascend_filter_t;
-
-/*
- *     This is a wild C hack...
- */
-typedef struct _cpp_hack {
-       char data[(sizeof(ascend_filter_t) == 32) ? 1 : -1 ];
-} _cpp_hack;
+#define SIZEOF_RADFILTER 32
 
 /*
  * FilterPortType:
@@ -375,6 +372,49 @@ static int str2argv(char *str, char **argv, int max_argc)
 
 
 /*
+ *     hex2bin converts hexadecimal strings into binary
+ *
+ *     Hmm... there are a number of such functions in the source.
+ *     maybe we want to make a library function?
+ */
+static int hex2bin(const char *str, uint8_t *bin, size_t length)
+{
+       unsigned int            len;
+       const           char *letters = "0123456789ABCDEFabcdef";
+
+       /*
+        *      Must be byte aligned, not nibble aligned.
+        */
+       len = strlen(str);
+       if ((len & 0x01) != 0) return -1;
+
+       /*
+        *      Input string is too long to fit.  Don't even bother
+        *      trying.
+        */
+       if ((len / 2) > length) return -1;
+
+       /*
+        *      Input string contains non-hex characters, die.
+        */
+       if (strspn(str, letters) != len) return -1;
+
+       len = 0;
+       while (*str) {
+               char    *c1, *c2;
+
+               c1 = memchr(letters, toupper((int) *(str++)), 16);
+               c2 = memchr(letters, toupper((int) *(str++)), 16);
+
+               *(bin++) = ((c1-letters)<<4) + (c2-letters);
+               len++;
+       }
+
+        return len;
+}
+
+
+/*
  *     ascend_parse_ipx_net
  *
  *     srcipxnet nnnn srcipxnode mmmmm [srcipxsoc cmd value ]
@@ -415,7 +455,7 @@ static int ascend_parse_ipx_net(int argc, char **argv,
        /*
         *      Node must be 6 octets long.
         */
-       token = lrad_hex2bin(p, net->node, IPX_NODE_ADDR_LEN);
+       token = hex2bin(p, net->node, IPX_NODE_ADDR_LEN);
        if (token != IPX_NODE_ADDR_LEN) return -1;
 
        /*
@@ -702,17 +742,6 @@ static int ascend_parse_port(uint16_t *port, char *compare, char *str)
 }
 
 
-#define IP_SRC_ADDR_FLAG    (1 << 0)
-#define IP_DEST_ADDR_FLAG   (1 << 1)
-#define IP_SRC_PORT_FLAG    (1 << 2)
-#define IP_DEST_PORT_FLAG   (1 << 3)
-#define IP_PROTO_FLAG       (1 << 4)
-#define IP_EST_FLAG         (1 << 5)
-
-#define DONE_FLAGS     (IP_SRC_ADDR_FLAG | IP_DEST_ADDR_FLAG | \
-                       IP_SRC_PORT_FLAG | IP_DEST_PORT_FLAG | \
-                       IP_PROTO_FLAG | IP_EST_FLAG)
-
 /*
  *     ascend_parse_ip:
  *
@@ -759,37 +788,72 @@ static int ascend_parse_ip(int argc, char **argv, ascend_ip_filter_t *filter)
         *      There may, or may not, be src & dst IP's in the string.
         */
        flags = 0;
-       while ((argc > 0) && (flags != DONE_FLAGS)) {
+       while ((argc > 0) && (flags != 7)) {
                token = lrad_str2int(filterKeywords, argv[0], -1);
                switch (token) {
                case FILTER_IP_SRC:
-                       if (flags & IP_SRC_ADDR_FLAG) return -1;
+                       if (flags & 0x01) return -1;
                        if (argc < 2) return -1;
 
                        rcode = ascend_parse_ipaddr(&filter->srcip, argv[1]);
                        if (rcode < 0) return rcode;
 
                        filter->srcmask = rcode;
-                       flags |= IP_SRC_ADDR_FLAG;
+                       flags |= 0x01;
                        argv += 2;
                        argc -= 2;
                        break;
 
                case FILTER_IP_DST:
-                       if (flags & IP_DEST_ADDR_FLAG) return -1;
+                       if (flags & 0x02) return -1;
                        if (argc < 2) return -1;
 
                        rcode = ascend_parse_ipaddr(&filter->dstip, argv[1]);
                        if (rcode < 0) return rcode;
 
                        filter->dstmask = rcode;
-                       flags |= IP_DEST_ADDR_FLAG;
+                       flags |= 0x02;
                        argv += 2;
                        argc -= 2;
                        break;
 
+                       /*
+                        *      Should be protocol, ASCII or otherwise.
+                        */
+               default:
+                       if (strspn(argv[0], "0123456789") == strlen(argv[0])) {
+                               token = atoi(argv[0]);
+                       } else {
+                               token = lrad_str2int(filterProtoName, argv[0], -1);
+                               if (token == -1) {
+                                       librad_log("Unknown IP protocol \"%s\" in IP data filter",
+                                                  argv[0]);
+                                       return -1;
+                               }
+                       }
+                       filter->proto = token;
+                       flags = 0x07; /* MUST have parsed everything. */
+
+                       argv++;
+                       argc--;
+                       break;
+               }
+       } /* looking for src/dst IP, and proto */
+
+       /*
+        *      Done looking for everything, return.
+        */
+       if (argc == 0) return 0;
+
+       /*
+        *      There may, or may not, be src & dst ports in the string.
+        */
+       flags = 0;
+       while ((argc > 0) && (flags != 7)) {
+               token = lrad_str2int(filterKeywords, argv[0], -1);
+               switch (token) {
                case FILTER_IP_SRC_PORT:
-                       if (flags & IP_SRC_PORT_FLAG) return -1;
+                       if (flags & 0x01) return -1;
                        if (argc < 3) return -1;
 
                        rcode = ascend_parse_port(&filter->srcport,
@@ -797,13 +861,13 @@ static int ascend_parse_ip(int argc, char **argv, ascend_ip_filter_t *filter)
                        if (rcode < 0) return rcode;
                        filter->srcPortComp = rcode;
 
-                       flags |= IP_SRC_PORT_FLAG;
+                       flags |= 0x01;
                        argv += 3;
                        argc -= 3;
                        break;
 
                case FILTER_IP_DST_PORT:
-                       if (flags & IP_DEST_PORT_FLAG) return -1;
+                       if (flags & 0x02) return -1;
                        if (argc < 3) return -1;
 
                        rcode = ascend_parse_port(&filter->dstport,
@@ -811,39 +875,31 @@ static int ascend_parse_ip(int argc, char **argv, ascend_ip_filter_t *filter)
                        if (rcode < 0) return rcode;
                        filter->dstPortComp = rcode;
 
-                       flags |= IP_DEST_PORT_FLAG;
+                       flags |= 0x02;
                        argv += 3;
                        argc -= 3;
                        break;
 
+                       /*
+                        *      Look for established connections.
+                        */
                case FILTER_EST:
-                       if (flags & IP_EST_FLAG) return -1;
                        filter->established = 1;
                        argv++;
                        argc--;
-                       flags |= IP_EST_FLAG;
+                       flags = 0x07;
                        break;
 
+                       /*
+                        *      Unknown thingy.
+                        */
                default:
-                       if (flags & IP_PROTO_FLAG) return -1;
-                       if (strspn(argv[0], "0123456789") == strlen(argv[0])) {
-                               token = atoi(argv[0]);
-                       } else {
-                               token = lrad_str2int(filterProtoName, argv[0], -1);
-                               if (token == -1) {
-                                       librad_log("Unknown IP protocol \"%s\" in IP data filter",
-                                                  argv[0]);
-                                       return -1;
-                               }
-                       }
-                       filter->proto = token;
-                       flags |= IP_PROTO_FLAG;
-
-                       argv++;
-                       argc--;
+                       librad_log("Unknown string \"%s\" in IP data filter",
+                                  argv[0]);
+                       return -1;
                        break;
                }
-       }
+       } /* looking for src/dst port */
 
        /*
         *      We should have parsed everything by now.
@@ -914,11 +970,11 @@ static int ascend_parse_generic(int argc, char **argv,
        filter->offset = rcode;
        filter->offset = htons(filter->offset);
 
-       rcode = lrad_hex2bin(argv[1], filter->mask, sizeof(filter->mask));
-       if (rcode != sizeof(filter->mask)) return -1;
+       rcode = hex2bin(argv[1], filter->mask, sizeof(filter->mask));
+       if (rcode < 0) return -1;
 
-       token = lrad_hex2bin(argv[2], filter->value, sizeof(filter->value));
-       if (token != sizeof(filter->value)) return -1;
+       token = hex2bin(argv[2], filter->value, sizeof(filter->value));
+       if (token < 0) return -1;
 
        /*
         *      The mask and value MUST be the same length.
@@ -993,7 +1049,7 @@ ascend_parse_filter(VALUE_PAIR *pair)
        ascend_filter_t filter;
 
        rcode = -1;
-
+       
        /*
         *      Rather than printing specific error messages, we create
         *      a general one here, which won't be used if the function
@@ -1004,10 +1060,10 @@ ascend_parse_filter(VALUE_PAIR *pair)
        /*
         *      Tokenize the input string in the VP.
         *
-        *      Once the filter is *completelty* parsed, then we will
+        *      Once the filter is *completely* parsed, then we will
         *      over-write it with the final binary filter.
         */
-       argc = str2argv(pair->vp_strvalue, argv, 32);
+       argc = str2argv(pair->strvalue, argv, 32);
        if (argc < 3) return -1;
 
        /*
@@ -1093,8 +1149,8 @@ ascend_parse_filter(VALUE_PAIR *pair)
         *      Touch the VP only if everything was OK.
         */
        if (rcode == 0) {
-               pair->length = sizeof(filter);
-               memcpy(pair->vp_filter, &filter, sizeof(filter));
+               pair->length = SIZEOF_RADFILTER;
+               memcpy(pair->strvalue, &filter, sizeof(filter));
        }
 
        return rcode;
@@ -1107,7 +1163,7 @@ ascend_parse_filter(VALUE_PAIR *pair)
      * previous 'more'
      */
     if( prevRadPair ) {
-       filt = ( RadFilter * )prevRadPair->vp_strvalue;
+       filt = ( RadFilter * )prevRadPair->strvalue;
        if(( tok != FILTER_GENERIC_TYPE ) || (rc == -1 ) ||
           ( prevRadPair->attribute != pair->attribute ) ||
           ( filt->indirection != radFil.indirection ) ||
@@ -1126,7 +1182,7 @@ ascend_parse_filter(VALUE_PAIR *pair)
     }
 
     if( rc != -1 ) {
-       memcpy( pair->vp_strvalue, &radFil, pair->length );
+       memcpy( pair->strvalue, (char *) &radFil, pair->length );
     }
     return(rc);
 
@@ -1141,40 +1197,40 @@ ascend_parse_filter(VALUE_PAIR *pair)
  *     Note we don't bother checking 'len' after the snprintf's.
  *     This function should ONLY be called with a large (~1k) buffer.
  */
-void print_abinary(VALUE_PAIR *vp, char *buffer, int len)
+void print_abinary(VALUE_PAIR *vp, u_char *buffer, int len)
 {
   int                  i;
   char                 *p;
-  ascend_filter_t      *filter;
+  ascend_filter_t      filter;
 
   static const char *action[] = {"drop", "forward"};
   static const char *direction[] = {"out", "in"};
 
-  p = buffer;
+  p = (char *)buffer;
 
   /*
    *  Just for paranoia: wrong size filters get printed as octets
    */
-  if (vp->length != sizeof(*filter)) {
-         strcpy(p, "0x");
-         p += 2;
-         len -= 2;
-         for (i = 0; i < vp->length; i++) {
-                 snprintf(p, len, "%02x", vp->vp_octets[i]);
-                 p += 2;
-                 len -= 2;
-         }
-         return;
+  if (vp->length > SIZEOF_RADFILTER) {
+    strcpy(p, "0x");
+    p += 2;
+    len -= 2;
+    for (i = 0; i < vp->length; i++) {
+      snprintf(p, len, "%02x", vp->strvalue[i]);
+      p += 2;
+      len -= 2;
+    }
+    return;
   }
 
+  memcpy(&filter, vp->strvalue, SIZEOF_RADFILTER); /* alignment issues */
   *(p++) = '"';
   len -= 3;                    /* account for leading & trailing quotes */
 
-  filter = (ascend_filter_t *) &(vp->vp_filter);
   i = snprintf(p, len, "%s %s %s",
-              lrad_int2str(filterType, filter->type, "??"),
-              direction[filter->direction & 0x01],
-              action[filter->forward & 0x01]);
+              lrad_int2str(filterType, filter.type, "??"),
+              direction[filter.direction & 0x01],
+              action[filter.forward & 0x01]);
 
   p += i;
   len -= i;
@@ -1182,52 +1238,52 @@ void print_abinary(VALUE_PAIR *vp, char *buffer, int len)
   /*
    *   Handle IP filters
    */
-  if (filter->type == RAD_FILTER_IP) {
+  if (filter.type == RAD_FILTER_IP) {
 
-    if (filter->u.ip.srcip) {
+    if (filter.u.ip.srcip) {
       i = snprintf(p, len, " srcip %d.%d.%d.%d/%d",
-                  ((uint8_t *) &filter->u.ip.srcip)[0],
-                  ((uint8_t *) &filter->u.ip.srcip)[1],
-                  ((uint8_t *) &filter->u.ip.srcip)[2],
-                  ((uint8_t *) &filter->u.ip.srcip)[3],
-                  filter->u.ip.srcmask);
+                  ((u_char *) &filter.u.ip.srcip)[0],
+                  ((u_char *) &filter.u.ip.srcip)[1],
+                  ((u_char *) &filter.u.ip.srcip)[2],
+                  ((u_char *) &filter.u.ip.srcip)[3],
+                  filter.u.ip.srcmask);
       p += i;
       len -= i;
     }
 
-    if (filter->u.ip.dstip) {
+    if (filter.u.ip.dstip) {
       i = snprintf(p, len, " dstip %d.%d.%d.%d/%d",
-                  ((uint8_t *) &filter->u.ip.dstip)[0],
-                  ((uint8_t *) &filter->u.ip.dstip)[1],
-                  ((uint8_t *) &filter->u.ip.dstip)[2],
-                  ((uint8_t *) &filter->u.ip.dstip)[3],
-                  filter->u.ip.dstmask);
+                  ((u_char *) &filter.u.ip.dstip)[0],
+                  ((u_char *) &filter.u.ip.dstip)[1],
+                  ((u_char *) &filter.u.ip.dstip)[2],
+                  ((u_char *) &filter.u.ip.dstip)[3],
+                  filter.u.ip.dstmask);
       p += i;
       len -= i;
     }
 
     i =  snprintf(p, len, " %s",
-                 lrad_int2str(filterProtoName, filter->u.ip.proto, "??"));
+                 lrad_int2str(filterProtoName, filter.u.ip.proto, "??"));
     p += i;
     len -= i;
 
-    if (filter->u.ip.srcPortComp > RAD_NO_COMPARE) {
+    if (filter.u.ip.srcPortComp > RAD_NO_COMPARE) {
       i = snprintf(p, len, " srcport %s %d",
-                  lrad_int2str(filterCompare, filter->u.ip.srcPortComp, "??"),
-                  ntohs(filter->u.ip.srcport));
+                  lrad_int2str(filterCompare, filter.u.ip.srcPortComp, "??"),
+                  ntohs(filter.u.ip.srcport));
       p += i;
       len -= i;
     }
 
-    if (filter->u.ip.dstPortComp > RAD_NO_COMPARE) {
+    if (filter.u.ip.dstPortComp > RAD_NO_COMPARE) {
       i = snprintf(p, len, " dstport %s %d",
-                  lrad_int2str(filterCompare, filter->u.ip.dstPortComp, "??"),
-                  ntohs(filter->u.ip.dstport));
+                  lrad_int2str(filterCompare, filter.u.ip.dstPortComp, "??"),
+                  ntohs(filter.u.ip.dstport));
       p += i;
       len -= i;
     }
 
-    if (filter->u.ip.established) {
+    if (filter.u.ip.established) {
       i = snprintf(p, len, " est");
       p += i;
       len -= i;
@@ -1236,56 +1292,56 @@ void print_abinary(VALUE_PAIR *vp, char *buffer, int len)
     /*
      * Handle IPX filters
      */
-  } else if (filter->type == RAD_FILTER_IPX) {
+  } else if (filter.type == RAD_FILTER_IPX) {
     /* print for source */
-    if (filter->u.ipx.src.net) {
+    if (filter.u.ipx.src.net) {
       i = snprintf(p, len, " srcipxnet 0x%04x srcipxnode 0x%02x%02x%02x%02x%02x%02x",
-                 (unsigned int)ntohl(filter->u.ipx.src.net),
-                 filter->u.ipx.src.node[0], filter->u.ipx.src.node[1],
-                 filter->u.ipx.src.node[2], filter->u.ipx.src.node[3],
-                 filter->u.ipx.src.node[4], filter->u.ipx.src.node[5]);
+                 (unsigned int)ntohl(filter.u.ipx.src.net),
+                 filter.u.ipx.src.node[0], filter.u.ipx.src.node[1],
+                 filter.u.ipx.src.node[2], filter.u.ipx.src.node[3],
+                 filter.u.ipx.src.node[4], filter.u.ipx.src.node[5]);
       p += i;
       len -= i;
 
-      if (filter->u.ipx.srcSocComp > RAD_NO_COMPARE) {
+      if (filter.u.ipx.srcSocComp > RAD_NO_COMPARE) {
        i = snprintf(p, len, " srcipxsock %s 0x%04x",
-                    lrad_int2str(filterCompare, filter->u.ipx.srcSocComp, "??"),
-                    ntohs(filter->u.ipx.src.socket));
+                    lrad_int2str(filterCompare, filter.u.ipx.srcSocComp, "??"),
+                    ntohs(filter.u.ipx.src.socket));
        p += i;
        len -= i;
       }
     }
 
     /* same for destination */
-    if (filter->u.ipx.dst.net) {
+    if (filter.u.ipx.dst.net) {
       i = snprintf(p, len, " dstipxnet 0x%04x dstipxnode 0x%02x%02x%02x%02x%02x%02x",
-                 (unsigned int)ntohl(filter->u.ipx.dst.net),
-                 filter->u.ipx.dst.node[0], filter->u.ipx.dst.node[1],
-                 filter->u.ipx.dst.node[2], filter->u.ipx.dst.node[3],
-                 filter->u.ipx.dst.node[4], filter->u.ipx.dst.node[5]);
+                 (unsigned int)ntohl(filter.u.ipx.dst.net),
+                 filter.u.ipx.dst.node[0], filter.u.ipx.dst.node[1],
+                 filter.u.ipx.dst.node[2], filter.u.ipx.dst.node[3],
+                 filter.u.ipx.dst.node[4], filter.u.ipx.dst.node[5]);
       p += i;
       len -= i;
 
-      if (filter->u.ipx.dstSocComp > RAD_NO_COMPARE) {
+      if (filter.u.ipx.dstSocComp > RAD_NO_COMPARE) {
        i = snprintf(p, len, " dstipxsock %s 0x%04x",
-                    lrad_int2str(filterCompare, filter->u.ipx.dstSocComp, "??"),
-                    ntohs(filter->u.ipx.dst.socket));
+                    lrad_int2str(filterCompare, filter.u.ipx.dstSocComp, "??"),
+                    ntohs(filter.u.ipx.dst.socket));
        p += i;
        len -= i;
       }
     }
 
 
-  } else if (filter->type == RAD_FILTER_GENERIC) {
+  } else if (filter.type == RAD_FILTER_GENERIC) {
     int count;
 
-    i = snprintf(p, len, " %u ", (unsigned int) ntohs(filter->u.generic.offset));
+    i = snprintf(p, len, " %u ", (unsigned int) ntohs(filter.u.generic.offset));
     p += i;
     i -= len;
 
     /* show the mask */
-    for (count = 0; count < ntohs(filter->u.generic.len); count++) {
-      i = snprintf(p, len, "%02x", filter->u.generic.mask[count]);
+    for (count = 0; count < ntohs(filter.u.generic.len); count++) {
+      i = snprintf(p, len, "%02x", filter.u.generic.mask[count]);
       p += i;
       len -= i;
     }
@@ -1295,17 +1351,17 @@ void print_abinary(VALUE_PAIR *vp, char *buffer, int len)
     len--;
 
     /* show the value */
-    for (count = 0; count < ntohs(filter->u.generic.len); count++) {
-      i = snprintf(p, len, "%02x", filter->u.generic.value[count]);
+    for (count = 0; count < ntohs(filter.u.generic.len); count++) {
+      i = snprintf(p, len, "%02x", filter.u.generic.value[count]);
       p += i;
       len -= i;
     }
 
-    i = snprintf(p, len, " %s", (filter->u.generic.compNeq) ? "!=" : "==");
+    i = snprintf(p, len, " %s", (filter.u.generic.compNeq) ? "!=" : "==");
     p += i;
     len -= i;
 
-    if (filter->u.generic.more != 0) {
+    if (filter.u.generic.more != 0) {
       i = snprintf(p, len, " more");
       p += i;
       len -= i;
diff --git a/src/lib/getaddrinfo.c b/src/lib/getaddrinfo.c
deleted file mode 100644 (file)
index 9171bb7..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * These functions are defined and used only if the configure
- * cannot detect the standard getaddrinfo(), freeaddrinfo(),
- * gai_strerror() and getnameinfo(). This avoids sprinkling of ifdefs.
- *
- * FIXME: getaddrinfo() & getnameinfo() should
- *        return all IPv4 addresses provided by DNS lookup.
- */
-
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/libradius.h>
-
-#include       <ctype.h>
-#include       <sys/param.h>
-
-#ifdef HAVE_PTHREAD_H
-#include       <pthread.h>
-
-/* Thread safe DNS lookups */
-/* TODO There are some systems that use the same hostent structure
-    to return for gethostbyname() & gethostbyaddr(), if that is the
-    case then use only one mutex instead of seperate mutexes
- */
-static int lrad_hostbyname = 0;
-static int lrad_hodtbyaddr = 0;
-static pthread_mutex_t lrad_hostbyname_mutex;
-static pthread_mutex_t lrad_hodtbyaddr_mutex;
-#endif
-
-#undef LOCAL_GETHOSTBYNAMERSTYLE
-#ifndef GETHOSTBYNAMERSTYLE
-#define LOCAL_GETHOSTBYNAMERSTYLE 1
-#elif (GETHOSTBYNAMERSTYLE != SYSVSTYLE) && (GETHOSTBYNAMERSTYLE != GNUSTYLE)
-#define LOCAL_GETHOSTBYNAMERSTYLE 1
-#endif /* GETHOSTBYNAMERSTYLE */
-
-#undef LOCAL_GETHOSTBYADDRR
-#ifndef GETHOSTBYADDRRSTYLE
-#define LOCAL_GETHOSTBYADDRR 1
-#elif (GETHOSTBYADDRRSTYLE != SYSVSTYLE) && (GETHOSTBYADDRRSTYLE != GNUSTYLE)
-#define LOCAL_GETHOSTBYADDRR 1
-#endif /* GETHOSTBYADDRRSTYLE */
-
-/*
- * gethostbyaddr() & gethostbyname() return hostent structure
- * To make these functions thread safe, we need to
- * copy the data and not pointers
- *
- * struct hostent {
- *    char    *h_name;        * official name of host *
- *    char    **h_aliases;    * alias list *
- *    int     h_addrtype;     * host address type *
- *    int     h_length;       * length of address *
- *    char    **h_addr_list;  * list of addresses *
- * }
- * This struct contains 3 pointers as members.
- * The data from these pointers is copied into a buffer.
- * The buffer is formatted as below to store the data
- *  ---------------------------------------------------------------
- * | h_name\0alias_array\0h_aliases\0..\0addr_array\0h_addr_list\0 |
- *  ---------------------------------------------------------------
- */
-#if defined(LOCAL_GETHOSTBYNAMER) || defined(LOCAL_GETHOSTBYADDRR)
-#define BUFFER_OVERFLOW 255
-int copy_hostent(struct hostent *from, struct hostent *to,
-           char *buffer, int buflen, int *error)
-{
-    int i, len;
-    char *ptr = buffer;
-
-    *error = 0;
-    to->h_addrtype = from->h_addrtype;
-    to->h_length = from->h_length;
-    to->h_name = (char *)ptr;
-
-    /* copy hostname to buffer */
-    len=strlen(from->h_name)+1;
-    strcpy(ptr, from->h_name);
-    ptr += len;
-
-    /* copy aliases to buffer */
-    to->h_aliases = (char**)ptr;
-    for(i = 0; from->h_aliases[i]; i++);
-    ptr += (i+1) * sizeof(char *);
-
-    for(i = 0; from->h_aliases[i]; i++) {
-       len = strlen(from->h_aliases[i])+1;
-       if ((ptr-buffer)+len < buflen) {
-           to->h_aliases[i] = ptr;
-              strcpy(ptr, from->h_aliases[i]);
-           ptr += len;
-       } else {
-           *error = BUFFER_OVERFLOW;
-           return *error;
-       }
-    }
-    to->h_aliases[i] = NULL;
-
-    /* copy addr_list to buffer */
-    to->h_addr_list = (char**)ptr;
-    for(i = 0; (int *)from->h_addr_list[i] != 0; i++);
-    ptr += (i+1) * sizeof(int *);
-
-    for(i = 0; (int *)from->h_addr_list[i] != 0; i++) {
-       len = sizeof(int);
-       if ((ptr-buffer)+len < buflen) {
-           to->h_addr_list[i] = ptr;
-           memcpy(ptr, from->h_addr_list[i], len);
-           ptr += len;
-       } else {
-           *error = BUFFER_OVERFLOW;
-            return *error;
-       }
-    }
-    to->h_addr_list[i] = 0;
-    return *error;
-}
-#endif /* (LOCAL_GETHOSTBYNAMER == 1) || (LOCAL_GETHOSTBYADDRR == 1) */
-
-#ifdef LOCAL_GETHOSTBYNAMERSTYLE
-static struct hostent *
-gethostbyname_r(const char *hostname, struct hostent *result,
-           char *buffer, int buflen, int *error)
-{
-    struct hostent *hp;
-
-#ifdef HAVE_PTHREAD_H
-    if (lrad_hostbyname == 0) {
-       pthread_mutex_init(&lrad_hostbyname_mutex, NULL);
-       lrad_hostbyname = 1;
-    }
-    pthread_mutex_lock(&lrad_hostbyname_mutex);
-#endif
-
-    hp = gethostbyname(hostname);
-    if ((!hp) || (hp->h_addrtype != AF_INET) || (hp->h_length != 4)) {
-        *error = h_errno;
-         hp = NULL;
-    } else {
-         copy_hostent(hp, result, buffer, buflen, error);
-         hp = result;
-    }
-
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&lrad_hostbyname_mutex);
-#endif
-
-    return hp;
-}
-#endif /* GETHOSTBYNAMERSTYLE */
-
-
-#ifdef LOCAL_GETHOSTBYADDRR
-static struct hostent *
-gethostbyaddr_r(const char *addr, int len, int type, struct hostent *result,
-               char *buffer, int buflen, int *error)
-{
-    struct hostent *hp;
-
-#ifdef HAVE_PTHREAD_H
-    if (lrad_hodtbyaddr == 0) {
-       pthread_mutex_init(&lrad_hodtbyaddr_mutex, NULL);
-       lrad_hodtbyaddr = 1;
-    }
-    pthread_mutex_lock(&lrad_hodtbyaddr_mutex);
-#endif
-
-    hp = gethostbyaddr(addr, len, type);
-    if ((!hp) || (hp->h_addrtype != AF_INET) || (hp->h_length != 4)) {
-        *error = h_errno;
-         hp = NULL;
-    } else {
-        copy_hostent(hp, result, buffer, buflen, error);
-         hp = result;
-    }
-
-#ifdef HAVE_PTHREAD_H
-    pthread_mutex_unlock(&lrad_hodtbyaddr_mutex);
-#endif
-
-    return hp;
-}
-#endif /* GETHOSTBYADDRRSTYLE */
-
-/*
- * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
- *
- * Below code is based on ssh-1.2.27-IPv6-1.5 written by
- * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
- */
-
-#ifndef HAVE_GETADDRINFO
-static struct addrinfo *
-malloc_ai(int port, u_long addr, int socktype, int proto)
-{
-    struct addrinfo *ai;
-
-    ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
-                                   sizeof(struct sockaddr_in));
-    if (ai) {
-        memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
-        ai->ai_addr = (struct sockaddr *)(ai + 1);
-        ai->ai_addrlen = sizeof(struct sockaddr_in);
-#ifdef HAVE_SOCKADDR_SA_LEN
-        ai->ai_addr->sa_len = sizeof(struct sockaddr_in);
-#endif
-        ai->ai_addr->sa_family = ai->ai_family = AF_INET;
-        ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
-        ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
-        ai->ai_socktype = socktype;
-        ai->ai_protocol = proto;
-        return ai;
-    } else {
-        return NULL;
-    }
-}
-
-char *
-gai_strerror(int ecode)
-{
-    switch (ecode) {
-    case EAI_MEMORY:
-        return "memory allocation failure.";
-    case EAI_FAMILY:
-        return "ai_family not supported.";
-    case EAI_NONAME:
-        return "hostname nor servname provided, or not known.";
-    case EAI_SERVICE:
-        return "servname not supported for ai_socktype.";
-    default:
-        return "unknown error.";
-    }
-}
-
-void
-freeaddrinfo(struct addrinfo *ai)
-{
-    struct addrinfo *next;
-
-    if (ai->ai_canonname)
-        free(ai->ai_canonname);
-    do {
-        next = ai->ai_next;
-        free(ai);
-    } while ((ai = next) != NULL);
-}
-
-int
-getaddrinfo(const char *hostname, const char *servname,
-            const struct addrinfo *hints, struct addrinfo **res)
-{
-    struct addrinfo *cur, *prev = NULL;
-    struct hostent *hp;
-    struct hostent result;
-    struct in_addr in;
-    int i, port = 0, socktype, proto;
-    int error;
-    char buffer[2048];
-
-    if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC)
-        return EAI_FAMILY;
-
-    socktype = (hints && hints->ai_socktype) ? hints->ai_socktype
-                                             : SOCK_STREAM;
-    if (hints && hints->ai_protocol)
-        proto = hints->ai_protocol;
-    else {
-        switch (socktype) {
-        case SOCK_DGRAM:
-            proto = IPPROTO_UDP;
-            break;
-        case SOCK_STREAM:
-            proto = IPPROTO_TCP;
-            break;
-        default:
-            proto = 0;
-            break;
-        }
-    }
-    if (servname) {
-        if (isdigit((int)*servname))
-            port = htons(atoi(servname));
-        else {
-            struct servent *se;
-            char *pe_proto;
-
-            switch (socktype) {
-            case SOCK_DGRAM:
-                pe_proto = "udp";
-                break;
-            case SOCK_STREAM:
-                pe_proto = "tcp";
-                break;
-            default:
-                pe_proto = NULL;
-                break;
-            }
-            if ((se = getservbyname(servname, pe_proto)) == NULL)
-                return EAI_SERVICE;
-            port = se->s_port;
-        }
-    }
-    if (!hostname) {
-        if (hints && hints->ai_flags & AI_PASSIVE)
-            *res = malloc_ai(port, htonl(0x00000000), socktype, proto);
-        else
-            *res = malloc_ai(port, htonl(0x7f000001), socktype, proto);
-        if (*res)
-            return 0;
-        else
-            return EAI_MEMORY;
-    }
-    /* Numeric IP Address */
-    if (inet_aton(hostname, &in)) {
-        *res = malloc_ai(port, in.s_addr, socktype, proto);
-        if (*res)
-            return 0;
-        else
-            return EAI_MEMORY;
-    }
-    if (hints && hints->ai_flags & AI_NUMERICHOST)
-        return EAI_NONAME;
-
-    /* DNS Lookup */
-#ifdef GETHOSTBYNAMERSTYLE
-#if GETHOSTBYNAMERSTYLE == SYSVSTYLE
-    hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error);
-#elif GETHOSTBYNAMERSTYLE == GNUSTYLE
-    if (gethostbyname_r(hostname, &result, buffer,
-         sizeof(buffer), &hp, &error) != 0) {
-               hp = NULL;
-       }
-#else
-    hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error);
-#endif
-#else
-    hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error);
-#endif
-    if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
-        for (i = 0; hp->h_addr_list[i]; i++) {
-            if ((cur = malloc_ai(port,
-                                ((struct in_addr *)hp->h_addr_list[i])->s_addr,
-                                socktype, proto)) == NULL) {
-                if (*res)
-                    freeaddrinfo(*res);
-                return EAI_MEMORY;
-            }
-            if (prev)
-                prev->ai_next = cur;
-            else
-                *res = cur;
-            prev = cur;
-        }
-        if (hints && hints->ai_flags & AI_CANONNAME && *res) {
-            if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) {
-                freeaddrinfo(*res);
-                return EAI_MEMORY;
-            }
-        }
-        return 0;
-    }
-    return EAI_NONAME;
-}
-#endif /* HAVE_GETADDRINFO */
-
-
-#ifndef HAVE_GETNAMEINFO
-int
-getnameinfo(const struct sockaddr *sa, socklen_t salen,
-               char *host, size_t hostlen,
-               char *serv, size_t servlen,
-               unsigned int flags)
-{
-    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-    struct hostent *hp;
-    struct hostent result;
-    char tmpserv[16];
-    char buffer[2048];
-    int error;
-
-    if (serv) {
-        snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
-        if (strlen(tmpserv) > servlen)
-            return EAI_MEMORY;
-        else
-            strcpy(serv, tmpserv);
-    }
-    if (host) {
-        if (flags & NI_NUMERICHOST) {
-            /*  No Reverse DNS lookup */
-            if (flags & NI_NAMEREQD)
-                return EAI_NONAME;
-            if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
-                return EAI_MEMORY;
-            else {
-                strcpy(host, inet_ntoa(sin->sin_addr));
-                return 0;
-            }
-        } else {
-        /*  Reverse DNS lookup required */
-#ifdef GETHOSTBYADDRRSTYLE
-#if GETHOSTBYADDRRSTYLE == SYSVSTYLE
-            hp = gethostbyaddr_r((char *)&sin->sin_addr,
-                               sizeof(struct in_addr), AF_INET,
-                              &result, buffer, sizeof(buffer), &error);
-#elif GETHOSTBYADDRRSTYLE == GNUSTYLE
-            if (gethostbyaddr_r((char *)&sin->sin_addr,
-                               sizeof(struct in_addr), AF_INET,
-                                   &result, buffer, sizeof(buffer),
-                                   &hp, &error) != 0) {
-                       hp = NULL;
-            }
-#else
-            hp = gethostbyaddr_r((char *)&sin->sin_addr,
-                               sizeof(struct in_addr), AF_INET,
-                              &result, buffer, sizeof(buffer), &error);
-#endif
-#else
-            hp = gethostbyaddr_r((char *)&sin->sin_addr,
-                               sizeof(struct in_addr), AF_INET,
-                              &result, buffer, sizeof(buffer), &error);
-#endif
-            if (hp)
-                if (strlen(hp->h_name) >= hostlen)
-                    return EAI_MEMORY;
-                else {
-                    strcpy(host, hp->h_name);
-                    return 0;
-                }
-            else if (flags & NI_NAMEREQD)
-                return EAI_NONAME;
-            else if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
-                return EAI_MEMORY;
-            else {
-                strcpy(host, inet_ntoa(sin->sin_addr));
-                return 0;
-            }
-        }
-    }
-    return 0;
-}
-#endif /* HAVE_GETNAMEINFO */
index 71aeeca..3ec180f 100644 (file)
@@ -6,10 +6,10 @@
  *  modifications so that they're not lock-free. :(
  *
  *  However, the split-order idea allows a fast & easy splitting of the
- *  hash bucket chain when the hash table is resized.  Without it, we'd
- *  have to check & update the pointers for every node in the buck chain,
- *  rather than being able to move 1/2 of the entries in the chain with
- *  one update.
+ *  hash bucket chain when the hash table is resized.
+ *
+ *  This implementation can do ~10^6 lookups/s, which should be fast
+ *  enough for most people.
  *
  * Version:    $Id$
  *
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- *  Copyright 2005,2006  The FreeRADIUS server project
+ *  Copyright 2005  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
+
+#include "autoconf.h"
+
+#include <stdlib.h>
+#include <string.h>
 
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/hash.h>
+#include "missing.h"
+#include "libradius.h"
 
 /*
  *     A reasonable number of buckets to start off with.
@@ -66,8 +70,6 @@ struct lrad_hash_table_t {
 };
 
 #ifdef TESTING
-#include <stdio.h>
-
 static int grow = 0;
 #endif
 
@@ -173,7 +175,7 @@ static uint32_t parent_of(uint32_t key)
 
        if (key > 0x000000ff)
                return (key & 0x000000ff) | (parent_byte[key >> 8] << 8);
-
+       
        return parent_byte[key];
 }
 
@@ -328,7 +330,7 @@ static void lrad_hash_table_fixup(lrad_hash_table_t *ht, uint32_t entry)
 
        if (!ht->buckets[parent_entry]) {
                lrad_hash_table_fixup(ht, parent_entry);
-       }
+       }       
 
        /*
         *      Keep walking down cur, trying to find entries that
@@ -337,7 +339,7 @@ static void lrad_hash_table_fixup(lrad_hash_table_t *ht, uint32_t entry)
         */
        last = &ht->buckets[parent_entry];
        this = parent_entry;
-
+       
        for (cur = *last; cur != &ht->null; cur = cur->next) {
                uint32_t real_entry;
 
@@ -369,7 +371,7 @@ static void lrad_hash_table_fixup(lrad_hash_table_t *ht, uint32_t entry)
 static void lrad_hash_table_grow(lrad_hash_table_t *ht)
 {
        lrad_hash_entry_t **buckets;
-
+       
        buckets = malloc(sizeof(*buckets) * GROW_FACTOR * ht->num_buckets);
        if (!buckets) return;
 
@@ -377,10 +379,10 @@ static void lrad_hash_table_grow(lrad_hash_table_t *ht)
               sizeof(*buckets) * ht->num_buckets);
        memset(&buckets[ht->num_buckets], 0,
               sizeof(*buckets) * ht->num_buckets);
-
+       
        free(ht->buckets);
        ht->buckets = buckets;
-       ht->num_buckets *= GROW_FACTOR;
+       ht->num_buckets *= GROW_FACTOR; 
        ht->next_grow *= GROW_FACTOR;
        ht->mask = ht->num_buckets - 1;
 #ifdef TESTING
@@ -562,9 +564,9 @@ void lrad_hash_table_free(lrad_hash_table_t *ht)
                                         node != &ht->null;
                                         node = next) {
                        next = node->next;
-
+                       
                        if (!node->data) continue; /* dummy entry */
-
+                       
                        if (ht->free) ht->free(node->data);
                        free(node);
                }
@@ -854,7 +856,7 @@ int main(int argc, char **argv)
                                fprintf(stderr, "Failed finding %d\n", i);
                                exit(1);
                        }
-
+                       
 #if 0
                        if (!lrad_hash_table_delete(ht, &i)) {
                                fprintf(stderr, "Failed deleting %d\n", i);
index d649f1a..48a48ec 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
 /*
 ** Function: hmac_md5
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/md5.h>
+#include <string.h>
+#include "md5.h"
+#include "libradius.h"
 
 /*
 unsigned char*  text;                pointer to data stream
@@ -40,27 +38,27 @@ unsigned char*  digest;              caller digest to be filled in
 */
 
 void
-lrad_hmac_md5(const uint8_t *text, int text_len,
-             const uint8_t *key, int key_len,
-             uint8_t *digest)
+lrad_hmac_md5(const unsigned char *text, int text_len,
+             const unsigned char *key, int key_len,
+             unsigned char *digest)
 {
-        lrad_MD5_CTX context;
-        uint8_t k_ipad[65];    /* inner padding -
+        MD5_CTX context;
+        unsigned char k_ipad[65];    /* inner padding -
                                       * key XORd with ipad
                                       */
-        uint8_t k_opad[65];    /* outer padding -
+        unsigned char k_opad[65];    /* outer padding -
                                       * key XORd with opad
                                       */
-        uint8_t tk[16];
+        unsigned char tk[16];
         int i;
         /* if key is longer than 64 bytes reset it to key=MD5(key) */
         if (key_len > 64) {
 
-               lrad_MD5_CTX      tctx;
+                MD5_CTX      tctx;
 
-                lrad_MD5Init(&tctx);
-                lrad_MD5Update(&tctx, key, key_len);
-                lrad_MD5Final(tk, &tctx);
+                MD5Init(&tctx);
+                MD5Update(&tctx, key, key_len);
+                MD5Final(tk, &tctx);
 
                 key = tk;
                 key_len = 16;
@@ -92,20 +90,20 @@ lrad_hmac_md5(const uint8_t *text, int text_len,
         /*
          * perform inner MD5
          */
-        lrad_MD5Init(&context);                   /* init context for 1st
+        MD5Init(&context);                   /* init context for 1st
                                               * pass */
-        lrad_MD5Update(&context, k_ipad, 64);      /* start with inner pad */
-        lrad_MD5Update(&context, text, text_len); /* then text of datagram */
-        lrad_MD5Final(digest, &context);          /* finish up 1st pass */
+        MD5Update(&context, k_ipad, 64);      /* start with inner pad */
+        MD5Update(&context, text, text_len); /* then text of datagram */
+        MD5Final(digest, &context);          /* finish up 1st pass */
         /*
          * perform outer MD5
          */
-        lrad_MD5Init(&context);                   /* init context for 2nd
+        MD5Init(&context);                   /* init context for 2nd
                                               * pass */
-        lrad_MD5Update(&context, k_opad, 64);     /* start with outer pad */
-        lrad_MD5Update(&context, digest, 16);     /* then results of 1st
+        MD5Update(&context, k_opad, 64);     /* start with outer pad */
+        MD5Update(&context, digest, 16);     /* then results of 1st
                                               * hash */
-        lrad_MD5Final(digest, &context);          /* finish up 2nd pass */
+        MD5Final(digest, &context);          /* finish up 2nd pass */
 }
 
 /*
@@ -141,11 +139,12 @@ Test Vectors (Trailing '\0' of a character string not included in test):
  *  ./hmac Jefe "what do ya want for nothing?"
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 
 int main(int argc, char **argv)
 {
-  uint8_t digest[16];
+  unsigned char digest[16];
   char *key;
   int key_len;
   char *text;
index c80d366..ba45a9d 100644 (file)
@@ -8,19 +8,19 @@
 ** Function: hmac_sha1
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/sha1.h>
+#include "autoconf.h"
 
+#include <string.h>
+#include <sys/types.h>
+#include "libradius.h"
+#include "sha1.h"
 
 /*
-uint8_t*  text;                pointer to data stream
+unsigned char*  text;                pointer to data stream
 int             text_len;            length of data stream
-uint8_t*  key;                 pointer to authentication key
+unsigned char*  key;                 pointer to authentication key
 int             key_len;             length of authentication key
-uint8_t*  digest;              caller digest to be filled in
+unsigned char*  digest;              caller digest to be filled in
 */
 
 #ifdef HMAC_SHA1_DATA_PROBLEMS
@@ -28,18 +28,18 @@ unsigned int sha1_data_problems = 0;
 #endif
 
 void
-lrad_hmac_sha1(const uint8_t *text, int text_len,
-              const uint8_t *key, int key_len,
-              uint8_t *digest)
+lrad_hmac_sha1(const unsigned char *text, int text_len,
+              const unsigned char *key, int key_len,
+              unsigned char *digest)
 {
         SHA1_CTX context;
-        uint8_t k_ipad[65];    /* inner padding -
+        unsigned char k_ipad[65];    /* inner padding -
                                       * key XORd with ipad
                                       */
-        uint8_t k_opad[65];    /* outer padding -
+        unsigned char k_opad[65];    /* outer padding -
                                       * key XORd with opad
                                       */
-        uint8_t tk[20];
+        unsigned char tk[20];
         int i;
         /* if key is longer than 64 bytes reset it to key=SHA1(key) */
         if (key_len > 64) {
@@ -161,7 +161,7 @@ Test Vectors (Trailing '\0' of a character string not included in test):
   key =         "Jefe"
   data =        "what do ya want for nothing?"
   data_len =    28 bytes
-  digest =     effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
+  digest =
 
   key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 
@@ -177,16 +177,17 @@ Test Vectors (Trailing '\0' of a character string not included in test):
 
 #ifdef TESTING
 /*
- *  cc -DTESTING -I ../include/ hmac.c sha1.c -o hmac
+ *  cc -DTESTING -I ../include/ hmac.c md5.c -o hmac
  *
  *  ./hmac Jefe "what do ya want for nothing?"
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 
 int main(int argc, char **argv)
 {
-  uint8_t digest[20];
+  unsigned char digest[20];
   char *key;
   int key_len;
   char *text;
index ac92135..e19dc05 100644 (file)
@@ -10,10 +10,8 @@ MODIFIED:
 ------------------------------------------------------------------------------
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
+#include "autoconf.h"
+#include "libradius.h"
 
 #define RANDSIZL   (8)  /* I recommend 8 for crypto, 4 for simulations */
 #define RANDSIZ    (1<<RANDSIZL)
index 089220b..84d54b5 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/libradius.h>
+#include "autoconf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "libradius.h"
 
 char librad_errstr[1024];
 
index 64520d9..5610b42 100644 (file)
@@ -1,20 +1,18 @@
 /*
- *  md4c.c     MD4 message-digest algorithm
+ * md4c.c      MD4 message-digest algorithm
  *
- *  Version:   $Id$
+ * Version:    $Id$
  *
- *  This file is licensed under the LGPL, but is largely derived
- *  from public domain source code.
+ * This file is licensed under the LGPL, but is largely derived
+ * from public domain source code.
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
-
+/*#include "global.h"*/
 /*
  *  FORCE MD4 TO USE OUR MD4 HEADER FILE!
+ *
  *  If we don't do this, it might pick up the systems broken MD4.
+ *  - Paul Hampson, (cf Alan DeKok <aland@ox.org> in md5.c)
  */
 #include "../include/md4.h"
 
@@ -77,7 +75,7 @@ unsigned int inlen;                     /* length of input block */
  (((((uint32_t)x) & 0xff000000) >> 24) | \
  ((((uint32_t)x) & 0x00ff0000) >> 8) | \
  ((((uint32_t)x) & 0x0000ff00) << 8) | \
- ((((uint32_t)x) & 0x000000ff) << 24))
+ ((((uint32_t)x) & 0x000000ff) << 24)) 
 
 #define htole32_4(buf) do {                                            \
        (buf)[ 0] = htole32((buf)[ 0]);                                 \
@@ -189,7 +187,7 @@ MD4Update(MD4_CTX *ctx, const unsigned char *buf, size_t len)
 }
 
 /*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
  * 1 0* (64-bit count of bits processed, MSB-first)
  */
 void
index eae4c70..1f2a94d 100644 (file)
@@ -1,31 +1,28 @@
-/*
- *  md5.c      MD5 message-digest algorithm
- *
- *  Version:   $Id$
- *
- *  This file is licensed under the LGPL, but is largely derived
- *  from public domain source code.
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+/* MD5 message-digest algorithm */
 
-#include <freeradius-devel/libradius.h>
+/* This file is licensed under the LGPL, but is largely derived from
+ * public domain source code
+ */
 
 /*
  *  FORCE MD5 TO USE OUR MD5 HEADER FILE!
+ *
  *  If we don't do this, it might pick up the systems broken MD5.
+ *  - Alan DeKok <aland@ox.org>
  */
 #include "../include/md5.h"
 
-void librad_md5_calc(uint8_t *output, const uint8_t *input,
+void librad_md5_calc(unsigned char *output, unsigned char *input,
+                    unsigned int inputlen);
+
+void librad_md5_calc(unsigned char *output, unsigned char *input,
                     unsigned int inlen)
 {
-       lrad_MD5_CTX    context;
+       MD5_CTX context;
 
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, input, inlen);
-       lrad_MD5Final(output, &context);
+       MD5Init(&context);
+       MD5Update(&context, input, inlen);
+       MD5Final(output, &context);
 }
 
 /*     The below was retrieved from
@@ -73,7 +70,7 @@ void librad_md5_calc(uint8_t *output, const uint8_t *input,
        (cp)[1] = (value) >> 8;                                         \
        (cp)[0] = (value); } while (0)
 
-static const uint8_t PADDING[MD5_BLOCK_LENGTH] = {
+static uint8_t PADDING[MD5_BLOCK_LENGTH] = {
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -84,7 +81,7 @@ static const uint8_t PADDING[MD5_BLOCK_LENGTH] = {
  * initialization constants.
  */
 void
-lrad_MD5Init(lrad_MD5_CTX *ctx)
+MD5Init(MD5_CTX *ctx)
 {
        ctx->count[0] = 0;
        ctx->count[1] = 0;
@@ -99,7 +96,7 @@ lrad_MD5Init(lrad_MD5_CTX *ctx)
  * of bytes.
  */
 void
-lrad_MD5Update(lrad_MD5_CTX *ctx, const unsigned char *input, size_t len)
+MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)
 {
        size_t have, need;
 
@@ -115,10 +112,12 @@ lrad_MD5Update(lrad_MD5_CTX *ctx, const unsigned char *input, size_t len)
        }
        ctx->count[1] += ((uint32_t)len >> 29);
 
+       
+
        if (len >= need) {
                if (have != 0) {
                        memcpy(ctx->buffer + have, input, need);
-                       lrad_MD5Transform(ctx->state, ctx->buffer);
+                       MD5Transform(ctx->state, ctx->buffer);
                        input += need;
                        len -= need;
                        have = 0;
@@ -126,7 +125,7 @@ lrad_MD5Update(lrad_MD5_CTX *ctx, const unsigned char *input, size_t len)
 
                /* Process data in MD5_BLOCK_LENGTH-byte chunks. */
                while (len >= MD5_BLOCK_LENGTH) {
-                       lrad_MD5Transform(ctx->state, input);
+                       MD5Transform(ctx->state, input);
                        input += MD5_BLOCK_LENGTH;
                        len -= MD5_BLOCK_LENGTH;
                }
@@ -142,7 +141,7 @@ lrad_MD5Update(lrad_MD5_CTX *ctx, const unsigned char *input, size_t len)
  * 1 0* (64-bit count of bits processed, MSB-first)
  */
 void
-lrad_MD5Final(uint8_t digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
+MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
 {
        uint8_t count[8];
        size_t padlen;
@@ -156,14 +155,14 @@ lrad_MD5Final(uint8_t digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
            ((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
        if (padlen < 1 + 8)
                padlen += MD5_BLOCK_LENGTH;
-       lrad_MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
-       lrad_MD5Update(ctx, count, 8);
+       MD5Update(ctx, PADDING, padlen - 8);            /* padlen - 8 <= 64 */
+       MD5Update(ctx, count, 8);
 
        if (digest != NULL) {
                for (i = 0; i < 4; i++)
                        PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
        }
-       memset(ctx, 0, sizeof(*ctx));   /* in case it's sensitive */
+       bzero(ctx, sizeof(*ctx));       /* in case it's sensitive */
 }
 
 
@@ -185,7 +184,7 @@ lrad_MD5Final(uint8_t digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
  * the data and converts bytes into longwords for this routine.
  */
 void
-lrad_MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_LENGTH])
+MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_LENGTH])
 {
        uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
 
index 2eed575..7865d7f 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] =
+"$Id$";
 
-#include       <freeradius-devel/libradius.h>
+#include       "autoconf.h"
 
+#include       <stdio.h>
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <netinet/in.h>
+#include       <arpa/inet.h>
+
+#include       <stdlib.h>
+#include       <string.h>
+#include       <netdb.h>
 #include       <ctype.h>
 #include       <sys/file.h>
 #include       <fcntl.h>
+#include       <unistd.h>
+
+#include       "libradius.h"
+#include       "missing.h"
 
 int            librad_dodns = 0;
 int            librad_debug = 0;
 
 
 /*
+ *     Return a printable host name (or IP address in dot notation)
+ *     for the supplied IP address.
+ */
+char * ip_hostname(char *buf, size_t buflen, uint32_t ipaddr)
+{
+       struct          hostent *hp;
+#ifdef GETHOSTBYADDRRSTYLE
+#if (GETHOSTBYADDRRSTYLE == SYSVSTYLE) || (GETHOSTBYADDRRSTYLE == GNUSTYLE)
+       char buffer[2048];
+       struct hostent result;
+       int error;
+#endif
+#endif
+
+       /*
+        *      No DNS: don't look up host names
+        */
+       if (librad_dodns == 0) {
+               ip_ntoa(buf, ipaddr);
+               return buf;
+       }
+
+#ifdef GETHOSTBYADDRRSTYLE
+#if GETHOSTBYADDRRSTYLE == SYSVSTYLE
+       hp = gethostbyaddr_r((char *)&ipaddr, sizeof(struct in_addr), AF_INET, &result, buffer, sizeof(buffer), &error);
+#elif GETHOSTBYADDRRSTYLE == GNUSTYLE
+       if (gethostbyaddr_r((char *)&ipaddr, sizeof(struct in_addr),
+                           AF_INET, &result, buffer, sizeof(buffer),
+                           &hp, &error) != 0) {
+               hp = NULL;
+       }
+#else
+       hp = gethostbyaddr((char *)&ipaddr, sizeof(struct in_addr), AF_INET);
+#endif
+#else
+       hp = gethostbyaddr((char *)&ipaddr, sizeof(struct in_addr), AF_INET);
+#endif
+       if ((hp == NULL) ||
+           (strlen((char *)hp->h_name) >= buflen)) {
+               ip_ntoa(buf, ipaddr);
+               return buf;
+       }
+
+       strNcpy(buf, (char *)hp->h_name, buflen);
+       return buf;
+}
+
+
+/*
+ *     Return an IP address from a host
+ *     name or address in dot notation.
+ */
+uint32_t ip_getaddr(const char *host)
+{
+       struct hostent  *hp;
+       uint32_t         a;
+#ifdef GETHOSTBYNAMERSTYLE
+#if (GETHOSTBYNAMERSTYLE == SYSVSTYLE) || (GETHOSTBYNAMERSTYLE == GNUSTYLE)
+       struct hostent result;
+       int error;
+       char buffer[2048];
+#endif
+#endif
+
+       if ((a = ip_addr(host)) != htonl(INADDR_NONE))
+               return a;
+
+#ifdef GETHOSTBYNAMERSTYLE
+#if GETHOSTBYNAMERSTYLE == SYSVSTYLE
+       hp = gethostbyname_r(host, &result, buffer, sizeof(buffer), &error);
+#elif GETHOSTBYNAMERSTYLE == GNUSTYLE
+       if (gethostbyname_r(host, &result, buffer, sizeof(buffer),
+                           &hp, &error) != 0) {
+               return htonl(INADDR_NONE);
+       }
+#else
+       hp = gethostbyname(host);
+#endif
+#else
+       hp = gethostbyname(host);
+#endif
+       if (hp == NULL) {
+               return htonl(INADDR_NONE);
+       }
+
+       /*
+        *      Paranoia from a Bind vulnerability.  An attacker
+        *      can manipulate DNS entries to change the length of the
+        *      address.  If the length isn't 4, something's wrong.
+        */
+       if (hp->h_length != 4) {
+               return htonl(INADDR_NONE);
+       }
+
+       memcpy(&a, hp->h_addr, sizeof(uint32_t));
+       return a;
+}
+
+
+/*
  *     Return an IP address in standard dot notation
- *
- *     FIXME: DELETE THIS
  */
-const char *ip_ntoa(char *buffer, uint32_t ipaddr)
+char *ip_ntoa(char *buffer, uint32_t ipaddr)
 {
        ipaddr = ntohl(ipaddr);
 
@@ -51,6 +162,63 @@ const char *ip_ntoa(char *buffer, uint32_t ipaddr)
 }
 
 
+/*
+ *     Return an IP address from
+ *     one supplied in standard dot notation.
+ */
+uint32_t ip_addr(const char *ip_str)
+{
+       struct in_addr  in;
+
+       if (inet_aton(ip_str, &in) == 0)
+               return htonl(INADDR_NONE);
+       return in.s_addr;
+}
+
+
+/*
+ *     Like strncpy, but always adds \0
+ */
+char *strNcpy(char *dest, const char *src, int n)
+{
+       char *p = dest;
+
+       while ((n > 1) && (*src)) {
+               *(p++) = *(src++);
+
+               n--;
+       }
+       *p = '\0';
+
+       return dest;
+}
+
+/*
+ * Lowercase a string
+ */
+void rad_lowercase(char *str) {
+       char *s;
+
+       for (s=str; *s; s++)
+               if (isupper((int) *s)) *s = tolower((int) *s);
+}
+
+/*
+ * Remove spaces from a string
+ */
+void rad_rmspace(char *str) {
+       char *s = str;
+       char *ptr = str;
+
+  while(ptr && *ptr!='\0') {
+    while(isspace((int) *ptr))
+      ptr++;
+    *s = *ptr;
+    ptr++;
+    s++;
+  }
+  *s = '\0';
+}
 
 /*
  *     Internal wrapper for locking, to minimize the number of ifdef's
@@ -178,330 +346,87 @@ uint8_t *ifid_aton(const char *ifid_str, uint8_t *ifid)
        }
        return ifid;
 }
-
-
-#ifndef HAVE_INET_PTON
-static int inet_pton4(const char *src, struct in_addr *dst)
-{
-       int octet;
-       unsigned int num;
-       const char *p, *off;
-       uint8_t tmp[4];
-       static const char digits[] = "0123456789";
-
-       octet = 0;
-       p = src;
-       while (1) {
-               num = 0;
-               while (*p && ((off = strchr(digits, *p)) != NULL)) {
-                       num *= 10;
-                       num += (off - digits);
-
-                       if (num > 255) return 0;
-
-                       p++;
-               }
-               if (!*p) break;
-
-               /*
-                *      Not a digit, MUST be a dot, else we
-                *      die.
-                */
-               if (*p != '.') {
-                       return 0;
-               }
-
-               tmp[octet++] = num;
-               p++;
-       }
-
-       /*
-        *      End of the string.  At the fourth
-        *      octet is OK, anything else is an
-        *      error.
-        */
-       if (octet != 3) {
-               return 0;
-       }
-       tmp[3] = num;
-
-       memcpy(dst, &tmp, sizeof(tmp));
-       return 1;
-}
-
-
-/* int
- * inet_pton6(src, dst)
- *     convert presentation level address to network order binary form.
- * return:
- *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *     (1) does not touch `dst' unless it's returning 1.
- *     (2) :: in a full address is silently ignored.
- * credit:
- *     inspired by Mark Andrews.
- * author:
- *     Paul Vixie, 1996.
- */
-static int
-inet_pton6(const char *src, unsigned char *dst)
-{
-       static const char xdigits_l[] = "0123456789abcdef",
-                         xdigits_u[] = "0123456789ABCDEF";
-       u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
-       const char *xdigits, *curtok;
-       int ch, saw_xdigit;
-       u_int val;
-
-       memset((tp = tmp), 0, IN6ADDRSZ);
-       endp = tp + IN6ADDRSZ;
-       colonp = NULL;
-       /* Leading :: requires some special handling. */
-       if (*src == ':')
-               if (*++src != ':')
-                       return (0);
-       curtok = src;
-       saw_xdigit = 0;
-       val = 0;
-       while ((ch = *src++) != '\0') {
-               const char *pch;
-
-               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-                       pch = strchr((xdigits = xdigits_u), ch);
-               if (pch != NULL) {
-                       val <<= 4;
-                       val |= (pch - xdigits);
-                       if (val > 0xffff)
-                               return (0);
-                       saw_xdigit = 1;
-                       continue;
-               }
-               if (ch == ':') {
-                       curtok = src;
-                       if (!saw_xdigit) {
-                               if (colonp)
-                                       return (0);
-                               colonp = tp;
-                               continue;
-                       }
-                       if (tp + INT16SZ > endp)
-                               return (0);
-                       *tp++ = (u_char) (val >> 8) & 0xff;
-                       *tp++ = (u_char) val & 0xff;
-                       saw_xdigit = 0;
-                       val = 0;
-                       continue;
-               }
-               if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
-                   inet_pton4(curtok, tp) > 0) {
-                       tp += INADDRSZ;
-                       saw_xdigit = 0;
-                       break;  /* '\0' was seen by inet_pton4(). */
-               }
-               return (0);
-       }
-       if (saw_xdigit) {
-               if (tp + INT16SZ > endp)
-                       return (0);
-               *tp++ = (u_char) (val >> 8) & 0xff;
-               *tp++ = (u_char) val & 0xff;
-       }
-       if (colonp != NULL) {
-               /*
-                * Since some memmove()'s erroneously fail to handle
-                * overlapping regions, we'll do the shift by hand.
-                */
-               const int n = tp - colonp;
-               int i;
-
-               for (i = 1; i <= n; i++) {
-                       endp[- i] = colonp[n - i];
-                       colonp[n - i] = 0;
-               }
-               tp = endp;
-       }
-       if (tp != endp)
-               return (0);
-       /* bcopy(tmp, dst, IN6ADDRSZ); */
-       memcpy(dst, tmp, IN6ADDRSZ);
-       return (1);
-}
-
-/*
- *     Utility function, so that the rest of the server doesn't
- *     have ifdef's around IPv6 support
- */
-int inet_pton(int af, const char *src, void *dst)
-{
-       if (af == AF_INET) {
-               return inet_pton4(src, dst);
-       }
-
-       if (af == AF_INET6) {
-               return inet_pton6(src, dst);
-       }
-
-       return -1;
-}
-#endif
-
-
-#ifndef HAVE_INET_NTOP
 /*
- *     Utility function, so that the rest of the server doesn't
- *     have ifdef's around IPv6 support
+ *     Return an IPv6 address in standard colon notation
  */
-const char *inet_ntop(int af, const void *src, char *dst, size_t cnt)
+const char *ipv6_ntoa(char *buffer, size_t size, void *ip6addr)
 {
-       if (af == AF_INET) {
-               const uint8_t *ipaddr = src;
-
-               if (cnt <= INET_ADDRSTRLEN) return NULL;
-
-               snprintf(dst, cnt, "%d.%d.%d.%d",
-                        ipaddr[0], ipaddr[1],
-                        ipaddr[2], ipaddr[3]);
-               return dst;
-       }
-
+#if defined(HAVE_INET_NTOP) && defined(AF_INET6)
+       return inet_ntop(AF_INET6, (struct in6_addr *) ip6addr, buffer, size);
+#else
        /*
-        *      If the system doesn't define this, we define it
-        *      in missing.h
+        *      Do it really stupidly.
         */
-       if (af == AF_INET6) {
-               const struct in6_addr *ipaddr = src;
-
-               if (cnt <= INET6_ADDRSTRLEN) return NULL;
-
-               snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x",
-                        (ipaddr->s6_addr[0] << 8) | ipaddr->s6_addr[1],
-                        (ipaddr->s6_addr[2] << 8) | ipaddr->s6_addr[3],
-                        (ipaddr->s6_addr[4] << 8) | ipaddr->s6_addr[5],
-                        (ipaddr->s6_addr[6] << 8) | ipaddr->s6_addr[7],
-                        (ipaddr->s6_addr[8] << 8) | ipaddr->s6_addr[9],
-                        (ipaddr->s6_addr[10] << 8) | ipaddr->s6_addr[11],
-                        (ipaddr->s6_addr[12] << 8) | ipaddr->s6_addr[13],
-                        (ipaddr->s6_addr[14] << 8) | ipaddr->s6_addr[15]);
-               return dst;
-       }
-
-       return NULL;            /* don't support IPv6 */
-}
+       snprintf(buffer, size, "%x:%x:%x:%x:%x:%x:%x:%x",
+                (((uint8_t *) ip6addr)[0] << 8) | ((uint8_t *) ip6addr)[1],
+                (((uint8_t *) ip6addr)[2] << 8) | ((uint8_t *) ip6addr)[3],
+                (((uint8_t *) ip6addr)[4] << 8) | ((uint8_t *) ip6addr)[5],
+                (((uint8_t *) ip6addr)[6] << 8) | ((uint8_t *) ip6addr)[7],
+                (((uint8_t *) ip6addr)[8] << 8) | ((uint8_t *) ip6addr)[9],
+                (((uint8_t *) ip6addr)[10] << 8) | ((uint8_t *) ip6addr)[11],
+                (((uint8_t *) ip6addr)[12] << 8) | ((uint8_t *) ip6addr)[13],
+                (((uint8_t *) ip6addr)[14] << 8) | ((uint8_t *) ip6addr)[15]);
+       return buffer;
 #endif
+}
 
 
 /*
- *     Wrappers for IPv4/IPv6 host to IP address lookup.
- *     This API returns only one IP address, of the specified
- *     address family, or the first address (of whatever family),
- *     if AF_UNSPEC is used.
+ *     Return an IPv6 address from
+ *     one supplied in standard colon notation.
  */
-int ip_hton(const char *src, int af, lrad_ipaddr_t *dst)
+int ipv6_addr(const char *ip6_str, void *ip6addr)
 {
-       int error;
-       struct addrinfo hints, *ai = NULL, *res = NULL;
-
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_family = af;
-
-       if ((error = getaddrinfo(src, NULL, &hints, &res)) != 0) {
-               librad_log("ip_nton: %s", gai_strerror(error));
-               return -1;
-       }
-
-       for (ai = res; ai; ai = ai->ai_next) {
-               if ((af == ai->ai_family) || (af == AF_UNSPEC))
-                       break;
-       }
-
-       if (!ai) {
-               librad_log("ip_hton failed to find requested information for host %.100s", src);
-               freeaddrinfo(ai);
+#if defined(HAVE_INET_PTON) && defined(AF_INET6)
+       if (inet_pton(AF_INET6, ip6_str, (struct in6_addr *) ip6addr) != 1)
                return -1;
-       }
-
-       switch (ai->ai_family) {
-       case AF_INET :
-               dst->af = AF_INET;
-               memcpy(&dst->ipaddr,
-                      &((struct sockaddr_in*)ai->ai_addr)->sin_addr,
-                      sizeof(struct in_addr));
-               break;
-
-       case AF_INET6 :
-               dst->af = AF_INET6;
-               memcpy(&dst->ipaddr,
-                      &((struct sockaddr_in6*)ai->ai_addr)->sin6_addr,
-                      sizeof(struct in6_addr));
-               break;
-
-               /* Flow should never reach here */
-       case AF_UNSPEC :
-       default :
-               librad_log("ip_hton found unusable information for host %.100s", src);
-               freeaddrinfo(ai);
-               return -1;
-       }
-
-       freeaddrinfo(ai);
-       return 0;
-}
-
-/*
- *     Look IP addreses up, and print names (depending on DNS config)
- */
-const char *ip_ntoh(const lrad_ipaddr_t *src, char *dst, size_t cnt)
-{
-       struct sockaddr_storage ss;
-       struct sockaddr_in  *s4;
-       int error, len;
-
+#else
        /*
-        *      No DNS lookups
+        *      Copied from the 'ifid' code above, with minor edits.
         */
-       if (!librad_dodns) {
-               return inet_ntop(src->af, &(src->ipaddr), dst, cnt);
-       }
-
-
-       memset(&ss, 0, sizeof(ss));
-        switch (src->af) {
-        case AF_INET :
-                s4 = (struct sockaddr_in *)&ss;
-                len    = sizeof(struct sockaddr_in);
-                s4->sin_family = AF_INET;
-                s4->sin_port = 0;
-                memcpy(&s4->sin_addr, &src->ipaddr.ip4addr, 4);
-                break;
-
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
-        case AF_INET6 :
-               {
-               struct sockaddr_in6 *s6;
-
-                s6 = (struct sockaddr_in6 *)&ss;
-                len    = sizeof(struct sockaddr_in6);
-                s6->sin6_family = AF_INET6;
-                s6->sin6_flowinfo = 0;
-                s6->sin6_port = 0;
-                memcpy(&s6->sin6_addr, &src->ipaddr.ip6addr, 16);
-                break;
-               }
-#endif
+       static const char xdigits[] = "0123456789abcdef";
+       const char *p, *pch;
+       int num_id = 0, val = 0, idx = 0;
+       uint8_t *addr = ip6addr;
 
-        default :
-                return NULL;
-        }
+       for (p = ip6_str; ; ++p) {
+               if (*p == ':' || *p == '\0') {
+                       if (num_id <= 0)
+                               return -1;
 
-       if ((error = getnameinfo((struct sockaddr *)&ss, len, dst, cnt, NULL, 0,
-                                NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
-               librad_log("ip_ntoh: %s", gai_strerror(error));
-               return NULL;
+                       /*
+                        *      Drop 'val' into the array.
+                        */
+                       addr[idx] = (val >> 8) & 0xff;
+                       addr[idx + 1] = val & 0xff;
+                       if (*p == '\0') {
+                               /*
+                                *      Must have all entries before
+                                *      end of the string.
+                                */
+                               if (idx != 14)
+                                       return -1;
+                               break;
+                       }
+                       val = 0;
+                       num_id = 0;
+                       if ((idx += 2) > 14)
+                               return -1;
+               } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
+                       if (++num_id > 8) /* no more than 8 16-bit numbers */
+                               return -1;
+                       /*
+                        *      Dumb version of 'scanf'
+                        */
+                       val <<= 4;
+                       val |= (pch - xdigits);
+               } else
+                       return -1;
        }
-       return dst;
+#endif
+       return 0;
 }
 
-
 static const char *hextab = "0123456789abcdef";
 
 /*
@@ -544,7 +469,6 @@ void lrad_bin2hex(const uint8_t *bin, char *hex, int len)
        return;
 }
 
-
 /*
  *     So we don't have ifdef's in the rest of the code
  */
@@ -575,28 +499,3 @@ int closefrom(int fd)
        return 0;
 }
 #endif
-
-int lrad_ipaddr_cmp(const lrad_ipaddr_t *a, const lrad_ipaddr_t *b)
-{
-       if (a->af < b->af) return -1;
-       if (a->af > b->af) return +1;
-
-       switch (a->af) {
-       case AF_INET:
-               return memcmp(&a->ipaddr.ip4addr,
-                             &b->ipaddr.ip4addr,
-                             sizeof(a->ipaddr.ip4addr));
-               break;
-
-       case AF_INET6:
-               return memcmp(&a->ipaddr.ip6addr,
-                             &b->ipaddr.ip6addr,
-                             sizeof(a->ipaddr.ip6addr));
-               break;
-
-       default:
-               break;
-       }
-
-       return -1;
-}
index 9c0c580..4ea562e 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/libradius.h>
+#include       "autoconf.h"
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <netinet/in.h>
+#include       <arpa/inet.h>
 #include       <ctype.h>
 
+#include       "libradius.h"
+#include       "missing.h"
+
 #ifndef HAVE_CRYPT
 char *crypt(char *key, char *salt)
 {
@@ -92,6 +100,19 @@ int inet_aton(char *cp, struct in_addr *inp)
 }
 #endif
 
+#ifndef HAVE_GETHOSTNAME
+int gethostname(char *name, int len)
+{
+       char            *h;
+
+       h = getenv("HOSTNAME");
+       if (!h || (strlen(h) + 1 > len))
+               return -1;
+       strcpy(name, h);
+       return 0;
+}
+#endif
+
 #ifndef HAVE_STRSEP
 /*
  *     Get next token from string *stringp, where tokens are
@@ -191,45 +212,3 @@ struct tm *gmtime_r(const time_t *l_clock, struct tm *result)
   return result;
 }
 #endif
-
-#ifndef HAVE_GETTIMEOFDAY
-#ifdef WIN32
-/*
- * Number of micro-seconds between the beginning of the Windows epoch
- * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
- *
- * This assumes all Win32 compilers have 64-bit support.
- */
-#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__WATCOMC__)
-#define DELTA_EPOCH_IN_USEC  11644473600000000Ui64
-#else
-#define DELTA_EPOCH_IN_USEC  11644473600000000ULL
-#endif
-
-static uint64_t filetime_to_unix_epoch (const FILETIME *ft)
-{
-       uint64_t res = (uint64_t) ft->dwHighDateTime << 32;
-
-       res |= ft->dwLowDateTime;
-       res /= 10;                   /* from 100 nano-sec periods to usec */
-       res -= DELTA_EPOCH_IN_USEC;  /* from Win epoch to Unix epoch */
-       return (res);
-}
-
-int gettimeofday (struct timeval *tv, UNUSED void *tz)
-{
-       FILETIME  ft;
-       uint64_t tim;
-
-       if (!tv) {
-               errno = EINVAL;
-               return (-1);
-       }
-        GetSystemTimeAsFileTime (&ft);
-        tim = filetime_to_unix_epoch (&ft);
-        tv->tv_sec  = (long) (tim / 1000000L);
-        tv->tv_usec = (long) (tim % 1000000L);
-        return (0);
-}
-#endif
-#endif
diff --git a/src/lib/packet.c b/src/lib/packet.c
deleted file mode 100644 (file)
index fca143a..0000000
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * packet.c    Generic packet manipulation functions.
- *
- * Version:    $Id$
- *
- *   This library is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU Lesser General Public
- *   License as published by the Free Software Foundation; either
- *   version 2.1 of the License, or (at your option) any later version.
- *
- *   This library is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *   Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public
- *   License along with this library; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2000-2006  The FreeRADIUS server project
- */
-
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/libradius.h>
-
-#ifdef WITH_UDPFROMTO
-#include       <freeradius-devel/udpfromto.h>
-#endif
-
-/*
- *     Take the key fields of a request packet, and convert it to a
- *     hash.
- */
-uint32_t lrad_request_packet_hash(const RADIUS_PACKET *packet)
-{
-       uint32_t hash;
-
-       if (packet->hash) return packet->hash;
-
-       hash = lrad_hash(&packet->sockfd, sizeof(packet->sockfd));
-       hash = lrad_hash_update(&packet->src_port, sizeof(packet->src_port),
-                               hash);
-       hash = lrad_hash_update(&packet->dst_port,
-                               sizeof(packet->dst_port), hash);
-       hash = lrad_hash_update(&packet->src_ipaddr.af,
-                               sizeof(packet->src_ipaddr.af), hash);
-
-       /*
-        *      The caller ensures that src & dst AF are the same.
-        */
-       switch (packet->src_ipaddr.af) {
-       case AF_INET:
-               hash = lrad_hash_update(&packet->src_ipaddr.ipaddr.ip4addr,
-                                       sizeof(packet->src_ipaddr.ipaddr.ip4addr),
-                                       hash);
-               hash = lrad_hash_update(&packet->dst_ipaddr.ipaddr.ip4addr,
-                                       sizeof(packet->dst_ipaddr.ipaddr.ip4addr),
-                                       hash);
-               break;
-       case AF_INET6:
-               hash = lrad_hash_update(&packet->src_ipaddr.ipaddr.ip6addr,
-                                       sizeof(packet->src_ipaddr.ipaddr.ip6addr),
-                                       hash);
-               hash = lrad_hash_update(&packet->dst_ipaddr.ipaddr.ip6addr,
-                                       sizeof(packet->dst_ipaddr.ipaddr.ip6addr),
-                                       hash);
-               break;
-       default:
-               break;
-       }
-
-       return lrad_hash_update(&packet->id, sizeof(packet->id), hash);
-}
-
-
-/*
- *     Take the key fields of a reply packet, and convert it to a
- *     hash.
- *
- *     i.e. take a reply packet, and find the hash of the request packet
- *     that asked for the reply.  To do this, we hash the reverse fields
- *     of the request.  e.g. where the request does (src, dst), we do
- *     (dst, src)
- */
-uint32_t lrad_reply_packet_hash(const RADIUS_PACKET *packet)
-{
-       uint32_t hash;
-
-       hash = lrad_hash(&packet->sockfd, sizeof(packet->sockfd));
-       hash = lrad_hash_update(&packet->id, sizeof(packet->id), hash);
-       hash = lrad_hash_update(&packet->src_port, sizeof(packet->src_port),
-                               hash);
-       hash = lrad_hash_update(&packet->dst_port,
-                               sizeof(packet->dst_port), hash);
-       hash = lrad_hash_update(&packet->src_ipaddr.af,
-                               sizeof(packet->src_ipaddr.af), hash);
-
-       /*
-        *      The caller ensures that src & dst AF are the same.
-        */
-       switch (packet->src_ipaddr.af) {
-       case AF_INET:
-               hash = lrad_hash_update(&packet->dst_ipaddr.ipaddr.ip4addr,
-                                       sizeof(packet->dst_ipaddr.ipaddr.ip4addr),
-                                       hash);
-               hash = lrad_hash_update(&packet->src_ipaddr.ipaddr.ip4addr,
-                                       sizeof(packet->src_ipaddr.ipaddr.ip4addr),
-                                       hash);
-               break;
-       case AF_INET6:
-               hash = lrad_hash_update(&packet->dst_ipaddr.ipaddr.ip6addr,
-                                       sizeof(packet->dst_ipaddr.ipaddr.ip6addr),
-                                       hash);
-               hash = lrad_hash_update(&packet->src_ipaddr.ipaddr.ip6addr,
-                                       sizeof(packet->src_ipaddr.ipaddr.ip6addr),
-                                       hash);
-               break;
-       default:
-               break;
-       }
-
-       return lrad_hash_update(&packet->id, sizeof(packet->id), hash);
-}
-
-
-/*
- *     See if two packets are identical.
- *
- *     Note that we do NOT compare the authentication vectors.
- *     That's because if the authentication vector is different,
- *     it means that the NAS has given up on the earlier request.
- */
-int lrad_packet_cmp(const RADIUS_PACKET *a, const RADIUS_PACKET *b)
-{
-       int rcode;
-
-       if (a->sockfd < b->sockfd) return -1;
-       if (a->sockfd > b->sockfd) return +1;
-
-       if (a->id < b->id) return -1;
-       if (a->id > b->id) return +1;
-
-       if (a->src_port < b->src_port) return -1;
-       if (a->src_port > b->src_port) return +1;
-
-       if (a->dst_port < b->dst_port) return -1;
-       if (a->dst_port > b->dst_port) return +1;
-
-       rcode = lrad_ipaddr_cmp(&a->dst_ipaddr, &b->dst_ipaddr);
-       if (rcode != 0) return rcode;
-       return lrad_ipaddr_cmp(&a->src_ipaddr, &b->src_ipaddr);
-}
-
-
-/*
- *     Create a fake "request" from a reply, for later lookup.
- */
-void lrad_request_from_reply(RADIUS_PACKET *request,
-                            const RADIUS_PACKET *reply)
-{
-       request->sockfd = reply->sockfd;
-       request->id = reply->id;
-       request->src_port = reply->dst_port;
-       request->dst_port = reply->src_port;
-       request->src_ipaddr = reply->dst_ipaddr;
-       request->dst_ipaddr = reply->src_ipaddr;
-}
-
-
-/*
- *     Open a socket on the given IP and port.
- */
-int lrad_socket(lrad_ipaddr_t *ipaddr, int port)
-{
-       int sockfd;
-       struct sockaddr_storage salocal;
-       socklen_t       salen;
-
-       if ((port < 0) || (port > 65535)) {
-               librad_log("Port %d is out of allowed bounds", port);
-               return -1;
-       }
-
-       sockfd = socket(ipaddr->af, SOCK_DGRAM, 0);
-       if (sockfd < 0) {
-               return sockfd;
-       }
-
-#ifdef WITH_UDPFROMTO
-       /*
-        *      Initialize udpfromto for all sockets.
-        */
-       if (udpfromto_init(sockfd) != 0) {
-               close(sockfd);
-               return -1;
-       }
-#endif
-
-       memset(&salocal, 0, sizeof(salocal));
-       if (ipaddr->af == AF_INET) {
-               struct sockaddr_in *sa;
-
-               sa = (struct sockaddr_in *) &salocal;
-               sa->sin_family = AF_INET;
-               sa->sin_addr = ipaddr->ipaddr.ip4addr;
-               sa->sin_port = htons((uint16_t) port);
-               salen = sizeof(*sa);
-
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
-       } else if (ipaddr->af == AF_INET6) {
-               struct sockaddr_in6 *sa;
-
-               sa = (struct sockaddr_in6 *) &salocal;
-               sa->sin6_family = AF_INET6;
-               sa->sin6_addr = ipaddr->ipaddr.ip6addr;
-               sa->sin6_port = htons((uint16_t) port);
-               salen = sizeof(*sa);
-
-#if 1
-               /*
-                *      Listening on '::' does NOT get you IPv4 to
-                *      IPv6 mapping.  You've got to listen on an IPv4
-                *      address, too.  This makes the rest of the server
-                *      design a little simpler.
-                */
-#ifdef IPV6_V6ONLY
-
-               if (IN6_IS_ADDR_UNSPECIFIED(&ipaddr->ipaddr.ip6addr)) {
-                       int on = 1;
-
-                       setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
-                                  (char *)&on, sizeof(on));
-               }
-#endif /* IPV6_V6ONLY */
-#endif
-#endif /* HAVE_STRUCT_SOCKADDR_IN6 */
-       } else {
-               return sockfd;  /* don't bind it */
-       }
-
-       if (bind(sockfd, (struct sockaddr *) &salocal, salen) < 0) {
-               close(sockfd);
-               return -1;
-       }
-
-       return sockfd;
-}
-
-
-/*
- *     We need to keep track of the socket & it's IP/port.
- */
-typedef struct lrad_packet_socket_t {
-       int             sockfd;
-
-       int             num_outgoing;
-
-       int             offset; /* 0..31 */
-       int             inaddr_any;
-       lrad_ipaddr_t   ipaddr;
-       int             port;
-} lrad_packet_socket_t;
-
-
-#define FNV_MAGIC_PRIME (0x01000193)
-#define MAX_SOCKETS (32)
-#define SOCKOFFSET_MASK (MAX_SOCKETS - 1)
-#define SOCK2OFFSET(sockfd) ((sockfd * FNV_MAGIC_PRIME) & SOCKOFFSET_MASK)
-
-#define MAX_QUEUES (8)
-
-/*
- *     Structure defining a list of packets (incoming or outgoing)
- *     that should be managed.
- */
-struct lrad_packet_list_t {
-       lrad_hash_table_t *ht;
-
-       lrad_hash_table_t *dst2id_ht;
-
-       int             alloc_id;
-       int             num_outgoing;
-
-       uint32_t mask;
-       int last_recv;
-       lrad_packet_socket_t sockets[MAX_SOCKETS];
-};
-
-
-/*
- *     Ugh.  Doing this on every sent/received packet is not nice.
- */
-static lrad_packet_socket_t *lrad_socket_find(lrad_packet_list_t *pl,
-                                            int sockfd)
-{
-       int i, start;
-
-       i = start = SOCK2OFFSET(sockfd);
-
-       do {                    /* make this hack slightly more efficient */
-               if (pl->sockets[i].sockfd == sockfd) return &pl->sockets[i];
-
-               i = (i + 1) & SOCKOFFSET_MASK;
-       } while (i != start);
-
-       return NULL;
-}
-
-int lrad_packet_list_socket_remove(lrad_packet_list_t *pl, int sockfd)
-{
-       lrad_packet_socket_t *ps;
-
-       if (!pl) return 0;
-
-       ps = lrad_socket_find(pl, sockfd);
-       if (!ps) return 0;
-
-       /*
-        *      FIXME: Allow the caller forcibly discard these?
-        */
-       if (ps->num_outgoing != 0) return 0;
-
-       ps->sockfd = -1;
-       pl->mask &= ~(1 << ps->offset);
-
-
-       return 1;
-}
-
-int lrad_packet_list_socket_add(lrad_packet_list_t *pl, int sockfd)
-{
-       int i, start;
-       struct sockaddr_storage src;
-       socklen_t               sizeof_src = sizeof(src);
-       lrad_packet_socket_t    *ps;
-
-       if (!pl) return 0;
-
-       ps = NULL;
-       i = start = SOCK2OFFSET(sockfd);
-
-       do {
-               if (pl->sockets[i].sockfd == -1) {
-                       ps =  &pl->sockets[i];
-                       start = i;
-                       break;
-               }
-
-               i = (i + 1) & SOCKOFFSET_MASK;
-       } while (i != start);
-
-       if (!ps) {
-               return 0;
-       }
-
-       memset(ps, 0, sizeof(*ps));
-       ps->sockfd = sockfd;
-       ps->offset = start;
-
-       /*
-        *      Get address family, etc. first, so we know if we
-        *      need to do udpfromto.
-        *
-        *      FIXME: udpfromto also does this, but it's not
-        *      a critical problem.
-        */
-       memset(&src, 0, sizeof_src);
-       if (getsockname(sockfd, (struct sockaddr *) &src,
-                       &sizeof_src) < 0) {
-               return 0;
-       }
-
-       /*
-        *      Grab IP addresses & ports from the sockaddr.
-        */
-       ps->ipaddr.af = src.ss_family;
-       if (src.ss_family == AF_INET) {
-               struct sockaddr_in      *s4;
-
-               s4 = (struct sockaddr_in *)&src;
-               ps->ipaddr.ipaddr.ip4addr = s4->sin_addr;
-               ps->port = ntohs(s4->sin_port);
-
-               if (ps->ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY) {
-                       ps->inaddr_any = 1;
-               }
-
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
-       } else if (src.ss_family == AF_INET6) {
-               struct sockaddr_in6     *s6;
-
-               s6 = (struct sockaddr_in6 *)&src;
-               ps->ipaddr.ipaddr.ip6addr = s6->sin6_addr;
-               ps->port = ntohs(s6->sin6_port);
-
-               if (IN6_IS_ADDR_UNSPECIFIED(&ps->ipaddr.ipaddr.ip6addr)) {
-                       ps->inaddr_any = 1;
-               }
-#endif
-       } else {
-               return 0;
-       }
-
-       pl->mask |= (1 << ps->offset);
-       return 1;
-}
-
-static uint32_t packet_entry_hash(const void *data)
-{
-       return lrad_request_packet_hash(*(const RADIUS_PACKET * const *) data);
-}
-
-static int packet_entry_cmp(const void *one, const void *two)
-{
-       const RADIUS_PACKET * const *a = one;
-       const RADIUS_PACKET * const *b = two;
-
-       return lrad_packet_cmp(*a, *b);
-}
-
-/*
- *     A particular socket can have 256 RADIUS ID's outstanding to
- *     any one destination IP/port.  So we have a structure that
- *     manages destination IP & port, and has an array of 256 ID's.
- *
- *     The only magic here is that we map the socket number (0..256)
- *     into an "internal" socket number 0..31, that we use to set
- *     bits in the ID array.  If a bit is 1, then that ID is in use
- *     for that socket, and the request MUST be in the packet hash!
- *
- *     Note that as a minor memory leak, we don't have an API to free
- *     this structure, except when we discard the whole packet list.
- *     This means that if destinations are added and removed, they
- *     won't be removed from this tree.
- */
-typedef struct lrad_packet_dst2id_t {
-       lrad_ipaddr_t   dst_ipaddr;
-       int             dst_port;
-       uint32_t        id[1];  /* really id[256] */
-} lrad_packet_dst2id_t;
-
-
-static uint32_t packet_dst2id_hash(const void *data)
-{
-       uint32_t hash;
-       const lrad_packet_dst2id_t *pd = data;
-
-       hash = lrad_hash(&pd->dst_port, sizeof(pd->dst_port));
-
-       switch (pd->dst_ipaddr.af) {
-       case AF_INET:
-               hash = lrad_hash_update(&pd->dst_ipaddr.ipaddr.ip4addr,
-                                       sizeof(pd->dst_ipaddr.ipaddr.ip4addr),
-                                       hash);
-               break;
-       case AF_INET6:
-               hash = lrad_hash_update(&pd->dst_ipaddr.ipaddr.ip6addr,
-                                       sizeof(pd->dst_ipaddr.ipaddr.ip6addr),
-                                       hash);
-               break;
-       default:
-               break;
-       }
-
-       return hash;
-}
-
-static int packet_dst2id_cmp(const void *one, const void *two)
-{
-       const lrad_packet_dst2id_t *a = one;
-       const lrad_packet_dst2id_t *b = two;
-
-       if (a->dst_port < b->dst_port) return -1;
-       if (a->dst_port > b->dst_port) return +1;
-
-       return lrad_ipaddr_cmp(&a->dst_ipaddr, &b->dst_ipaddr);
-}
-
-static void packet_dst2id_free(void *data)
-{
-       free(data);
-}
-
-
-void lrad_packet_list_free(lrad_packet_list_t *pl)
-{
-       if (!pl) return;
-
-       lrad_hash_table_free(pl->ht);
-       lrad_hash_table_free(pl->dst2id_ht);
-       free(pl);
-}
-
-
-/*
- *     Caller is responsible for managing the packet entries.
- */
-lrad_packet_list_t *lrad_packet_list_create(int alloc_id)
-{
-       int i;
-       lrad_packet_list_t      *pl;
-
-       pl = malloc(sizeof(*pl));
-       if (!pl) return NULL;
-       memset(pl, 0, sizeof(*pl));
-
-       pl->ht = lrad_hash_table_create(packet_entry_hash,
-                                       packet_entry_cmp,
-                                       NULL);
-       if (!pl->ht) {
-               lrad_packet_list_free(pl);
-               return NULL;
-       }
-
-       for (i = 0; i < MAX_SOCKETS; i++) {
-               pl->sockets[i].sockfd = -1;
-       }
-
-       if (alloc_id) {
-               pl->alloc_id = 1;
-
-               pl->dst2id_ht = lrad_hash_table_create(packet_dst2id_hash,
-                                                      packet_dst2id_cmp,
-                                                      packet_dst2id_free);
-               if (!pl->dst2id_ht) {
-                       lrad_packet_list_free(pl);
-                       return NULL;
-               }
-       }
-
-       return pl;
-}
-
-
-/*
- *     If pl->alloc_id is set, then lrad_packet_list_id_alloc() MUST
- *     be called before inserting the packet into the list!
- */
-int lrad_packet_list_insert(lrad_packet_list_t *pl,
-                           RADIUS_PACKET **request_p)
-{
-       if (!pl || !request_p || !*request_p) return 0;
-
-       (*request_p)->hash = lrad_request_packet_hash(*request_p);
-
-       return lrad_hash_table_insert(pl->ht, request_p);
-}
-
-RADIUS_PACKET **lrad_packet_list_find(lrad_packet_list_t *pl,
-                                     RADIUS_PACKET *request)
-{
-       if (!pl || !request) return 0;
-
-       return lrad_hash_table_finddata(pl->ht, &request);
-}
-
-
-/*
- *     This presumes that the reply has dst_ipaddr && dst_port set up
- *     correctly (i.e. real IP, or "*").
- */
-RADIUS_PACKET **lrad_packet_list_find_byreply(lrad_packet_list_t *pl,
-                                             RADIUS_PACKET *reply)
-{
-       RADIUS_PACKET my_request, *request;
-       lrad_packet_socket_t *ps;
-
-       if (!pl || !reply) return NULL;
-
-       ps = lrad_socket_find(pl, reply->sockfd);
-       if (!ps) return NULL;
-
-       /*
-        *      Initialize request from reply, AND from the source
-        *      IP & port of this socket.  The client may have bound
-        *      the socket to 0, in which case it's some random port,
-        *      that is NOT in the original request->src_port.
-        */
-       my_request.sockfd = reply->sockfd;
-       my_request.id = reply->id;
-
-       if (ps->inaddr_any) {
-               my_request.src_ipaddr = ps->ipaddr;
-       } else {
-               my_request.src_ipaddr = reply->dst_ipaddr;
-       }
-       my_request.src_port = ps->port;;
-
-       my_request.dst_ipaddr = reply->src_ipaddr;
-       my_request.dst_port = reply->src_port;
-       my_request.hash = 0;
-
-       request = &my_request;
-
-       return lrad_hash_table_finddata(pl->ht, &request);
-}
-
-
-RADIUS_PACKET **lrad_packet_list_yank(lrad_packet_list_t *pl,
-                                     RADIUS_PACKET *request)
-{
-       if (!pl || !request) return NULL;
-
-       return lrad_hash_table_yank(pl->ht, &request);
-}
-
-int lrad_packet_list_num_elements(lrad_packet_list_t *pl)
-{
-       if (!pl) return 0;
-
-       return lrad_hash_table_num_elements(pl->ht);
-}
-
-
-/*
- *     1 == ID was allocated & assigned
- *     0 == error allocating memory
- *     -1 == all ID's are used, caller should open a new socket.
- *
- *     Note that this ALSO assigns a socket to use, and updates
- *     packet->request->src_ipaddr && packet->request->src_port
- *
- *     In multi-threaded systems, the calls to id_alloc && id_free
- *     should be protected by a mutex.  This does NOT have to be
- *     the same mutex as the one protecting the insert/find/yank
- *     calls!
- */
-int lrad_packet_list_id_alloc(lrad_packet_list_t *pl,
-                             RADIUS_PACKET *request)
-{
-       int i, id, start;
-       uint32_t free_mask;
-       lrad_packet_dst2id_t my_pd, *pd;
-       lrad_packet_socket_t *ps;
-
-       if (!pl || !pl->alloc_id || !request) return 0;
-
-       my_pd.dst_ipaddr = request->dst_ipaddr;
-       my_pd.dst_port = request->dst_port;
-
-       pd = lrad_hash_table_finddata(pl->dst2id_ht, &my_pd);
-       if (!pd) {
-               pd = malloc(sizeof(*pd) + 255 * sizeof(pd->id[0]));
-               if (!pd) return 0;
-
-               memset(pd, 0, sizeof(*pd) + 255 * sizeof(pd->id[0]));
-
-               pd->dst_ipaddr = request->dst_ipaddr;
-               pd->dst_port = request->dst_port;
-
-               if (!lrad_hash_table_insert(pl->dst2id_ht, pd)) {
-                       free(pd);
-                       return 0;
-               }
-       }
-
-       /*
-        *      FIXME: Go to an LRU system.  This prevents ID re-use
-        *      for as long as possible.  The main problem with that
-        *      approach is that it requires us to populate the
-        *      LRU/FIFO when we add a new socket, or a new destination,
-        *      which can be expensive.
-        *
-        *      The LRU can be avoided if the caller takes care to free
-        *      Id's only when all responses have been received, OR after
-        *      a timeout.
-        */
-       id = start = (int) lrad_rand() & 0xff;
-
-       while (pd->id[id] == pl->mask) { /* all sockets are using this ID */
-               id++;
-               id &= 0xff;
-               if (id == start) return 0;
-       }
-
-       free_mask = ~((~pd->id[id]) & pl->mask);
-
-       start = -1;
-       for (i = 0; i < MAX_SOCKETS; i++) {
-               if (pl->sockets[i].sockfd == -1) continue; /* paranoia */
-
-               if ((free_mask & (1 << i)) == 0) {
-                       start = i;
-                       break;
-               }
-       }
-
-       if (start < 0) return 0; /* bad error */
-
-       pd->id[id] |= (1 << start);
-       ps = &pl->sockets[start];
-
-       ps->num_outgoing++;
-       pl->num_outgoing++;
-
-       /*
-        *      Set the ID, source IP, and source port.
-        */
-       request->id = id;
-
-       request->sockfd = ps->sockfd;
-       request->src_ipaddr = ps->ipaddr;
-       request->src_port = ps->port;
-
-       return 1;
-}
-
-/*
- *     Should be called AFTER yanking it from the list, so that
- *     any newly inserted entries don't collide with this one.
- */
-int lrad_packet_list_id_free(lrad_packet_list_t *pl,
-                            RADIUS_PACKET *request)
-{
-       lrad_packet_socket_t *ps;
-       lrad_packet_dst2id_t my_pd, *pd;
-
-       if (!pl || !request) return 0;
-
-       ps = lrad_socket_find(pl, request->sockfd);
-       if (!ps) return 0;
-
-       my_pd.dst_ipaddr = request->dst_ipaddr;
-       my_pd.dst_port = request->dst_port;
-
-       pd = lrad_hash_table_finddata(pl->dst2id_ht, &my_pd);
-       if (!pd) return 0;
-
-       pd->id[request->id] &= ~(1 << ps->offset);
-       request->hash = 0;      /* invalidate the cached hash */
-
-       ps->num_outgoing--;
-       pl->num_outgoing--;
-
-       return 1;
-}
-
-int lrad_packet_list_walk(lrad_packet_list_t *pl, void *ctx,
-                         lrad_hash_table_walk_t callback)
-{
-       if (!pl || !callback) return 0;
-
-       return lrad_hash_table_walk(pl->ht, callback, ctx);
-}
-
-int lrad_packet_list_fd_set(lrad_packet_list_t *pl, fd_set *set)
-{
-       int i, maxfd;
-
-       if (!pl || !set) return 0;
-
-       maxfd = -1;
-
-       for (i = 0; i < MAX_SOCKETS; i++) {
-               if (pl->sockets[i].sockfd == -1) continue;
-               FD_SET(pl->sockets[i].sockfd, set);
-               if (pl->sockets[i].sockfd > maxfd) {
-                       maxfd = pl->sockets[i].sockfd;
-               }
-       }
-
-       if (maxfd < 0) return -1;
-
-       return maxfd + 1;
-}
-
-/*
- *     Round-robins the receivers, without priority.
- *
- *     FIXME: Add sockfd, if -1, do round-robin, else do sockfd
- *             IF in fdset.
- */
-RADIUS_PACKET *lrad_packet_list_recv(lrad_packet_list_t *pl, fd_set *set)
-{
-       int start;
-       RADIUS_PACKET *packet;
-
-       if (!pl || !set) return NULL;
-
-       start = pl->last_recv;
-       do {
-               start++;
-               start &= SOCKOFFSET_MASK;
-
-               if (pl->sockets[start].sockfd == -1) continue;
-
-               if (!FD_ISSET(pl->sockets[start].sockfd, set)) continue;
-
-               packet = rad_recv(pl->sockets[start].sockfd);
-               if (!packet) continue;
-
-               /*
-                *      Call lrad_packet_list_find_byreply().  If it
-                *      doesn't find anything, discard the reply.
-                */
-
-               pl->last_recv = start;
-               return packet;
-       } while (start != pl->last_recv);
-
-       return NULL;
-}
-
-int lrad_packet_list_num_incoming(lrad_packet_list_t *pl)
-{
-       int num_elements;
-
-       if (!pl) return 0;
-
-       num_elements = lrad_hash_table_num_elements(pl->ht);
-       if (num_elements < pl->num_outgoing) return 0; /* panic! */
-
-       return num_elements - pl->num_outgoing;
-}
-
-int lrad_packet_list_num_outgoing(lrad_packet_list_t *pl)
-{
-       if (!pl) return 0;
-
-       return pl->num_outgoing;
-}
index 611bf02..54959e1 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/libradius.h>
+#include       "autoconf.h"
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <sys/types.h>
 #include       <ctype.h>
+#include       <string.h>
+
+#include       "libradius.h"
 
 /*
  *     Convert a string to something printable.
@@ -64,11 +69,8 @@ void librad_safeprint(char *in, int inlen, char *out, int outlen)
                        case '\t':
                                sp = 't';
                                break;
-                       case '"':
-                               sp = '"';
-                               break;
                        default:
-                         if (*str < 32 || (*str >= 128)){
+                               if (*str < 32 || (*str >= 128)){
                                        snprintf(out, outlen, "\\%03o", *str);
                                        done += 4;
                                        out  += 4;
@@ -99,128 +101,108 @@ int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
 {
        DICT_VALUE  *v;
        char        buf[1024];
-       const char  *a = NULL;
-       size_t      len;
+       char        *a;
        time_t      t;
        struct tm   s_tm;
 
-       out[0] = '\0';
+       out[0] = 0;
        if (!vp) return 0;
 
        switch (vp->type) {
                case PW_TYPE_STRING:
-                       if ((delimitst == 1) && vp->flags.has_tag) {
-                               /* Tagged attribute: print delimter and ignore tag */
-                               buf[0] = '"';
-                               librad_safeprint((char *)(vp->vp_strvalue),
-                                                vp->length, buf + 1, sizeof(buf) - 2);
-                               strcat(buf, "\"");
-                       } else if (delimitst == 1) {
-                               /* Non-tagged attribute: print delimter */
-                               buf[0] = '"';
-                               librad_safeprint((char *)vp->vp_strvalue,
-                                                vp->length, buf + 1, sizeof(buf) - 2);
-                               strcat(buf, "\"");
-
-                       } else if (delimitst < 0) {
-                               strlcpy(out, vp->vp_strvalue, outlen);
-                               return strlen(out);
-
-                       } else {
-                               /* Non-tagged attribute: no delimiter */
-                               librad_safeprint((char *)vp->vp_strvalue,
-                                                vp->length, buf, sizeof(buf));
+                       /*
+                        *  NAS-Port may have multiple integer values?
+                        *  This is an internal server extension...
+                        */
+                       if (vp->attribute == PW_NAS_PORT)
+                               a = (char *)vp->strvalue;
+                       else {
+                               if (delimitst && vp->flags.has_tag) {
+                                       /* Tagged attribute: print delimter and ignore tag */
+                                       buf[0] = '"';
+                                       librad_safeprint((char *)(vp->strvalue),
+                                                        vp->length, buf + 1, sizeof(buf) - 2);
+                                       strcat(buf, "\"");
+                               } else if (delimitst) {
+                                       /* Non-tagged attribute: print delimter */
+                                       buf[0] = '"';
+                                       librad_safeprint((char *)vp->strvalue,
+                                                        vp->length, buf + 1, sizeof(buf) - 2);
+                                       strcat(buf, "\"");
+                               } else {
+                                       /* Non-tagged attribute: no delimiter */
+                                       librad_safeprint((char *)vp->strvalue,
+                                                        vp->length, buf, sizeof(buf));
+                               }
+                               a = buf;
                        }
-                       a = buf;
                        break;
                case PW_TYPE_INTEGER:
                        if ( vp->flags.has_tag ) {
                                /* Attribute value has a tag, need to ignore it */
-                               if ((v = dict_valbyattr(vp->attribute, (vp->vp_integer & 0xffffff)))
+                               if ((v = dict_valbyattr(vp->attribute, (vp->lvalue & 0xffffff)))
                                    != NULL)
                                        a = v->name;
                                else {
-                                       snprintf(buf, sizeof(buf), "%u", (vp->vp_integer & 0xffffff));
+                                       snprintf(buf, sizeof(buf), "%u", (vp->lvalue & 0xffffff));
                                        a = buf;
                                }
                        } else {
-                       case PW_TYPE_BYTE:
-                       case PW_TYPE_SHORT:
                                /* Normal, non-tagged attribute */
-                               if ((v = dict_valbyattr(vp->attribute, vp->vp_integer))
+                               if ((v = dict_valbyattr(vp->attribute, vp->lvalue))
                                    != NULL)
                                        a = v->name;
                                else {
-                                       snprintf(buf, sizeof(buf), "%u", vp->vp_integer);
+                                       snprintf(buf, sizeof(buf), "%u", vp->lvalue);
                                        a = buf;
                                }
                        }
                        break;
                case PW_TYPE_DATE:
-                       t = vp->vp_date;
+                       t = vp->lvalue;
                        if (delimitst) {
-                         len = strftime(buf, sizeof(buf), "\"%b %e %Y %H:%M:%S %Z\"",
-                                        localtime_r(&t, &s_tm));
+                         strftime(buf, sizeof(buf), "\"%b %e %Y %H:%M:%S %Z\"",
+                                  localtime_r(&t, &s_tm));
                        } else {
-                         len = strftime(buf, sizeof(buf), "%b %e %Y %H:%M:%S %Z",
-                                        localtime_r(&t, &s_tm));
+                         strftime(buf, sizeof(buf), "%b %e %Y %H:%M:%S %Z",
+                                  localtime_r(&t, &s_tm));
                        }
-                       if (len > 0) a = buf;
+                       a = buf;
                        break;
                case PW_TYPE_IPADDR:
-                       a = inet_ntop(AF_INET, &(vp->vp_ipaddr),
-                                     buf, sizeof(buf));
+                       a = ip_ntoa(buf, vp->lvalue);
                        break;
                case PW_TYPE_ABINARY:
 #ifdef ASCEND_BINARY
-                       a = buf;
-                       print_abinary(vp, buf, sizeof(buf));
-                       break;
+                 a = buf;
+                 print_abinary(vp, (unsigned char *)buf, sizeof(buf));
+                 break;
 #else
                  /* FALL THROUGH */
 #endif
                case PW_TYPE_OCTETS:
-                       if (outlen <= (2 * (vp->length + 1))) return 0;
-
-                       strcpy(buf, "0x");
-
-                       lrad_bin2hex(vp->vp_octets, buf + 2, vp->length);
-                       a = buf;
+                 strcpy(buf, "0x");
+                 a = buf + 2;
+                 for (t = 0; t < vp->length; t++) {
+                       sprintf(a, "%02x", vp->strvalue[t]);
+                       a += 2;
+                 }
+                 a = buf;
                  break;
 
                case PW_TYPE_IFID:
-                       a = ifid_ntoa(buf, sizeof(buf), vp->vp_octets);
+                       a = ifid_ntoa(buf, sizeof(buf), vp->strvalue);
                        break;
 
                case PW_TYPE_IPV6ADDR:
-                       a = inet_ntop(AF_INET6,
-                                     (const struct in6_addr *) vp->vp_strvalue,
-                                     buf, sizeof(buf));
-                       break;
-
-               case PW_TYPE_IPV6PREFIX:
-               {
-                       struct in6_addr addr;
-
-                       /*
-                        *      Alignment issues.
-                        */
-                       memcpy(&addr, vp->vp_strvalue + 2, sizeof(addr));
-
-                       a = inet_ntop(AF_INET6, &addr, buf, sizeof(buf));
-                       if (a) {
-                               char *p = buf + strlen(buf);
-                               sprintf(p, "/%u", (unsigned int) vp->vp_strvalue[1]);
-                       }
-               }
+                       a = ipv6_ntoa(buf, sizeof(buf), vp->strvalue);
                        break;
 
                default:
-                       a = "UNKNOWN-TYPE";
+                       a = 0;
                        break;
        }
-
-       if (a != NULL) strlcpy(out, a, outlen);
+       strNcpy(out, a?a:"UNKNOWN-TYPE", outlen);
 
        return strlen(out);
 }
@@ -229,7 +211,7 @@ int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
  *  This is a hack, and has to be kept in sync with tokens.h
  */
 static const char *vp_tokens[] = {
-  "?",                         /* T_OP_INVALID */
+  "?",                         /* T_INVALID */
   "EOL",                       /* T_EOL */
   "{",
   "}",
@@ -266,24 +248,15 @@ int vp_prints(char *out, int outlen, VALUE_PAIR *vp)
 {
        int             len;
        const char      *token = NULL;
-       const char      *name;
 
        out[0] = 0;
        if (!vp) return 0;
-       name = vp->name;
-
-       if (!*name) {
-               DICT_ATTR *da = dict_attrbyvalue(vp->attribute);
-               if (!da) return 0;
-
-               name = da->name;
-       }
 
-       if (strlen(name) + 3 > (size_t)outlen) {
+       if (strlen(vp->name) + 3 > (size_t)outlen) {
                return 0;
        }
 
-       if ((vp->operator > T_OP_INVALID) &&
+       if ((vp->operator > T_INVALID) &&
            (vp->operator < T_TOKEN_LAST)) {
                token = vp_tokens[vp->operator];
        } else {
@@ -292,7 +265,7 @@ int vp_prints(char *out, int outlen, VALUE_PAIR *vp)
 
        if( vp->flags.has_tag ) {
 
-               snprintf(out, outlen, "%s:%d %s ", name, vp->flags.tag,
+               snprintf(out, outlen, "%s:%d %s ", vp->name, vp->flags.tag,
                         token);
 
                len = strlen(out);
@@ -300,7 +273,7 @@ int vp_prints(char *out, int outlen, VALUE_PAIR *vp)
 
        } else {
 
-               snprintf(out, outlen, "%s %s ", name, token);
+               snprintf(out, outlen, "%s %s ", vp->name, token);
                len = strlen(out);
                vp_prints_value(out + len, outlen - len, vp, 1);
 
index ea1f025..044ed8f 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000-2003,2006  The FreeRADIUS server project
+ * Copyright 2000-2003  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/libradius.h>
-#include       <freeradius-devel/md5.h>
+#include       "autoconf.h"
+#include       "md5.h"
+
+#include       <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include       <unistd.h>
+#endif
 
 #include       <fcntl.h>
+#include       <string.h>
 #include       <ctype.h>
 
+#include       "libradius.h"
 #ifdef WITH_UDPFROMTO
-#include       <freeradius-devel/udpfromto.h>
+#include       "udpfromto.h"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include       <netinet/in.h>
+#endif
+
+#include       <sys/socket.h>
+
+#ifdef HAVE_ARPA_INET_H
+#include       <arpa/inet.h>
 #endif
 
 #ifdef HAVE_MALLOC_H
 #include       <malloc.h>
 #endif
 
+#ifdef WIN32
+#include       <process.h>
+#endif
+
 /*
  *  The RFC says 4096 octets max, and most packets are less than 256.
  */
@@ -64,11 +85,9 @@ typedef struct radius_packet_t {
 } radius_packet_t;
 
 static lrad_randctx lrad_rand_pool;    /* across multiple calls */
-static int lrad_rand_initialized = 0;
+static volatile int lrad_rand_index = -1;
 static unsigned int salt_offset = 0;
 
-
-#define MAX_PACKET_CODE (52)
 static const char *packet_codes[] = {
   "",
   "Access-Request",
@@ -125,338 +144,6 @@ static const char *packet_codes[] = {
 };
 
 
-/*
- *     Wrapper for sendto which handles sendfromto, IPv6, and all
- *     possible combinations.
- */
-static int rad_sendto(int sockfd, void *data, size_t data_len, int flags,
-                     lrad_ipaddr_t *src_ipaddr, lrad_ipaddr_t *dst_ipaddr,
-                     int dst_port)
-{
-       struct sockaddr_storage dst;
-       socklen_t               sizeof_dst = sizeof(dst);
-
-#ifdef WITH_UDPFROMTO
-       struct sockaddr_storage src;
-       socklen_t               sizeof_src = sizeof(src);
-
-       memset(&src, 0, sizeof(src));
-#endif
-       memset(&dst, 0, sizeof(dst));
-
-       /*
-        *      IPv4 is supported.
-        */
-       if (dst_ipaddr->af == AF_INET) {
-               struct sockaddr_in      *s4;
-
-               s4 = (struct sockaddr_in *)&dst;
-               sizeof_dst = sizeof(struct sockaddr_in);
-
-               s4->sin_family = AF_INET;
-               s4->sin_addr = dst_ipaddr->ipaddr.ip4addr;
-               s4->sin_port = htons(dst_port);
-
-#ifdef WITH_UDPFROMTO
-               s4 = (struct sockaddr_in *)&src;
-               sizeof_src = sizeof(struct sockaddr_in);
-
-               s4->sin_family = AF_INET;
-               s4->sin_addr = src_ipaddr->ipaddr.ip4addr;
-#endif
-
-       /*
-        *      IPv6 MAY be supported.
-        */
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
-       } else if (dst_ipaddr->af == AF_INET6) {
-               struct sockaddr_in6     *s6;
-
-               s6 = (struct sockaddr_in6 *)&dst;
-               sizeof_dst = sizeof(struct sockaddr_in6);
-
-               s6->sin6_family = AF_INET6;
-               s6->sin6_addr = dst_ipaddr->ipaddr.ip6addr;
-               s6->sin6_port = htons(dst_port);
-
-#ifdef WITH_UDPFROMTO
-               return -1;      /* UDPFROMTO && IPv6 are not supported */
-#if 0
-               s6 = (struct sockaddr_in6 *)&src;
-               sizeof_src = sizeof(struct sockaddr_in6);
-
-               s6->sin6_family = AF_INET6;
-               s6->sin6_addr = src_ipaddr->ipaddr.ip6addr;
-#endif /* #if 0 */
-#endif /* WITH_UDPFROMTO */
-#endif /* HAVE_STRUCT_SOCKADDR_IN6 */
-       } else return -1;   /* Unknown address family, Die Die Die! */
-
-#ifdef WITH_UDPFROMTO
-       /*
-        *      Only IPv4 is supported for udpfromto.
-        *
-        *      And if they don't specify a source IP address, don't
-        *      use udpfromto.
-        */
-       if ((dst_ipaddr->af == AF_INET) ||
-           (src_ipaddr->af != AF_UNSPEC)) {
-               return sendfromto(sockfd, data, data_len, flags,
-                                 (struct sockaddr *)&src, sizeof_src,
-                                 (struct sockaddr *)&dst, sizeof_dst);
-       }
-#else
-       src_ipaddr = src_ipaddr; /* -Wunused */
-#endif
-
-       /*
-        *      No udpfromto, OR an IPv6 socket, fail gracefully.
-        */
-       return sendto(sockfd, data, data_len, flags,
-                     (struct sockaddr *)&dst, sizeof_dst);
-}
-
-
-void rad_recv_discard(int sockfd)
-{
-       uint8_t                 header[4];
-       struct sockaddr_storage src;
-       socklen_t               sizeof_src = sizeof(src);
-
-       recvfrom(sockfd, header, sizeof(header), 0,
-                (struct sockaddr *)&src, &sizeof_src);
-}
-
-
-ssize_t rad_recv_header(int sockfd, lrad_ipaddr_t *src_ipaddr, int *src_port,
-                       int *code)
-{
-       ssize_t                 data_len, packet_len;
-       uint8_t                 header[4];
-       struct sockaddr_storage src;
-       socklen_t               sizeof_src = sizeof(src);
-
-       data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK,
-                           (struct sockaddr *)&src, &sizeof_src);
-       if (data_len < 0) return -1;
-
-       /*
-        *      Too little data is available, discard the packet.
-        */
-       if (data_len < 4) {
-               recvfrom(sockfd, header, sizeof(header), 0,
-                        (struct sockaddr *)&src, &sizeof_src);
-               return 1;
-
-       } else {                /* we got 4 bytes of data. */
-               /*
-                *      See how long the packet says it is.
-                */
-               packet_len = (header[2] * 256) + header[3];
-
-               /*
-                *      The length in the packet says it's less than
-                *      a RADIUS header length: discard it.
-                */
-               if (packet_len < AUTH_HDR_LEN) {
-                       recvfrom(sockfd, header, sizeof(header), 0,
-                                (struct sockaddr *)&src, &sizeof_src);
-                       return 1;
-
-                       /*
-                        *      Enforce RFC requirements, for sanity.
-                        *      Anything after 4k will be discarded.
-                        */
-               } else if (packet_len > MAX_PACKET_LEN) {
-                       recvfrom(sockfd, header, sizeof(header), 0,
-                                (struct sockaddr *)&src, &sizeof_src);
-                       return 1;
-               }
-       }
-
-       if (src.ss_family == AF_INET) {
-               struct sockaddr_in      *s4;
-
-               s4 = (struct sockaddr_in *)&src;
-               src_ipaddr->af = AF_INET;
-               src_ipaddr->ipaddr.ip4addr = s4->sin_addr;
-               *src_port = ntohs(s4->sin_port);
-
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
-       } else if (src.ss_family == AF_INET6) {
-               struct sockaddr_in6     *s6;
-
-               s6 = (struct sockaddr_in6 *)&src;
-               src_ipaddr->af = AF_INET6;
-               src_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
-               *src_port = ntohs(s6->sin6_port);
-
-#endif
-       } else {
-               recvfrom(sockfd, header, sizeof(header), 0,
-                        (struct sockaddr *)&src, &sizeof_src);
-               return 1;
-       }
-
-       *code = header[0];
-
-       /*
-        *      The packet says it's this long, but the actual UDP
-        *      size could still be smaller.
-        */
-       return packet_len;
-}
-
-
-/*
- *     wrapper for recvfrom, which handles recvfromto, IPv6, and all
- *     possible combinations.
- */
-static ssize_t rad_recvfrom(int sockfd, uint8_t **pbuf, int flags,
-                           lrad_ipaddr_t *src_ipaddr, uint16_t *src_port,
-                           lrad_ipaddr_t *dst_ipaddr, uint16_t *dst_port)
-{
-       struct sockaddr_storage src;
-       struct sockaddr_storage dst;
-       socklen_t               sizeof_src = sizeof(src);
-       socklen_t               sizeof_dst = sizeof(dst);
-       ssize_t                 data_len;
-       uint8_t                 header[4];
-       void                    *buf;
-       size_t                  len;
-
-       memset(&src, 0, sizeof_src);
-       memset(&dst, 0, sizeof_dst);
-
-       /*
-        *      Get address family, etc. first, so we know if we
-        *      need to do udpfromto.
-        *
-        *      FIXME: udpfromto also does this, but it's not
-        *      a critical problem.
-        */
-       if (getsockname(sockfd, (struct sockaddr *)&dst,
-                       &sizeof_dst) < 0) return -1;
-
-       /*
-        *      Read the length of the packet, from the packet.
-        *      This lets us allocate the buffer to use for
-        *      reading the rest of the packet.
-        */
-       data_len = recvfrom(sockfd, header, sizeof(header), MSG_PEEK,
-                           (struct sockaddr *)&src, &sizeof_src);
-       if (data_len < 0) return -1;
-
-       /*
-        *      Too little data is available, discard the packet.
-        */
-       if (data_len < 4) {
-               recvfrom(sockfd, header, sizeof(header), flags,
-                        (struct sockaddr *)&src, &sizeof_src);
-               return 0;
-
-       } else {                /* we got 4 bytes of data. */
-               /*
-                *      See how long the packet says it is.
-                */
-               len = (header[2] * 256) + header[3];
-
-               /*
-                *      The length in the packet says it's less than
-                *      a RADIUS header length: discard it.
-                */
-               if (len < AUTH_HDR_LEN) {
-                       recvfrom(sockfd, header, sizeof(header), flags,
-                                (struct sockaddr *)&src, &sizeof_src);
-                       return 0;
-
-                       /*
-                        *      Enforce RFC requirements, for sanity.
-                        *      Anything after 4k will be discarded.
-                        */
-               } else if (len > MAX_PACKET_LEN) {
-                       recvfrom(sockfd, header, sizeof(header), flags,
-                                (struct sockaddr *)&src, &sizeof_src);
-                       return len;
-               }
-       }
-
-       buf = malloc(len);
-       if (!buf) return -1;
-
-       /*
-        *      Receive the packet.  The OS will discard any data in the
-        *      packet after "len" bytes.
-        */
-#ifdef WITH_UDPFROMTO
-       if (dst.ss_family == AF_INET) {
-               data_len = recvfromto(sockfd, buf, len, flags,
-                                     (struct sockaddr *)&src, &sizeof_src,
-                                     (struct sockaddr *)&dst, &sizeof_dst);
-       } else
-#endif
-               /*
-                *      No udpfromto, OR an IPv6 socket.  Fail gracefully.
-                */
-               data_len = recvfrom(sockfd, buf, len, flags,
-                                   (struct sockaddr *)&src, &sizeof_src);
-       if (data_len < 0) {
-               free(buf);
-               return data_len;
-       }
-
-       /*
-        *      Check address families, and update src/dst ports, etc.
-        */
-       if (src.ss_family == AF_INET) {
-               struct sockaddr_in      *s4;
-
-               s4 = (struct sockaddr_in *)&src;
-               src_ipaddr->af = AF_INET;
-               src_ipaddr->ipaddr.ip4addr = s4->sin_addr;
-               *src_port = ntohs(s4->sin_port);
-
-               s4 = (struct sockaddr_in *)&dst;
-               dst_ipaddr->af = AF_INET;
-               dst_ipaddr->ipaddr.ip4addr = s4->sin_addr;
-               *dst_port = ntohs(s4->sin_port);
-
-#ifdef HAVE_STRUCT_SOCKADDR_IN6
-       } else if (src.ss_family == AF_INET6) {
-               struct sockaddr_in6     *s6;
-
-               s6 = (struct sockaddr_in6 *)&src;
-               src_ipaddr->af = AF_INET6;
-               src_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
-               *src_port = ntohs(s6->sin6_port);
-
-               s6 = (struct sockaddr_in6 *)&dst;
-               dst_ipaddr->af = AF_INET6;
-               dst_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
-               *dst_port = ntohs(s6->sin6_port);
-#endif
-       } else {
-               free(buf);
-               return -1;      /* Unknown address family, Die Die Die! */
-       }
-
-       /*
-        *      Different address families should never happen.
-        */
-       if (src.ss_family != dst.ss_family) {
-               free(buf);
-               return -1;
-       }
-
-       /*
-        *      Tell the caller about the data
-        */
-       *pbuf = buf;
-
-       return data_len;
-}
-
-
 #define AUTH_PASS_LEN (AUTH_VECTOR_LEN)
 /*************************************************************************
  *
@@ -472,13 +159,13 @@ static ssize_t rad_recvfrom(int sockfd, uint8_t **pbuf, int flags,
 static void make_secret(uint8_t *digest, const uint8_t *vector,
                        const char *secret, const uint8_t *value)
 {
-       lrad_MD5_CTX context;
+       MD5_CTX context;
         int             i;
 
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
-       lrad_MD5Update(&context, secret, strlen(secret));
-       lrad_MD5Final(digest, &context);
+       MD5Init(&context);
+       MD5Update(&context, vector, AUTH_VECTOR_LEN);
+       MD5Update(&context, secret, strlen(secret));
+       MD5Final(digest, &context);
 
         for ( i = 0; i < AUTH_VECTOR_LEN; i++ ) {
                digest[i] ^= value[i];
@@ -490,7 +177,7 @@ static void make_passwd(uint8_t *output, int *outlen,
                        const uint8_t *input, int inlen,
                        const char *secret, const uint8_t *vector)
 {
-       lrad_MD5_CTX context, old;
+       MD5_CTX context, old;
        uint8_t digest[AUTH_VECTOR_LEN];
        uint8_t passwd[MAX_PASS_LEN];
        int     i, n;
@@ -514,24 +201,24 @@ static void make_passwd(uint8_t *output, int *outlen,
        memcpy(passwd, input, len);
        memset(passwd + len, 0, sizeof(passwd) - len);
 
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, secret, strlen(secret));
+       MD5Init(&context);
+       MD5Update(&context, secret, strlen(secret));
        old = context;
 
        /*
         *      Do first pass.
         */
-       lrad_MD5Update(&context, vector, AUTH_PASS_LEN);
+       MD5Update(&context, vector, AUTH_PASS_LEN);
 
        for (n = 0; n < len; n += AUTH_PASS_LEN) {
                if (n > 0) {
                        context = old;
-                       lrad_MD5Update(&context,
+                       MD5Update(&context,
                                       passwd + n - AUTH_PASS_LEN,
                                       AUTH_PASS_LEN);
                }
 
-               lrad_MD5Final(digest, &context);
+               MD5Final(digest, &context);
                for (i = 0; i < AUTH_PASS_LEN; i++) {
                        passwd[i + n] ^= digest[i];
                }
@@ -544,18 +231,13 @@ static void make_tunnel_passwd(uint8_t *output, int *outlen,
                               const uint8_t *input, int inlen, int room,
                               const char *secret, const uint8_t *vector)
 {
-       lrad_MD5_CTX context, old;
+       MD5_CTX context, old;
        uint8_t digest[AUTH_VECTOR_LEN];
        uint8_t passwd[MAX_STRING_LEN + AUTH_VECTOR_LEN];
        int     i, n;
        int     len;
 
        /*
-        *      Be paranoid.
-        */
-       if (room > 253) room = 253;
-
-       /*
         *      Account for 2 bytes of the salt, and round the room
         *      available down to the nearest multiple of 16.  Then,
         *      subtract one from that to account for the length byte,
@@ -608,22 +290,22 @@ static void make_tunnel_passwd(uint8_t *output, int *outlen,
        passwd[1] = lrad_rand();
        passwd[2] = inlen;      /* length of the password string */
 
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, secret, strlen(secret));
+       MD5Init(&context);
+       MD5Update(&context, secret, strlen(secret));
        old = context;
 
-       lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
-       lrad_MD5Update(&context, &passwd[0], 2);
+       MD5Update(&context, vector, AUTH_VECTOR_LEN);
+       MD5Update(&context, &passwd[0], 2);
 
        for (n = 0; n < len; n += AUTH_PASS_LEN) {
                if (n > 0) {
                        context = old;
-                       lrad_MD5Update(&context,
+                       MD5Update(&context,
                                       passwd + 2 + n - AUTH_PASS_LEN,
                                       AUTH_PASS_LEN);
                }
 
-               lrad_MD5Final(digest, &context);
+               MD5Final(digest, &context);
                for (i = 0; i < AUTH_PASS_LEN; i++) {
                        passwd[i + 2 + n] ^= digest[i];
                }
@@ -647,33 +329,12 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
        vendorcode = total_length = 0;
        length_ptr = vsa_length_ptr = NULL;
-
+       
        /*
         *      For interoperability, always put vendor attributes
         *      into their own VSA.
         */
-       if ((vendorcode = VENDOR(vp->attribute)) == 0) {
-               *(ptr++) = vp->attribute & 0xFF;
-               length_ptr = ptr;
-               *(ptr++) = 2;
-               total_length += 2;
-
-       } else {
-               int vsa_tlen = 1;
-               int vsa_llen = 1;
-               DICT_VENDOR *dv = dict_vendorbyvalue(vendorcode);
-
-               /*
-                *      This must be an RFC-format attribute.  If it
-                *      wasn't, then the "decode" function would have
-                *      made a Vendor-Specific attribute (i.e. type
-                *      26), and we would have "vendorcode == 0" here.
-                */
-               if (dv) {
-                       vsa_tlen = dv->type;
-                       vsa_llen = dv->length;
-               }
-
+       if ((vendorcode = VENDOR(vp->attribute)) != 0) {
                /*
                 *      Build a VSA header.
                 */
@@ -684,52 +345,64 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                memcpy(ptr, &lvalue, 4);
                ptr += 4;
                total_length += 6;
-
-               switch (vsa_tlen) {
-               case 1:
-                       ptr[0] = (vp->attribute & 0xFF);
-                       break;
-
-               case 2:
-                       ptr[0] = ((vp->attribute >> 8) & 0xFF);
-                       ptr[1] = (vp->attribute & 0xFF);
-                       break;
-
-               case 4:
-                       ptr[0] = 0;
-                       ptr[1] = 0;
-                       ptr[2] = ((vp->attribute >> 8) & 0xFF);
-                       ptr[3] = (vp->attribute & 0xFF);
-                       break;
-
-               default:
-                       return 0; /* silently discard it */
-               }
-               ptr += vsa_tlen;
-
-               switch (vsa_llen) {
-               case 0:
+               
+               if (vendorcode == VENDORPEC_USR) {
+                       lvalue = htonl(vp->attribute & 0xFFFF);
+                       memcpy(ptr, &lvalue, 4);
+                       
                        length_ptr = vsa_length_ptr;
+                       
+                       total_length += 4;
+                       *length_ptr  += 4;
+                       ptr          += 4;
+                       
+                       /*
+                        *      We don't have two different lengths.
+                        */
                        vsa_length_ptr = NULL;
-                       break;
-               case 1:
-                       ptr[0] = 0;
+                       
+               } else if (vendorcode == VENDORPEC_LUCENT) {
+                       /*
+                        *      16-bit attribute, 8-bit length
+                        */
+                       *ptr++ = ((vp->attribute >> 8) & 0xFF);
+                       *ptr++ = (vp->attribute & 0xFF);
                        length_ptr = ptr;
-                       break;
-               case 2:
-                       ptr[0] = 0;
-                       ptr[1] = 0;
-                       length_ptr = ptr + 1;
-                       break;
+                       *vsa_length_ptr += 3;
+                       *ptr++ = 3;
+                       total_length += 3;
 
-               default:
-                       return 0; /* silently discard it */
+               } else if (vendorcode == VENDORPEC_STARENT) {
+                       /*
+                        *      16-bit attribute, 16-bit length
+                        *      with the upper 8 bits of the length
+                        *      always zero!
+                        */
+                       *ptr++ = ((vp->attribute >> 8) & 0xFF);
+                       *ptr++ = (vp->attribute & 0xFF);
+                       *ptr++ = 0;
+                       length_ptr = ptr;
+                       *vsa_length_ptr += 4;
+                       *ptr++ = 4;
+                       total_length += 4;
+               } else {
+                       /*
+                        *      All other VSA's are encoded the same
+                        *      as RFC attributes.
+                        */
+                       *vsa_length_ptr += 2;
+                       goto rfc;
                }
-               ptr += vsa_llen;
-
-               total_length += vsa_tlen + vsa_llen;
-               if (vsa_length_ptr) *vsa_length_ptr += vsa_tlen + vsa_llen;
-               *length_ptr += vsa_tlen + vsa_llen;
+       } else {
+       rfc:
+               /*
+                *      All other attributes are encoded as
+                *      per the RFC.
+                */
+               *ptr++ = (vp->attribute & 0xFF);
+               length_ptr = ptr;
+               *ptr++ = 2;
+               total_length += 2;
        }
 
        offset = 0;
@@ -737,7 +410,7 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                if (TAG_VALID(vp->flags.tag)) {
                        ptr[0] = vp->flags.tag & 0xff;
                        offset = 1;
-
+           
                } else if (vp->flags.encrypt == FLAG_ENCRYPT_TUNNEL_PASSWORD) {
                        /*
                         *      Tunnel passwords REQUIRE a tag, even
@@ -747,13 +420,25 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                        offset = 1;
                } /* else don't write a tag */
        } /* else the attribute doesn't have a tag */
-
+       
        /*
         *      Set up the default sources for the data.
         */
-       data = vp->vp_octets;
+       data = vp->strvalue;
        len = vp->length;
 
+       /*
+        *      Encrypted passwords can't be very long.
+        *      This check also ensures that the hashed version
+        *      of the password + attribute header fits into one
+        *      attribute.
+        *
+        *      FIXME: Print a warning message if it's too long?
+        */
+       if (vp->flags.encrypt && (len > MAX_PASS_LEN)) {
+               len = MAX_PASS_LEN;
+       }
+
        switch(vp->type) {
        case PW_TYPE_STRING:
        case PW_TYPE_OCTETS:
@@ -763,26 +448,10 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        case PW_TYPE_ABINARY:
                /* nothing more to do */
                break;
-
-       case PW_TYPE_BYTE:
-               len = 1;        /* just in case */
-               array[0] = vp->vp_integer & 0xff;
-               data = array;
-               offset = 0;
-               break;
-
-
-       case PW_TYPE_SHORT:
-               len = 2;        /* just in case */
-               array[0] = (vp->vp_integer >> 8) & 0xff;
-               array[1] = vp->vp_integer & 0xff;
-               data = array;
-               offset = 0;
-               break;
-
+                       
        case PW_TYPE_INTEGER:
                len = 4;        /* just in case */
-               lvalue = htonl(vp->vp_integer);
+               lvalue = htonl(vp->lvalue);
                memcpy(array, &lvalue, sizeof(lvalue));
 
                /*
@@ -791,9 +460,9 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                data = &array[offset];
                len -= offset;
                break;
-
+                       
        case PW_TYPE_IPADDR:
-               data = (const uint8_t *) &vp->vp_ipaddr;
+               data = (const uint8_t *) &vp->lvalue;
                len = 4;        /* just in case */
                break;
 
@@ -801,7 +470,7 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                 *  There are no tagged date attributes.
                 */
        case PW_TYPE_DATE:
-               lvalue = htonl(vp->vp_date);
+               lvalue = htonl(vp->lvalue);
                data = (const uint8_t *) &lvalue;
                len = 4;        /* just in case */
                break;
@@ -816,7 +485,7 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
         */
        if (len + offset + total_length > 255) {
                len = 255 - offset - total_length;
-       }
+       }       
 
        /*
         *      Encrypt the various password styles
@@ -830,7 +499,7 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                            data, len,
                            secret, packet->vector);
                break;
-
+               
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
                if (!original) {
                        librad_log("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
@@ -848,6 +517,9 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                 */
                if ((255 - offset - total_length) < 18) return 0;
 
+               /*
+                *      Can't make the password, suppress it.
+                */
                make_tunnel_passwd(ptr + offset, &len,
                                   data, len, 255 - offset - total_length,
                                   secret, original->vector);
@@ -863,7 +535,7 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                len = AUTH_VECTOR_LEN;
                break;
 
-
+               
        default:
                /*
                 *      Just copy the data over
@@ -906,9 +578,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        uint16_t        total_length;
        int             len;
        VALUE_PAIR      *reply;
-       const char      *what;
-       char            ip_buffer[128];
-
+       
        /*
         *      For simplicity in the following logic, we allow
         *      the attributes to "overflow" the 4k maximum
@@ -918,19 +588,6 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
         */
        uint32_t        data[(MAX_PACKET_LEN + 256) / 4];
 
-       if ((packet->code > 0) && (packet->code < MAX_PACKET_CODE)) {
-               what = packet_codes[packet->code];
-       } else {
-               what = "Reply";
-       }
-
-       DEBUG("Sending %s of id %d to %s port %d\n",
-             what, packet->id,
-             inet_ntop(packet->dst_ipaddr.af,
-                       &packet->dst_ipaddr.ipaddr,
-                       ip_buffer, sizeof(ip_buffer)),
-             packet->dst_port);
-
        /*
         *      Double-check some things based on packet code.
         */
@@ -943,7 +600,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                        return -1;
                }
                break;
-
+               
                /*
                 *      These packet vectors start off as all zero.
                 */
@@ -952,32 +609,32 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        case PW_COA_REQUEST:
                memset(packet->vector, 0, sizeof(packet->vector));
                break;
-
+               
        default:
                break;
        }
-
+               
        /*
         *      Use memory on the stack, until we know how
         *      large the packet will be.
         */
        hdr = (radius_packet_t *) data;
-
+       
        /*
         *      Build standard header
         */
        hdr->code = packet->code;
        hdr->id = packet->id;
-
+       
        memcpy(hdr->vector, packet->vector, sizeof(hdr->vector));
 
        total_length = AUTH_HDR_LEN;
-
+       packet->verified = 0;
+       
        /*
         *      Load up the configuration values for the user
         */
        ptr = hdr->data;
-       packet->offset = 0;
 
        /*
         *      FIXME: Loop twice over the reply list.  The first time,
@@ -987,7 +644,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
         *      Hmm... this may be slower than just doing a small
         *      memcpy.
         */
-
+       
        /*
         *      Loop over the reply attributes for the packet.
         */
@@ -999,22 +656,17 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                    ((reply->attribute & 0xFFFF) > 0xff)) {
                        continue;
                }
-
+               
                /*
                 *      Set the Message-Authenticator to the correct
                 *      length and initial value.
                 */
                if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
                        reply->length = AUTH_VECTOR_LEN;
-                       memset(reply->vp_strvalue, 0, AUTH_VECTOR_LEN);
-
-                       /*
-                        *      Cache the offset to the
-                        *      Message-Authenticator
-                        */
-                       packet->offset = total_length;
+                       memset(reply->strvalue, 0, AUTH_VECTOR_LEN);
+                       packet->verified = total_length; /* HACK! */
                }
-
+               
                /*
                 *      Print out ONLY the attributes which
                 *      we're sending over the wire, and print
@@ -1023,7 +675,6 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                debug_pair(reply);
 
                len = rad_vp2attr(packet, original, secret, reply, ptr);
-
                if (len < 0) return -1;
 
                /*
@@ -1041,7 +692,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                ptr += len;
                total_length += len;
        } /* done looping over all attributes */
-
+       
        /*
         *      Fill in the rest of the fields, and copy the data over
         *      from the local stack to the newly allocated memory.
@@ -1059,7 +710,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
        memcpy(packet->data, data, packet->data_len);
        hdr = (radius_packet_t *) packet->data;
-
+       
        total_length = htons(total_length);
        memcpy(hdr->length, &total_length, sizeof(total_length));
 
@@ -1084,7 +735,7 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        }
 
        if (!packet->data || (packet->data_len < AUTH_HDR_LEN) ||
-           (packet->offset < 0)) {
+           (packet->verified < 0)) {
                librad_log("ERROR: You must call rad_encode() before rad_sign()");
                return -1;
        }
@@ -1092,10 +743,12 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        /*
         *      If there's a Message-Authenticator, update it
         *      now, BEFORE updating the authentication vector.
+        *
+        *      This is a hack...
         */
-       if (packet->offset > 0) {
+       if (packet->verified > 0) {
                uint8_t calc_auth_vector[AUTH_VECTOR_LEN];
-
+               
                switch (packet->code) {
                case PW_ACCOUNTING_REQUEST:
                case PW_ACCOUNTING_RESPONSE:
@@ -1121,9 +774,9 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
                default:        /* others have vector already set to zero */
                        break;
-
+                       
                }
-
+               
                /*
                 *      Set the authentication vector to zero,
                 *      calculate the signature, and put it
@@ -1133,16 +786,16 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                lrad_hmac_md5(packet->data, packet->data_len,
                              secret, strlen(secret),
                              calc_auth_vector);
-               memcpy(packet->data + packet->offset + 2,
+               memcpy(packet->data + packet->verified + 2,
                       calc_auth_vector, AUTH_VECTOR_LEN);
-
+               
                /*
                 *      Copy the original request vector back
                 *      to the raw packet.
                 */
                memcpy(hdr->vector, packet->vector, AUTH_VECTOR_LEN);
        }
-
+       
        /*
         *      Switch over the packet code, deciding how to
         *      sign the packet.
@@ -1155,7 +808,7 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        case PW_AUTHENTICATION_REQUEST:
        case PW_STATUS_SERVER:
                break;
-
+               
                /*
                 *      Reply packets are signed with the
                 *      authentication vector of the request.
@@ -1163,13 +816,13 @@ int rad_sign(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        default:
                {
                        uint8_t digest[16];
-
+                       
                        MD5_CTX context;
                        MD5Init(&context);
                        MD5Update(&context, packet->data, packet->data_len);
                        MD5Update(&context, secret, strlen(secret));
                        MD5Final(digest, &context);
-
+                       
                        memcpy(hdr->vector, digest, AUTH_VECTOR_LEN);
                        memcpy(packet->vector, digest, AUTH_VECTOR_LEN);
                        break;
@@ -1189,6 +842,8 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        VALUE_PAIR              *reply;
        const char              *what;
        char                    ip_buffer[128];
+       struct  sockaddr_in     saremote;
+       struct  sockaddr_in     *sa;
 
        /*
         *      Maybe it's a fake packet.  Don't send it.
@@ -1197,7 +852,7 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                return 0;
        }
 
-       if ((packet->code > 0) && (packet->code < MAX_PACKET_CODE)) {
+       if ((packet->code > 0) && (packet->code < 52)) {
                what = packet_codes[packet->code];
        } else {
                what = "Reply";
@@ -1207,13 +862,18 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
         *  First time through, allocate room for the packet
         */
        if (!packet->data) {
+               DEBUG("Sending %s of id %d to %s port %d\n",
+                     what, packet->id,
+                     ip_ntoa(ip_buffer, packet->dst_ipaddr),
+                     packet->dst_port);
+               
                /*
                 *      Encode the packet.
                 */
                if (rad_encode(packet, original, secret) < 0) {
                        return -1;
                }
-
+               
                /*
                 *      Re-sign it, including updating the
                 *      Message-Authenticator.
@@ -1227,10 +887,8 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                 *      the VP list again only for debugging.
                 */
        } else if (librad_debug) {
-               DEBUG("Sending %s of id %d to %s port %d\n", what, packet->id,
-                     inet_ntop(packet->dst_ipaddr.af,
-                               &packet->dst_ipaddr.ipaddr,
-                               ip_buffer, sizeof(ip_buffer)),
+               DEBUG("Re-sending %s of id %d to %s port %d\n", what, packet->id,
+                     ip_ntoa(ip_buffer, packet->dst_ipaddr),
                      packet->dst_port);
 
                for (reply = packet->vps; reply; reply = reply->next) {
@@ -1242,9 +900,26 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        /*
         *      And send it on it's way.
         */
-       return rad_sendto(packet->sockfd, packet->data, packet->data_len, 0,
-                         &packet->src_ipaddr, &packet->dst_ipaddr,
-                         packet->dst_port);
+       sa = (struct sockaddr_in *) &saremote;
+        memset ((char *) sa, '\0', sizeof (saremote));
+       sa->sin_family = AF_INET;
+       sa->sin_addr.s_addr = packet->dst_ipaddr;
+       sa->sin_port = htons(packet->dst_port);
+#ifndef WITH_UDPFROMTO
+       return sendto(packet->sockfd, packet->data, (int)packet->data_len, 0,
+                     (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
+#else
+       {
+               struct sockaddr_in salocal;
+               memset ((char *) &salocal, '\0', sizeof (salocal));
+               salocal.sin_family = AF_INET;
+               salocal.sin_addr.s_addr = packet->src_ipaddr;
+               
+               return sendfromto(packet->sockfd, packet->data, (int)packet->data_len, 0,
+                                 (struct sockaddr *)&salocal,  sizeof(struct sockaddr_in),
+                                 (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
+       }
+#endif
 }
 
 
@@ -1254,10 +929,20 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
  */
 static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
 {
-       uint8_t         digest[AUTH_VECTOR_LEN];
+       u_char          digest[AUTH_VECTOR_LEN];
        MD5_CTX         context;
 
        /*
+        *      Older clients have the authentication vector set to
+        *      all zeros. Return `1' in that case.
+        */
+       memset(digest, 0, sizeof(digest));
+       if (memcmp(packet->vector, digest, AUTH_VECTOR_LEN) == 0) {
+               packet->verified = 1;
+               return 1;
+       }
+
+       /*
         *      Zero out the auth_vector in the received packet.
         *      Then append the shared secret to the received packet,
         *      and calculate the MD5 sum. This must be the same
@@ -1276,10 +961,11 @@ static int calc_acctdigest(RADIUS_PACKET *packet, const char *secret)
        /*
         *      Return 0 if OK, 2 if not OK.
         */
-       if (memcmp(digest, packet->vector, AUTH_VECTOR_LEN) != 0) return 2;
-       return 0;
-}
+       packet->verified =
+       memcmp(digest, packet->vector, AUTH_VECTOR_LEN) ? 2 : 0;
 
+       return packet->verified;
+}
 
 /*
  *     Validates the requesting client NAS.  Calculates the
@@ -1312,34 +998,95 @@ static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
        MD5Final(calc_digest, &context);
 
        /*
-        *  Copy the packet's vector back to the packet.
+        *  Copy the packet's vector back to the packet.
+        */
+       memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
+
+       /*
+        *      Return 0 if OK, 2 if not OK.
+        */
+       packet->verified =
+               memcmp(packet->vector, calc_digest, AUTH_VECTOR_LEN) ? 2 : 0;
+       return packet->verified;
+}
+
+/*
+ *     Receive UDP client requests, and fill in
+ *     the basics of a RADIUS_PACKET structure.
+ */
+RADIUS_PACKET *rad_recv(int fd)
+{
+       RADIUS_PACKET           *packet;
+       struct sockaddr_in      saremote;
+       int                     totallen;
+       socklen_t               salen;
+       uint8_t                 *attr;
+       int                     count;
+       radius_packet_t         *hdr;
+       char                    host_ipaddr[16];
+       int                     require_ma = 0;
+       int                     seen_ma = 0;
+       uint8_t                 data[MAX_PACKET_LEN];
+       int                     num_attributes;
+
+       /*
+        *      Allocate the new request data structure
+        */
+       if ((packet = malloc(sizeof(RADIUS_PACKET))) == NULL) {
+               librad_log("out of memory");
+               return NULL;
+       }
+       memset(packet, 0, sizeof(RADIUS_PACKET));
+
+       /*
+        *      Receive the packet.
+        */
+       salen = sizeof(saremote);
+       memset(&saremote, 0, sizeof(saremote));
+#ifndef WITH_UDPFROMTO
+       packet->data_len = recvfrom(fd, data, sizeof(data),
+                                   0, (struct sockaddr *)&saremote, &salen);
+       packet->dst_ipaddr = htonl(INADDR_ANY); /* i.e. unknown */
+#else
+       {
+               socklen_t               salen_local;
+               struct sockaddr_in      salocal;
+               salen_local = sizeof(salocal);
+               memset(&salocal, 0, sizeof(salocal));
+               packet->data_len = recvfromto(fd, data, sizeof(data), 0,
+                                             (struct sockaddr *)&saremote, &salen,
+                                             (struct sockaddr *)&salocal, &salen_local);
+               packet->dst_ipaddr = salocal.sin_addr.s_addr;
+       }
+#endif
+
+       /*
+        *      Check for socket errors.
+        */
+       if (packet->data_len < 0) {
+               librad_log("Error receiving packet: %s", strerror(errno));
+               free(packet);
+               return NULL;
+       }
+
+       /*
+        *      Fill IP header fields.  We need these for the error
+        *      messages which may come later.
         */
-       memcpy(packet->data + 4, packet->vector, AUTH_VECTOR_LEN);
+       packet->sockfd = fd;
+       packet->src_ipaddr = saremote.sin_addr.s_addr;
+       packet->src_port = ntohs(saremote.sin_port);
 
        /*
-        *      Return 0 if OK, 2 if not OK.
+        *      FIXME: Do even more filtering by only permitting
+        *      certain IP's.  The problem is that we don't know
+        *      how to do this properly for all possible clients...
         */
-       if (memcmp(packet->vector, calc_digest, AUTH_VECTOR_LEN) != 0) return 2;
-       return 0;
-}
-
 
-/*
- *     See if the data pointed to by PTR is a valid RADIUS packet.
- *
- *     packet is not 'const * const' because we may update data_len,
- *     if there's more data in the UDP packet than in the RADIUS packet.
- */
-int rad_packet_ok(RADIUS_PACKET *packet)
-{
-       uint8_t                 *attr;
-       int                     totallen;
-       int                     count;
-       radius_packet_t         *hdr;
-       char                    host_ipaddr[128];
-       int                     require_ma = 0;
-       int                     seen_ma = 0;
-       int                     num_attributes;
+       /*
+        *      Explicitely set the VP list to empty.
+        */
+       packet->vps = NULL;
 
        /*
         *      Check for packets smaller than the packet header.
@@ -1350,11 +1097,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (packet->data_len < AUTH_HDR_LEN) {
                librad_log("WARNING: Malformed RADIUS packet from host %s: too short (received %d < minimum %d)",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           packet->data_len, AUTH_HDR_LEN);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1364,11 +1110,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (packet->data_len > MAX_PACKET_LEN) {
                librad_log("WARNING: Malformed RADIUS packet from host %s: too long (received %d > maximum %d)",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           packet->data_len, MAX_PACKET_LEN);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1376,21 +1121,20 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         *      i.e. We've received 128 bytes, and the packet header
         *      says it's 256 bytes long.
         */
-       totallen = (packet->data[2] << 8) | packet->data[3];
-       hdr = (radius_packet_t *)packet->data;
+       totallen = (data[2] << 8) | data[3];
+       hdr = (radius_packet_t *)data;
 
        /*
         *      Code of 0 is not understood.
         *      Code of 16 or greate is not understood.
         */
        if ((hdr->code == 0) ||
-           (hdr->code >= MAX_PACKET_CODE)) {
+           (hdr->code >= 52)) {
                librad_log("WARNING: Bad RADIUS packet from host %s: unknown packet code %d",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           hdr->code);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1412,11 +1156,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (totallen < AUTH_HDR_LEN) {
                librad_log("WARNING: Malformed RADIUS packet from host %s: too short (length %d < minimum %d)",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           totallen, AUTH_HDR_LEN);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1428,11 +1171,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (totallen > MAX_PACKET_LEN) {
                librad_log("WARNING: Malformed RADIUS packet from host %s: too long (length %d > maximum %d)",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           totallen, MAX_PACKET_LEN);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1445,11 +1187,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (packet->data_len < totallen) {
                librad_log("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet length says %d",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           packet->data_len, totallen);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1463,7 +1204,7 @@ int rad_packet_ok(RADIUS_PACKET *packet)
                 *      We're shortening the packet below, but just
                 *      to be paranoid, zero out the extra data.
                 */
-               memset(packet->data + totallen, 0, packet->data_len - totallen);
+               memset(data + totallen, 0, packet->data_len - totallen);
                packet->data_len = totallen;
        }
 
@@ -1489,10 +1230,9 @@ int rad_packet_ok(RADIUS_PACKET *packet)
                 */
                if (attr[0] == 0) {
                        librad_log("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
-                                  inet_ntop(packet->src_ipaddr.af,
-                                            &packet->src_ipaddr.ipaddr,
-                                            host_ipaddr, sizeof(host_ipaddr)));
-                       return 0;
+                                  ip_ntoa(host_ipaddr, packet->src_ipaddr));
+                       free(packet);
+                       return NULL;
                }
 
                /*
@@ -1501,11 +1241,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
                 */
                        if (attr[1] < 2) {
                        librad_log("WARNING: Malformed RADIUS packet from host %s: attribute %d too short",
-                                  inet_ntop(packet->src_ipaddr.af,
-                                            &packet->src_ipaddr.ipaddr,
-                                            host_ipaddr, sizeof(host_ipaddr)),
+                                  ip_ntoa(host_ipaddr, packet->src_ipaddr),
                                   attr[0]);
-                       return 0;
+                       free(packet);
+                       return NULL;
                }
 
                /*
@@ -1515,6 +1254,7 @@ int rad_packet_ok(RADIUS_PACKET *packet)
                default:        /* don't do anything by default */
                        break;
 
+
                        /*
                         *      If there's an EAP-Message, we require
                         *      a Message-Authenticator.
@@ -1526,11 +1266,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
                case PW_MESSAGE_AUTHENTICATOR:
                        if (attr[1] != 2 + AUTH_VECTOR_LEN) {
                                librad_log("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
-                                          inet_ntop(packet->src_ipaddr.af,
-                                                    &packet->src_ipaddr.ipaddr,
-                                                    host_ipaddr, sizeof(host_ipaddr)),
+                                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                                           attr[1] - 2);
-                               return 0;
+                               free(packet);
+                               return NULL;
                        }
                        seen_ma = 1;
                        break;
@@ -1554,10 +1293,9 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (count != 0) {
                librad_log("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)));
-               return 0;
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr));
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1568,11 +1306,10 @@ int rad_packet_ok(RADIUS_PACKET *packet)
        if ((librad_max_attributes > 0) &&
            (num_attributes > librad_max_attributes)) {
                librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)),
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr),
                           num_attributes, librad_max_attributes);
-               return 0;
+               free(packet);
+               return NULL;
        }
 
        /*
@@ -1588,122 +1325,42 @@ int rad_packet_ok(RADIUS_PACKET *packet)
         */
        if (require_ma && ! seen_ma) {
                librad_log("WARNING: Insecure packet from host %s:  Packet does not contain required Message-Authenticator attribute",
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    host_ipaddr, sizeof(host_ipaddr)));
-               return 0;
-       }
-
-       /*
-        *      Fill RADIUS header fields
-        */
-       packet->code = hdr->code;
-       packet->id = hdr->id;
-       memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
-
-       return 1;
-}
-
-
-/*
- *     Receive UDP client requests, and fill in
- *     the basics of a RADIUS_PACKET structure.
- */
-RADIUS_PACKET *rad_recv(int fd)
-{
-       RADIUS_PACKET           *packet;
-
-       /*
-        *      Allocate the new request data structure
-        */
-       if ((packet = malloc(sizeof(*packet))) == NULL) {
-               librad_log("out of memory");
-               return NULL;
-       }
-       memset(packet, 0, sizeof(*packet));
-
-       packet->data_len = rad_recvfrom(fd, &packet->data, 0,
-                                       &packet->src_ipaddr, &packet->src_port,
-                                       &packet->dst_ipaddr, &packet->dst_port);
-
-       /*
-        *      Check for socket errors.
-        */
-       if (packet->data_len < 0) {
-               librad_log("Error receiving packet: %s", strerror(errno));
-               /* packet->data is NULL */
-               free(packet);
-               return NULL;
-       }
-
-       /*
-        *      If the packet is too big, then rad_recvfrom did NOT
-        *      allocate memory.  Instead, it just discarded the
-        *      packet.
-        */
-       if (packet->data_len > MAX_PACKET_LEN) {
-               librad_log("Discarding packet: Larger than RFC limitation of 4096 bytes.");
-               /* packet->data is NULL */
-               free(packet);
-               return NULL;
-       }
-
-       /*
-        *      Read no data.  Continue.
-        *      This check is AFTER the MAX_PACKET_LEN check above, because
-        *      if the packet is larger than MAX_PACKET_LEN, we also have
-        *      packet->data == NULL
-        */
-       if ((packet->data_len == 0) || !packet->data) {
-               librad_log("No data.");
+                          ip_ntoa(host_ipaddr, packet->src_ipaddr));
                free(packet);
                return NULL;
        }
 
-       /*
-        *      See if it's a well-formed RADIUS packet.
-        */
-       if (!rad_packet_ok(packet)) {
-               rad_free(&packet);
-               return NULL;
+       if (librad_debug) {
+               if ((hdr->code > 0) && (hdr->code < 52)) {
+                       printf("rad_recv: %s packet from host %s:%d",
+                              packet_codes[hdr->code],
+                              ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
+               } else {
+                       printf("rad_recv: Packet from host %s:%d code=%d",
+                              ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
+                              hdr->code);
+               }
+               printf(", id=%d, length=%d\n", hdr->id, totallen);
        }
 
        /*
-        *      Remember which socket we read the packet from.
-        */
-       packet->sockfd = fd;
-
-       /*
-        *      FIXME: Do even more filtering by only permitting
-        *      certain IP's.  The problem is that we don't know
-        *      how to do this properly for all possible clients...
+        *      Fill RADIUS header fields
         */
+       packet->code = hdr->code;
+       packet->id = hdr->id;
+       memcpy(packet->vector, hdr->vector, AUTH_VECTOR_LEN);
 
        /*
-        *      Explicitely set the VP list to empty.
+        *  Now that we've sanity checked the packet, we can allocate
+        *  memory for it, and copy the data from the local area to
+        *  the packet buffer.
         */
-       packet->vps = NULL;
-
-       if (librad_debug) {
-               char host_ipaddr[128];
-
-               if ((packet->code > 0) && (packet->code < MAX_PACKET_CODE)) {
-                       printf("rad_recv: %s packet from host %s port %d",
-                              packet_codes[packet->code],
-                              inet_ntop(packet->src_ipaddr.af,
-                                        &packet->src_ipaddr.ipaddr,
-                                        host_ipaddr, sizeof(host_ipaddr)),
-                              packet->src_port);
-               } else {
-                       printf("rad_recv: Packet from host %s port %d code=%d",
-                              inet_ntop(packet->src_ipaddr.af,
-                                        &packet->src_ipaddr.ipaddr,
-                                        host_ipaddr, sizeof(host_ipaddr)),
-                              packet->src_port,
-                              packet->code);
-               }
-               printf(", id=%d, length=%d\n", packet->id, packet->data_len);
+       if ((packet->data = malloc(packet->data_len)) == NULL) {
+         free(packet);
+         librad_log("out of memory");
+         return NULL;
        }
+       memcpy(packet->data, data, packet->data_len);
 
        return packet;
 }
@@ -1777,11 +1434,9 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                                   sizeof(calc_auth_vector)) != 0) {
                                char buffer[32];
                                librad_log("Received packet from %s with invalid Message-Authenticator!  (Shared secret is incorrect.)",
-                                          inet_ntop(packet->src_ipaddr.af,
-                                                    &packet->src_ipaddr.ipaddr,
-                                                    buffer, sizeof(buffer)));
+                                          ip_ntoa(buffer, packet->src_ipaddr));
                                /* Silently drop packet, according to RFC 3579 */
-                               return -1;
+                               return -2;
                        } /* else the message authenticator was good */
 
                        /*
@@ -1797,27 +1452,10 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
        } /* loop over the packet, sanity checking the attributes */
 
        /*
-        *      It looks like a RADIUS packet, but we can't validate
-        *      the signature.
-        */
-       if ((packet->code == 0) || packet->code >= MAX_PACKET_CODE) {
-               char buffer[32];
-               librad_log("Received Unknown packet code %d"
-                          "from client %s port %d: Cannot validate signature",
-                          packet->code,
-                          inet_ntop(packet->src_ipaddr.af,
-                                    &packet->src_ipaddr.ipaddr,
-                                    buffer, sizeof(buffer)),
-                          packet->src_port);
-               return -1;
-       }
-
-       /*
         *      Calculate and/or verify digest.
         */
        switch(packet->code) {
                int rcode;
-               char buffer[32];
 
                case PW_AUTHENTICATION_REQUEST:
                case PW_STATUS_SERVER:
@@ -1830,11 +1468,10 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
                case PW_ACCOUNTING_REQUEST:
                        if (calc_acctdigest(packet, secret) > 1) {
+                               char buffer[32];
                                librad_log("Received Accounting-Request packet "
                                           "from %s with invalid signature!  (Shared secret is incorrect.)",
-                                          inet_ntop(packet->src_ipaddr.af,
-                                                    &packet->src_ipaddr.ipaddr,
-                                                    buffer, sizeof(buffer)));
+                                          ip_ntoa(buffer, packet->src_ipaddr));
                                return -1;
                        }
                        break;
@@ -1844,33 +1481,18 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                case PW_AUTHENTICATION_REJECT:
                case PW_ACCESS_CHALLENGE:
                case PW_ACCOUNTING_RESPONSE:
-               case PW_DISCONNECT_ACK:
-               case PW_DISCONNECT_NAK:
-               case PW_COA_ACK:
-               case PW_COA_NAK:
                        rcode = calc_replydigest(packet, original, secret);
                        if (rcode > 1) {
+                               char buffer[32];
                                librad_log("Received %s packet "
                                           "from client %s port %d with invalid signature (err=%d)!  (Shared secret is incorrect.)",
                                           packet_codes[packet->code],
-                                          inet_ntop(packet->src_ipaddr.af,
-                                                    &packet->src_ipaddr.ipaddr,
-                                                    buffer, sizeof(buffer)),
+                                          ip_ntoa(buffer, packet->src_ipaddr),
                                           packet->src_port,
                                           rcode);
                                return -1;
                        }
-                       break;
-
-               default:
-                       librad_log("Received Unknown packet code %d"
-                                  "from client %s port %d: Cannot validate signature",
-                                  packet->code,
-                                  inet_ntop(packet->src_ipaddr.af,
-                                            &packet->src_ipaddr.ipaddr,
-                                                    buffer, sizeof(buffer)),
-                                  packet->src_port);
-                       return -1;
+                 break;
        }
 
        return 0;
@@ -1880,7 +1502,7 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 /*
  *     Parse a RADIUS attribute into a data structure.
  */
-VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
+static VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                        const char *secret, int attribute, int length,
                        const uint8_t *data)
 {
@@ -1890,7 +1512,7 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
        if ((vp = paircreate(attribute, PW_TYPE_OCTETS)) == NULL) {
                return NULL;
        }
-
+       
        /*
         *      If length is greater than 253, something is SERIOUSLY
         *      wrong.
@@ -1921,7 +1543,7 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
        /*
         *      Copy the data to be decrypted
         */
-       memcpy(&vp->vp_octets[0], data + offset, length - offset);
+       memcpy(&vp->strvalue[0], data + offset, length - offset);
        vp->length -= offset;
 
        /*
@@ -1933,32 +1555,32 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
                 */
        case FLAG_ENCRYPT_USER_PASSWORD:
                if (original) {
-                       rad_pwdecode((char *)vp->vp_strvalue,
+                       rad_pwdecode((char *)vp->strvalue,
                                     vp->length, secret,
                                     original->vector);
                } else {
-                       rad_pwdecode((char *)vp->vp_strvalue,
+                       rad_pwdecode((char *)vp->strvalue,
                                     vp->length, secret,
                                     packet->vector);
                }
                if (vp->attribute == PW_USER_PASSWORD) {
-                       vp->length = strlen(vp->vp_strvalue);
+                       vp->length = strlen(vp->strvalue);
                }
                break;
-
+               
                /*
                 *      Tunnel-Password's may go ONLY
                 *      in response packets.
                 */
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
                if (!original) goto raw;
-
-               if (rad_tunnel_pwdecode(vp->vp_octets, &vp->length,
+               
+               if (rad_tunnel_pwdecode(vp->strvalue, &vp->length,
                                        secret, original->vector) < 0) {
                        goto raw;
                }
                break;
-
+               
                /*
                 *  Ascend-Send-Secret
                 *  Ascend-Receive-Secret
@@ -1971,10 +1593,10 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
                        make_secret(my_digest,
                                    original->vector,
                                    secret, data);
-                       memcpy(vp->vp_strvalue, my_digest,
+                       memcpy(vp->strvalue, my_digest,
                               AUTH_VECTOR_LEN );
-                       vp->vp_strvalue[AUTH_VECTOR_LEN] = '\0';
-                       vp->length = strlen(vp->vp_strvalue);
+                       vp->strvalue[AUTH_VECTOR_LEN] = '\0';
+                       vp->length = strlen(vp->strvalue);
                }
                break;
 
@@ -1990,26 +1612,13 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
                /* nothing more to do */
                break;
 
-       case PW_TYPE_BYTE:
-               if (vp->length != 1) goto raw;
-
-               vp->vp_integer = vp->vp_octets[0];
-               break;
-
-
-       case PW_TYPE_SHORT:
-               if (vp->length != 2) goto raw;
-
-               vp->vp_integer = (vp->vp_octets[0] << 8) | vp->vp_octets[1];
-               break;
-
        case PW_TYPE_INTEGER:
                if (vp->length != 4) goto raw;
 
-               memcpy(&vp->vp_integer, vp->vp_octets, 4);
-               vp->vp_integer = ntohl(vp->vp_integer);
+               memcpy(&vp->lvalue, vp->strvalue, 4);
+               vp->lvalue = ntohl(vp->lvalue);
 
-               if (vp->flags.has_tag) vp->vp_integer &= 0x00ffffff;
+               if (vp->flags.has_tag) vp->lvalue &= 0x00ffffff;
 
                /*
                 *      Try to get named VALUEs
@@ -2017,11 +1626,11 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
                {
                        DICT_VALUE *dval;
                        dval = dict_valbyattr(vp->attribute,
-                                             vp->vp_integer);
+                                             vp->lvalue);
                        if (dval) {
-                               strlcpy(vp->vp_strvalue,
+                               strNcpy(vp->strvalue,
                                        dval->name,
-                                       sizeof(vp->vp_strvalue));
+                                       sizeof(vp->strvalue));
                        }
                }
                break;
@@ -2029,15 +1638,20 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
        case PW_TYPE_DATE:
                if (vp->length != 4) goto raw;
 
-               memcpy(&vp->vp_date, vp->vp_octets, 4);
-               vp->vp_date = ntohl(vp->vp_date);
+               memcpy(&vp->lvalue, vp->strvalue, 4);
+               vp->lvalue = ntohl(vp->lvalue);
                break;
 
-
+               /*
+                *      IPv4 address. Keep it in network byte order in
+                *      vp->lvalue and put ASCII IP address in standard
+                *      dot notation into vp->strvalue.
+                */
        case PW_TYPE_IPADDR:
                if (vp->length != 4) goto raw;
 
-               memcpy(&vp->vp_ipaddr, vp->vp_octets, 4);
+               memcpy(&vp->lvalue, vp->strvalue, 4);
+               ip_ntoa(vp->strvalue, vp->lvalue);
                break;
 
                /*
@@ -2045,17 +1659,17 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
                 */
        case PW_TYPE_IFID:
                if (vp->length != 8) goto raw;
-               /* vp->vp_ifid == vp->vp_octets */
+               /* vp->vp_ifid == vp->strvalue */
                break;
-
+               
                /*
                 *      IPv6 addresses are 16 octets long
                 */
        case PW_TYPE_IPV6ADDR:
                if (vp->length != 16) goto raw;
-               /* vp->vp_ipv6addr == vp->vp_octets */
+               /* vp->vp_ipv6addr == vp->strvalue */
                break;
-
+               
                /*
                 *      IPv6 prefixes are 2 to 18 octets long.
                 *
@@ -2067,14 +1681,14 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
                 */
        case PW_TYPE_IPV6PREFIX:
                if (vp->length < 2 || vp->length > 18) goto raw;
-               if (vp->vp_octets[1] > 128) goto raw;
+               if (vp->strvalue[1] > 128) goto raw;
 
                /*
                 *      FIXME: double-check that
-                *      (vp->vp_octets[1] >> 3) matches vp->length + 2
+                *      (vp->strvalue[1] >> 3) matches vp->length + 2
                 */
                if (vp->length < 18) {
-                       memset(vp->vp_octets + vp->length, 0,
+                       memset(vp->strvalue + vp->length, 0,
                               18 - vp->length);
                }
                break;
@@ -2083,8 +1697,8 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
        raw:
                vp->type = PW_TYPE_OCTETS;
                vp->length = length;
-               memcpy(vp->vp_octets, data, length);
-
+               memcpy(vp->strvalue, data, length);
+               
 
                /*
                 *      Ensure there's no encryption or tag stuff,
@@ -2099,9 +1713,6 @@ VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *origin
 
 /*
  *     Calculate/check digest, and decode radius attributes.
- *     Returns:
- *     -1 on decoding error
- *     0 on success
  */
 int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
               const char *secret)
@@ -2118,7 +1729,6 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
        radius_packet_t         *hdr;
        int                     vsa_tlen, vsa_llen;
        DICT_VENDOR             *dv = NULL;
-       int                     num_attributes = 0;
 
        /*
         *      Extract attribute-value pairs
@@ -2169,7 +1779,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        packet_length  -= 2;
 
                        if (attribute != PW_VENDOR_SPECIFIC) goto create_pair;
-
+                       
                        /*
                         *      No vendor code, or ONLY vendor code.
                         */
@@ -2177,7 +1787,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
                        vendorlen = 0;
                }
-
+               
                /*
                 *      Handle Vendor-Specific
                 */
@@ -2185,7 +1795,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        uint8_t *subptr;
                        int sublen;
                        int myvendor;
-
+                       
                        /*
                         *      attrlen was checked above.
                         */
@@ -2196,7 +1806,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                         *      Zero isn't allowed.
                         */
                        if (myvendor == 0) goto create_pair;
-
+                       
                        /*
                         *      This is an implementation issue.
                         *      We currently pack vendor into the upper
@@ -2205,14 +1815,14 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                         *      than 16 bits.
                         */
                        if (myvendor > 65535) goto create_pair;
-
+                       
                        vsa_tlen = vsa_llen = 1;
                        dv = dict_vendorbyvalue(myvendor);
                        if (dv) {
                                vsa_tlen = dv->type;
                                vsa_llen = dv->length;
                        }
-
+                       
                        /*
                         *      Sweep through the list of VSA's,
                         *      seeing if they exactly fill the
@@ -2233,7 +1843,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                                 *      Don't have a type, it's bad.
                                 */
                                if (sublen < vsa_tlen) goto create_pair;
-
+                               
                                /*
                                 *      Ensure that the attribute number
                                 *      is OK.
@@ -2242,25 +1852,25 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                                case 1:
                                        myattr = subptr[0];
                                        break;
-
+                                       
                                case 2:
                                        myattr = (subptr[0] << 8) | subptr[1];
                                        break;
-
+                                       
                                case 4:
                                        if ((subptr[0] != 0) ||
                                            (subptr[1] != 0)) goto create_pair;
-
+                                       
                                        myattr = (subptr[2] << 8) | subptr[3];
                                        break;
-
+                                       
                                        /*
                                         *      Our dictionary is broken.
                                         */
                                default:
                                        goto create_pair;
                                }
-
+                               
                                /*
                                 *      Not enough room for one more
                                 *      attribute.  Die!
@@ -2319,7 +1929,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                case 1:
                        attribute = ptr[0];
                        break;
-
+                       
                case 2:
                        attribute = (ptr[0] << 8) | ptr[1];
                        break;
@@ -2334,7 +1944,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                case 1:
                        attrlen = ptr[0] - (vsa_tlen + vsa_llen);
                        break;
-
+                       
                case 2:
                        attrlen = ptr[1] - (vsa_tlen + vsa_llen);
                        break;
@@ -2349,45 +1959,22 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 
                /*
                 *      Create the attribute, setting the default type
-                *      to 'octets'.  If the type in the dictionary
+                *      to 'octects'.  If the type in the dictionary
                 *      is different, then the dictionary type will
                 *      over-ride this one.
                 */
        create_pair:
                pair = rad_attr2vp(packet, original, secret,
-                                  attribute, attrlen, ptr);
+                                attribute, attrlen, ptr);
                if (!pair) {
                        pairfree(&packet->vps);
                        librad_log("out of memory");
                        return -1;
                }
 
+               debug_pair(pair);
                *tail = pair;
-               while (pair) {
-                       num_attributes++;
-                       debug_pair(pair);
-                       tail = &pair->next;
-                       pair = pair->next;
-               }
-
-               /*
-                *      VSA's may not have been counted properly in
-                *      rad_packet_ok() above, as it is hard to count
-                *      then without using the dictionary.  We
-                *      therefore enforce the limits here, too.
-                */
-               if ((librad_max_attributes > 0) &&
-                   (num_attributes > librad_max_attributes)) {
-                       char host_ipaddr[128];
-
-                       pairfree(&packet->vps);
-                       librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
-                                  inet_ntop(packet->src_ipaddr.af,
-                                            &packet->src_ipaddr.ipaddr,
-                                            host_ipaddr, sizeof(host_ipaddr)),
-                                  num_attributes, librad_max_attributes);
-                       return -1;
-               }
+               tail = &pair->next;
 
                ptr += attrlen;
                packet_length -= attrlen;
@@ -2398,7 +1985,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
         *      random pool.
         */
        lrad_rand_seed(packet->data, AUTH_HDR_LEN);
-
+         
        return 0;
 }
 
@@ -2415,62 +2002,55 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
  *     password - a multiple of 16 bytes.
  */
 int rad_pwencode(char *passwd, int *pwlen, const char *secret,
-                const uint8_t *vector)
+                const char *vector)
 {
-       lrad_MD5_CTX context, old;
-       uint8_t digest[AUTH_VECTOR_LEN];
+       uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
+       char    digest[AUTH_VECTOR_LEN];
        int     i, n, secretlen;
        int     len;
 
        /*
-        *      RFC maximum is 128 bytes.
-        *
-        *      If length is zero, pad it out with zeros.
-        *
-        *      If the length isn't aligned to 16 bytes,
-        *      zero out the extra data.
+        *      Pad password to multiple of AUTH_PASS_LEN bytes.
         */
        len = *pwlen;
-
        if (len > 128) len = 128;
+       *pwlen = len;
+       if (len % AUTH_PASS_LEN != 0) {
+               n = AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
+               for (i = len; n > 0; n--, i++)
+                       passwd[i] = 0;
+               len = *pwlen = i;
 
-       if (len == 0) {
+       } else if (len == 0) {
                memset(passwd, 0, AUTH_PASS_LEN);
-               len = AUTH_PASS_LEN;
-       } else if ((len % AUTH_PASS_LEN) != 0) {
-               memset(&passwd[len], 0, AUTH_PASS_LEN - (len % AUTH_PASS_LEN));
-               len += AUTH_PASS_LEN - (len % AUTH_PASS_LEN);
+               *pwlen = len = AUTH_PASS_LEN;
        }
-       *pwlen = len;
 
        /*
         *      Use the secret to setup the decryption digest
         */
        secretlen = strlen(secret);
-
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, secret, secretlen);
-       old = context;          /* save intermediate work */
+       memcpy(buffer, secret, secretlen);
+       memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
+       librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
 
        /*
-        *      Encrypt it in place.  Don't bother checking
-        *      len, as we've ensured above that it's OK.
+        *      Now we can encode the password *in place*
         */
-       for (n = 0; n < len; n += AUTH_PASS_LEN) {
-               if (n == 0) {
-                       lrad_MD5Update(&context, vector, AUTH_PASS_LEN);
-                       lrad_MD5Final(digest, &context);
-               } else {
-                       context = old;
-                       lrad_MD5Update(&context,
-                                        passwd + n - AUTH_PASS_LEN,
-                                        AUTH_PASS_LEN);
-                       lrad_MD5Final(digest, &context);
-               }
+       for (i = 0; i < AUTH_PASS_LEN; i++)
+               passwd[i] ^= digest[i];
 
-               for (i = 0; i < AUTH_PASS_LEN; i++) {
-                       passwd[i + n] ^= digest[i];
-               }
+       if (len <= AUTH_PASS_LEN) return 0;
+
+       /*
+        *      Length > AUTH_PASS_LEN, so we need to use the extended
+        *      algorithm.
+        */
+       for (n = 0; n < 128 && n <= (len - AUTH_PASS_LEN); n += AUTH_PASS_LEN) {
+               memcpy(buffer + secretlen, passwd + n, AUTH_PASS_LEN);
+               librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
+               for (i = 0; i < AUTH_PASS_LEN; i++)
+                       passwd[i + n + AUTH_PASS_LEN] ^= digest[i];
        }
 
        return 0;
@@ -2480,58 +2060,51 @@ int rad_pwencode(char *passwd, int *pwlen, const char *secret,
  *     Decode password.
  */
 int rad_pwdecode(char *passwd, int pwlen, const char *secret,
-                const uint8_t *vector)
+                const char *vector)
 {
-       lrad_MD5_CTX context, old;
-       uint8_t digest[AUTH_VECTOR_LEN];
+       uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 1];
+       char    digest[AUTH_VECTOR_LEN];
+       char    r[AUTH_VECTOR_LEN];
+       char    *s;
        int     i, n, secretlen;
-
-       /*
-        *      The RFC's say that the maximum is 128.
-        *      The buffer we're putting it into above is 254, so
-        *      we don't need to do any length checking.
-        */
-       if (pwlen > 128) pwlen = 128;
-
-       /*
-        *      Catch idiots.
-        */
-       if (pwlen == 0) goto done;
+       int     rlen;
 
        /*
         *      Use the secret to setup the decryption digest
         */
        secretlen = strlen(secret);
-
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, secret, secretlen);
-       old = context;          /* save intermediate work */
+       memcpy(buffer, secret, secretlen);
+       memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
+       librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_VECTOR_LEN);
 
        /*
-        *      The inverse of the code above.
+        *      Now we can decode the password *in place*
         */
-       for (n = 0; n < pwlen; n += AUTH_PASS_LEN) {
-               if (n == 0) {
-                       lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
-                       lrad_MD5Final(digest, &context);
+       memcpy(r, passwd, AUTH_PASS_LEN);
+       for (i = 0; i < AUTH_PASS_LEN && i < pwlen; i++)
+               passwd[i] ^= digest[i];
 
-                       context = old;
-                       if (pwlen > AUTH_PASS_LEN) lrad_MD5Update(&context, passwd, AUTH_PASS_LEN);
-               } else {
-                       lrad_MD5Final(digest, &context);
+       if (pwlen <= AUTH_PASS_LEN) {
+               passwd[pwlen+1] = 0;
+               return pwlen;
+       }
 
-                       context = old;
-                       if (pwlen > (n + AUTH_PASS_LEN)) lrad_MD5Update(&context, passwd + n, AUTH_PASS_LEN);
-               }
+       /*
+        *      Length > AUTH_PASS_LEN, so we need to use the extended
+        *      algorithm.
+        */
+       rlen = ((pwlen - 1) / AUTH_PASS_LEN) * AUTH_PASS_LEN;
 
-               for (i = 0; i < AUTH_PASS_LEN; i++) {
+       for (n = rlen; n > 0; n -= AUTH_PASS_LEN ) {
+               s = (n == AUTH_PASS_LEN) ? r : (passwd + n - AUTH_PASS_LEN);
+               memcpy(buffer + secretlen, s, AUTH_PASS_LEN);
+               librad_md5_calc((u_char *)digest, buffer, secretlen + AUTH_PASS_LEN);
+               for (i = 0; i < AUTH_PASS_LEN && (i + n) < pwlen; i++)
                        passwd[i + n] ^= digest[i];
-               }
        }
+       passwd[pwlen] = 0;
 
- done:
-       passwd[pwlen] = '\0';
-       return strlen(passwd);
+       return pwlen;
 }
 
 
@@ -2545,7 +2118,7 @@ int rad_pwdecode(char *passwd, int pwlen, const char *secret,
  *      value MD5 hash.
  */
 int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
-                       const uint8_t *vector)
+                       const char *vector)
 {
        uint8_t buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
        unsigned char   digest[AUTH_VECTOR_LEN];
@@ -2556,7 +2129,6 @@ int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
        len = *pwlen;
 
        if (len > 127) len = 127;
-
        /*
         * Shift the password 3 positions right to place a salt and original
         * length, tag will be added automatically on packet send
@@ -2628,12 +2200,13 @@ int rad_tunnel_pwencode(char *passwd, int *pwlen, const char *secret,
  *      above.
  */
 int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
-                       const uint8_t *vector)
+                       const char *vector)
 {
-       lrad_MD5_CTX  context, old;
+       uint8_t         buffer[AUTH_VECTOR_LEN + MAX_STRING_LEN + 3];
        uint8_t         digest[AUTH_VECTOR_LEN];
+       uint8_t         decrypted[MAX_STRING_LEN + 1];
        int             secretlen;
-       unsigned        i, n, len, reallen;
+       unsigned        i, n, len;
 
        len = *pwlen;
 
@@ -2668,62 +2241,64 @@ int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
         */
        secretlen = strlen(secret);
 
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, secret, secretlen);
-       old = context;          /* save intermediate work */
-
        /*
         *      Set up the initial key:
         *
         *       b(1) = MD5(secret + vector + salt)
         */
-       lrad_MD5Update(&context, vector, AUTH_VECTOR_LEN);
-       lrad_MD5Update(&context, passwd, 2);
-
-       reallen = 0;
-       for (n = 0; n < len; n += AUTH_PASS_LEN) {
-               int base = 0;
+       memcpy(buffer, secret, secretlen);
+       memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);
+       memcpy(buffer + secretlen + AUTH_VECTOR_LEN, passwd, 2);
+       librad_md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN + 2);
 
-               if (n == 0) {
-                       lrad_MD5Final(digest, &context);
+       /*
+        *      A quick check: decrypt the first octet of the password,
+        *      which is the 'data_len' field.  Ensure it's sane.
+        *
+        *      'n' doesn't include the 'data_len' octet
+        *      'len' does.
+        */
+       n = passwd[2] ^ digest[0];
+       if (n >= len) {
+               librad_log("tunnel password is too long for the attribute");
+               return -1;
+       }
 
-                       context = old;
+       /*
+        *      Loop over the data, decrypting it, and generating
+        *      the key for the next round of decryption.
+        */
+       for (n = 0; n < len; n += AUTH_PASS_LEN) {
+               for (i = 0; i < AUTH_PASS_LEN; i++) {
+                       decrypted[n + i] = passwd[n + i + 2] ^ digest[i];
 
                        /*
-                        *      A quick check: decrypt the first octet
-                        *      of the password, which is the
-                        *      'data_len' field.  Ensure it's sane.
+                        *      Encrypted password may not be aligned
+                        *      on 16 octets, so we catch that here...
                         */
-                       reallen = passwd[2] ^ digest[0];
-                       if (reallen >= len) {
-                               librad_log("tunnel password is too long for the attribute");
-                               return -1;
-                       }
-
-                       lrad_MD5Update(&context, passwd + 2, AUTH_PASS_LEN);
-
-                       base = 1;
-               } else {
-                       lrad_MD5Final(digest, &context);
-
-                       context = old;
-                       lrad_MD5Update(&context, passwd + n + 2, AUTH_PASS_LEN);
+                       if ((n + i) == len) break;
                }
 
-               for (i = base; i < AUTH_PASS_LEN; i++) {
-                       passwd[n + i - 1] = passwd[n + i + 2] ^ digest[i];
-               }
+               /*
+                *      Update the digest, based on
+                *
+                *      b(n) = MD5(secret + cleartext(n-1)
+                *
+                *      but only if there's more data...
+                */
+               memcpy(buffer + secretlen, passwd + n + 2, AUTH_PASS_LEN);
+               librad_md5_calc(digest, buffer, secretlen + AUTH_PASS_LEN);
        }
 
        /*
-        *      See make_tunnel_password, above.
+        *      We've already validated the length of the decrypted
+        *      password.  Copy it back to the caller.
         */
-       if (reallen > 239) reallen = 239;
+       memcpy(passwd, decrypted + 1, decrypted[0]);
+       passwd[decrypted[0]] = 0;
+       *pwlen = decrypted[0];
 
-       *pwlen = reallen;
-       passwd[reallen] = 0;
-
-       return reallen;
+       return decrypted[0];
 }
 
 /*
@@ -2733,12 +2308,12 @@ int rad_tunnel_pwdecode(uint8_t *passwd, int *pwlen, const char *secret,
  *     we use vp->length, and Ascend gear likes
  *     to send an extra '\0' in the string!
  */
-int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
+int rad_chap_encode(RADIUS_PACKET *packet, char *output, int id,
                    VALUE_PAIR *password)
 {
        int             i;
        char            *ptr;
-       uint8_t         string[MAX_STRING_LEN * 2 + 1];
+       char            string[MAX_STRING_LEN * 2 + 1];
        VALUE_PAIR      *challenge;
 
        /*
@@ -2760,7 +2335,7 @@ int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
        *ptr++ = id;
 
        i++;
-       memcpy(ptr, password->vp_strvalue, password->length);
+       memcpy(ptr, password->strvalue, password->length);
        ptr += password->length;
        i += password->length;
 
@@ -2770,7 +2345,7 @@ int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
         */
        challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE);
        if (challenge) {
-               memcpy(ptr, challenge->vp_strvalue, challenge->length);
+               memcpy(ptr, challenge->strvalue, challenge->length);
                i += challenge->length;
        } else {
                memcpy(ptr, packet->vector, AUTH_VECTOR_LEN);
@@ -2778,7 +2353,7 @@ int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id,
        }
 
        *output = id;
-       librad_md5_calc((uint8_t *)output + 1, (uint8_t *)string, i);
+       librad_md5_calc((u_char *)output + 1, (u_char *)string, i);
 
        return 0;
 }
@@ -2796,9 +2371,9 @@ void lrad_rand_seed(const void *data, size_t size)
        /*
         *      Ensure that the pool is initialized.
         */
-       if (!lrad_rand_initialized) {
+       if (lrad_rand_index < 0) {
                int fd;
-
+               
                memset(&lrad_rand_pool, 0, sizeof(lrad_rand_pool));
 
                fd = open("/dev/urandom", O_RDONLY);
@@ -2821,8 +2396,7 @@ void lrad_rand_seed(const void *data, size_t size)
                }
 
                lrad_randinit(&lrad_rand_pool, 1);
-               lrad_rand_pool.randcnt = 0;
-               lrad_rand_initialized = 1;
+               lrad_rand_index = 0;
        }
 
        if (!data) return;
@@ -2830,11 +2404,18 @@ void lrad_rand_seed(const void *data, size_t size)
        /*
         *      Hash the user data
         */
-       hash = lrad_rand();
-       if (!hash) hash = lrad_rand();
-       hash = lrad_hash_update(data, size, hash);
+       hash = lrad_hash(data, size);
+       
+       lrad_rand_pool.randrsl[lrad_rand_index & 0xff] ^= hash;
+       lrad_rand_index++;
+       lrad_rand_index &= 0xff;
 
-       lrad_rand_pool.randmem[lrad_rand_pool.randcnt] ^= hash;
+       /*
+        *      Churn the pool every so often after seeding it.
+        */
+       if (((int) (hash & 0xff)) == lrad_rand_index) {
+               lrad_isaac(&lrad_rand_pool);
+       }
 }
 
 
@@ -2848,20 +2429,28 @@ uint32_t lrad_rand(void)
        /*
         *      Ensure that the pool is initialized.
         */
-       if (!lrad_rand_initialized) {
+       if (lrad_rand_index < 0) {
                lrad_rand_seed(NULL, 0);
        }
 
-       num = lrad_rand_pool.randrsl[lrad_rand_pool.randcnt++];
-       if (lrad_rand_pool.randcnt == 256) {
+       /*
+        *      We don't return data directly from the pool.
+        *      Rather, we return a summary of the data.
+        */
+       num = lrad_rand_pool.randrsl[lrad_rand_index & 0xff];
+       lrad_rand_index++;
+       lrad_rand_index &= 0xff;
+
+       /*
+        *      Every so often, churn the pool.
+        */
+       if (((int) (num & 0xff)) == lrad_rand_index) {
                lrad_isaac(&lrad_rand_pool);
-               lrad_rand_pool.randcnt = 0;
        }
 
        return num;
 }
 
-
 /*
  *     Allocate a new RADIUS_PACKET
  */
@@ -2873,10 +2462,7 @@ RADIUS_PACKET *rad_alloc(int newvector)
                librad_log("out of memory");
                return NULL;
        }
-       memset(rp, 0, sizeof(*rp));
-       rp->id = -1;
-       rp->offset = -1;
-
+       memset(rp, 0, sizeof(RADIUS_PACKET));
        if (newvector) {
                int i;
                uint32_t hash, base;
@@ -2891,7 +2477,7 @@ RADIUS_PACKET *rad_alloc(int newvector)
                        memcpy(rp->vector + i, &hash, sizeof(hash));
                }
        }
-       lrad_rand();            /* stir the pool again */
+       lrad_rand();
 
        return rp;
 }
@@ -2903,12 +2489,11 @@ void rad_free(RADIUS_PACKET **radius_packet_ptr)
 {
        RADIUS_PACKET *radius_packet;
 
-       if (!radius_packet_ptr || !*radius_packet_ptr) return;
+       if (!radius_packet_ptr) return;
        radius_packet = *radius_packet_ptr;
 
-       free(radius_packet->data);
-
-       pairfree(&radius_packet->vps);
+       if (radius_packet->data) free(radius_packet->data);
+       if (radius_packet->vps) pairfree(&radius_packet->vps);
 
        free(radius_packet);
 
index 595299c..26dcc43 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- *  Copyright 2004,2006  The FreeRADIUS server project
+ *  Copyright 2004  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/libradius.h>
+#include "autoconf.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "missing.h"
+#include "libradius.h"
 
 /* red-black tree description */
 typedef enum { Black, Red } NodeColor;
@@ -37,7 +42,7 @@ struct rbnode_t {
 };
 
 #define NIL &Sentinel           /* all leafs are sentinels */
-static rbnode_t Sentinel = { NIL, NIL, NULL, Black, NULL};
+static const rbnode_t Sentinel = { NIL, NIL, NULL, Black, NULL};
 
 struct rbtree_t {
 #ifndef NDEBUG
@@ -228,7 +233,7 @@ static void InsertFixup(rbtree_t *tree, rbnode_t *X)
 /*
  *     Insert an element into the tree.
  */
-rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data)
+int rbtree_insert(rbtree_t *tree, void *Data)
 {
        rbnode_t *Current, *Parent, *X;
 
@@ -251,7 +256,7 @@ rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data)
                         *      Don't replace the entry.
                         */
                        if (tree->replace_flag == 0) {
-                               return NULL;
+                               return 0;
                        }
 
                        /*
@@ -259,7 +264,7 @@ rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data)
                         */
                        if (tree->freeNode) tree->freeNode(Current->Data);
                        Current->Data = Data;
-                       return Current;
+                       return 1;
                }
 
                Parent = Current;
@@ -291,13 +296,7 @@ rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data)
 
        tree->num_elements++;
 
-       return X;
-}
-
-int rbtree_insert(rbtree_t *tree, void *Data)
-{
-       if (rbtree_insertnode(tree, Data)) return 1;
-       return 0;
+       return 1;
 }
 
 static void DeleteFixup(rbtree_t *tree, rbnode_t *X, rbnode_t *Parent)
@@ -372,7 +371,6 @@ static void DeleteFixup(rbtree_t *tree, rbnode_t *X, rbnode_t *Parent)
  */
 void rbtree_delete(rbtree_t *tree, rbnode_t *Z)
 {
-       int fixup = 0;
        rbnode_t *X, *Y;
        rbnode_t *Parent;
 
@@ -410,41 +408,21 @@ void rbtree_delete(rbtree_t *tree, rbnode_t *Z)
                tree->Root = X;
 
        if (Y != Z) {
+               /*
+                *      Move the child's data to here, and then
+                *      re-balance the tree.
+                */
                if (tree->freeNode) tree->freeNode(Z->Data);
                Z->Data = Y->Data;
                Y->Data = NULL;
+       } else if (tree->freeNode) {
+               tree->freeNode(Z->Data);
+       }
 
-               if (Y->Color == Black && X != NIL)
-                       DeleteFixup(tree, X, Parent);
-
-               /*
-                *      The user structure in Y->Data MAY include a
-                *      pointer to Y.  In that case, we CANNOT delete
-                *      Y.  Instead, we copy Z (which is now in the
-                *      tree) to Y, and fix up the parent/child
-                *      pointers.
-                */
-               memcpy(Y, Z, sizeof(*Y));
-
-               if (!Y->Parent) {
-                       tree->Root = Y;
-               } else {
-                       if (Y->Parent->Left == Z) Y->Parent->Left = Y;
-                       if (Y->Parent->Right == Z) Y->Parent->Right = Y;
-               }
-               if (Y->Left->Parent == Z) Y->Left->Parent = Y;
-               if (Y->Right->Parent == Z) Y->Right->Parent = Y;
-
-               free(Z);
-
-       } else {
-               if (tree->freeNode) tree->freeNode(Y->Data);
-
-               if (Y->Color == Black && X != NIL)
-                       DeleteFixup(tree, X, Parent);
+       if (Y->Color == Black && X != NIL)
+               DeleteFixup(tree, X, Parent);
 
-               free(Y);
-       }
+       free(Y);
 
        tree->num_elements--;
 }
@@ -456,7 +434,7 @@ void rbtree_delete(rbtree_t *tree, rbnode_t *Z)
 int rbtree_deletebydata(rbtree_t *tree, const void *data)
 {
        rbnode_t *node = rbtree_find(tree, data);
-
+       
        if (!node) return 0;    /* false */
 
        rbtree_delete(tree, node);
@@ -622,18 +600,3 @@ void *rbtree_node2data(rbtree_t *tree, rbnode_t *node)
 
        return node->Data;
 }
-
-/*
- *     Return left-most child.
- */
-void *rbtree_min(rbtree_t *tree)
-{
-       rbnode_t *Current;
-
-       if (!tree || !tree->Root) return NULL;
-
-       Current = tree->Root;
-       while (Current->Left != NIL) Current = Current->Left;
-
-       return Current->Data;
-}
index 75cb9f7..534c24a 100644 (file)
@@ -6,10 +6,7 @@
  *  Version:   $Id$
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <string.h>
 
@@ -25,10 +22,6 @@ RCSID("$Id$")
 #include <stdint.h>
 #endif
 
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
 #include "../include/sha1.h"
 
 #define blk0(i) (block->l[i] = htonl(block->l[i]))
@@ -150,9 +143,9 @@ uint8_t finalcount[8];
         finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)]
          >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
     }
-    SHA1Update(context, (const unsigned char *) "\200", 1);
+    SHA1Update(context, "\200", 1);
     while ((context->count[0] & 504) != 448) {
-        SHA1Update(context, (const unsigned char *) "\0", 1);
+        SHA1Update(context, "\0", 1);
     }
     SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
     for (i = 0; i < 20; i++) {
index 409c920..85cb649 100644 (file)
@@ -24,7 +24,8 @@
          *  Fetched from: http://savannah.gnu.org/cgi-bin/viewcvs/mailutils/mailutils/lib/snprintf.c?rev=1.4
          *  Fetched from: http://savannah.gnu.org/cgi-bin/viewcvs/mailutils/mailutils/lib/snprintf.h?rev=1.4
          *  Replace config.h with autoconf.h
-         *  Protect with HAVE_SNPRINTF and HAVE_VSNPRINTF
+         *  Protect with HAVE_LOCAL_SNPRINTF
+  
    1.3:
       *  add #include <config.h> ifdef HAVE_CONFIG_H
       *  cosmetic change, when exponent is 0 print xxxE+00
 
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/autoconf.h>
-#include "snprintf.h"
+#ifdef HAVE_LOCAL_SNPRINTF
 
-#ifndef HAVE_VSNPRINTF
+#include "snprintf.h"
 
 /*
  * Find the nth power of 10
@@ -677,8 +676,6 @@ va_list args;
   return data.counter;
 }
 
-#endif /* HAVE_VSNPRINTF */
-
 #ifndef HAVE_SNPRINTF
 
 PUBLIC int
@@ -879,4 +876,6 @@ int main()
 
   return 0;
 }
-#endif /* !DRIVER */
+#endif
+
+#endif /* !HAVE_LOCAL_SNPRINTF */
index 094a085..c951ac7 100644 (file)
@@ -35,11 +35,6 @@ Return values:
 Alain Magloire: alainm@rcsm.ee.mcgill.ca
 */
 
-#ifndef HAVE_VSNPRINTF
-
-#include <freeradius-devel/ident.h>
-RCSIDH(snprintf_h, "$Id$")
-
 #if __STDC__
 #include <stdarg.h>
 #else
@@ -49,8 +44,6 @@ RCSIDH(snprintf_h, "$Id$")
 #include <stdlib.h>    /* for atoi() */
 #include <ctype.h>
 
-#define PRIVATE static
-#define PUBLIC
 
 /*
  * For the FLOATING POINT FORMAT :
@@ -124,6 +117,8 @@ struct DATA {
   int square, space, star_w, star_p, a_long, a_longlong;
 };
 
+#define PRIVATE static
+#define PUBLIC
 /* signature of the functions */
 #ifdef __STDC__
 /* the floating point stuff */
@@ -217,5 +212,3 @@ struct DATA {
               (p)->width = va_arg(args, int); \
             if ((p)->star_p == FOUND) \
               (p)->precision = va_arg(args, int)
-
-#endif /* HAVE_VSNPRINTF */
diff --git a/src/lib/strlcat.c b/src/lib/strlcat.c
deleted file mode 100644 (file)
index 563a14c..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  strlcat.c  Concatenate strings.
- *
- *  Version:   $Id$
- *
- */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Copyright 2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
-
-#ifndef HAVE_STRLCAT
-
-#include <freeradius-devel/missing.h>
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left).  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
-       char *d = dst;
-       const char *s = src;
-       size_t n = siz;
-       size_t dlen;
-
-       /* Find the end of dst and adjust bytes left but don't go past end */
-       while (n-- != 0 && *d != '\0')
-               d++;
-       dlen = d - dst;
-       n = siz - dlen;
-
-       if (n == 0)
-               return(dlen + strlen(s));
-       while (*s != '\0') {
-               if (n != 1) {
-                       *d++ = *s;
-                       n--;
-               }
-               s++;
-       }
-       *d = '\0';
-
-       return(dlen + (s - src));       /* count does not include NUL */
-}
-
-#endif
diff --git a/src/lib/strlcpy.c b/src/lib/strlcpy.c
deleted file mode 100644 (file)
index 549f138..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  strlcpy.c  Copy strings.
- *
- *  Version:   $Id$
- *
- */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Copyright 2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
-
-#ifndef HAVE_STRLCPY
-
-#include <freeradius-devel/missing.h>
-
-/*
- * Copy src to string dst of size siz.  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t siz)
-{
-       char *d = dst;
-       const char *s = src;
-       size_t n = siz;
-
-       /* Copy as many bytes as will fit */
-       if (n != 0 && --n != 0) {
-               do {
-                       if ((*d++ = *s++) == 0)
-                               break;
-               } while (--n != 0);
-       }
-
-       /* Not enough room in dst, add NUL and traverse rest of src */
-       if (n == 0) {
-               if (siz != 0)
-                       *d = '\0';              /* NUL-terminate dst */
-               while (*s++)
-                       ;
-       }
-
-       return(s - src - 1);    /* count does not include NUL */
-}
-
-#endif
index cad7c1c..cdad21c 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/token.h>
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
+#include "token.h"
+
+static const char rcsid[] = "$Id$";
 
 static const LRAD_NAME_NUMBER tokens[] = {
        { "=~", T_OP_REG_EQ,    }, /* order is important! */
@@ -75,7 +75,7 @@ static LRAD_TOKEN getthing(char **ptr, char *buf, int buflen, int tok,
        char    *s, *p;
        int     quote;
        int     escape;
-       unsigned int    x;
+       int     x;
        const LRAD_NAME_NUMBER*t;
        LRAD_TOKEN rcode;
 
index e4535fc..3798ffa 100644 (file)
  * Version: $Id$
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/udpfromto.h>
+#include "autoconf.h"
 
 #ifdef WITH_UDPFROMTO
+static const char rcsid[] = "$Id$";
+
+#include <sys/types.h>
 
 #ifdef HAVE_SYS_UIO_H
 #include <sys/uio.h>
 #endif
 
+#include <netinet/in.h>
+#include <errno.h>
+#include <unistd.h>
 #include <fcntl.h>
+#include <string.h>
 
+#include "udpfromto.h"
 
 int udpfromto_init(int s)
 {
@@ -175,22 +180,11 @@ int sendfromto(int s, void *buf, size_t len, int flags,
        struct in_pktinfo pktinfo, *pktinfo_ptr;
        memset(&pktinfo, 0, sizeof(struct in_pktinfo));
 # endif
-       struct sockaddr_in      *s4;
 
 # ifdef HAVE_IP_SENDSRCADDR
        char cmsgbuf[CMSG_SPACE(sizeof(struct in_addr))];
 # endif
 
-       s4 = (struct sockaddr_in *) from;
-
-       /*
-        *      Source is unset, empty, or unspecified,
-        *      fall back to sendto().
-        */
-       if (!s4 || (fromlen == 0) || (s4->sin_family == AF_UNSPEC)) {
-               return sendto(s, buf, len, flags, to, tolen);
-       }
-
        /* Set up iov and msgh structures. */
        memset(&msgh, 0, sizeof(struct msghdr));
        iov.iov_base = buf;
index d27525e..535c79f 100644 (file)
  *   License along with this library; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/libradius.h>
+#include       "autoconf.h"
 
+#include       <sys/types.h>
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
 #include       <ctype.h>
 
+#include       "libradius.h"
+
 #ifdef HAVE_MALLOC_H
 #  include     <malloc.h>
 #endif
@@ -35,67 +41,12 @@ RCSID("$Id$")
 #  include     <regex.h>
 #endif
 
+#include       "missing.h"
+
 static const char *months[] = {
         "jan", "feb", "mar", "apr", "may", "jun",
         "jul", "aug", "sep", "oct", "nov", "dec" };
 
-static VALUE_PAIR *pairalloc(DICT_ATTR *da)
-{
-       VALUE_PAIR *vp;
-
-       vp = malloc(sizeof(*vp));
-       if (!vp) return NULL;
-       memset(vp, 0, sizeof(*vp));
-
-       if (da) {
-               vp->attribute = da->attr;
-               vp->vendor = da->vendor;
-               vp->type = da->type;
-               strlcpy(vp->name, da->name, sizeof(vp->name));
-               vp->flags = da->flags;
-       } else {
-               vp->attribute = 0;
-               vp->vendor = 0;
-               vp->type = PW_TYPE_OCTETS;
-               vp->name[0] = '\0';
-               memset(&vp->flags, 0, sizeof(vp->flags));
-       }
-
-       switch (vp->type) {
-               case PW_TYPE_BYTE:
-                       vp->length = 1;
-                       break;
-
-               case PW_TYPE_SHORT:
-                       vp->length = 2;
-                       break;
-
-               case PW_TYPE_INTEGER:
-               case PW_TYPE_IPADDR:
-               case PW_TYPE_DATE:
-                       vp->length = 4;
-                       break;
-
-               case PW_TYPE_IFID:
-                       vp->length = sizeof(vp->vp_ifid);
-                       break;
-
-               case PW_TYPE_IPV6ADDR:
-                       vp->length = sizeof(vp->vp_ipv6addr);
-                       break;
-
-               case PW_TYPE_IPV6PREFIX:
-                       vp->length = sizeof(vp->vp_ipv6prefix);
-                       break;
-
-               default:
-                       vp->length = 0;
-                       break;
-       }
-
-       return vp;
-}
-
 
 /*
  *     Create a new valuepair.
@@ -105,33 +56,46 @@ VALUE_PAIR *paircreate(int attr, int type)
        VALUE_PAIR      *vp;
        DICT_ATTR       *da;
 
-       da = dict_attrbyvalue(attr);
-       if ((vp = pairalloc(da)) == NULL) {
+       if ((vp = malloc(sizeof(VALUE_PAIR))) == NULL) {
                librad_log("out of memory");
                return NULL;
        }
+       memset(vp, 0, sizeof(VALUE_PAIR));
+       vp->attribute = attr;
        vp->operator = T_OP_EQ;
+       vp->type = type;
 
        /*
-        *      Update the name...
+        *      Dictionary type over-rides what the caller says.
         */
-       if (!da) {
-               if (VENDOR(attr) == 0) {
-                       sprintf(vp->name, "Attr-%u", attr);
+       if ((da = dict_attrbyvalue(attr)) != NULL) {
+               strcpy(vp->name, da->name);
+               vp->type = da->type;
+               vp->flags = da->flags;
+       } else if (VENDOR(attr) == 0) {
+               sprintf(vp->name, "Attr-%u", attr);
+       } else {
+               DICT_VENDOR *v;
 
+               v = dict_vendorbyvalue(VENDOR(attr));
+               if (v) {
+                       sprintf(vp->name, "%s-Attr-%u",
+                               v->name, attr & 0xffff);
                } else {
-                       DICT_VENDOR *v;
-
-                       v = dict_vendorbyvalue(VENDOR(attr));
-                       if (v) {
-                               sprintf(vp->name, "%s-Attr-%u",
-                                       v->name, attr & 0xffff);
-                       } else {
-                               sprintf(vp->name, "Vendor-%u-Attr-%u",
-                                       VENDOR(attr), attr & 0xffff);
-                       }
+                       sprintf(vp->name, "Vendor-%u-Attr-%u",
+                               VENDOR(attr), attr & 0xffff);
                }
        }
+       switch (vp->type) {
+               case PW_TYPE_INTEGER:
+               case PW_TYPE_IPADDR:
+               case PW_TYPE_DATE:
+                       vp->length = 4;
+                       break;
+               default:
+                       vp->length = 0;
+                       break;
+       }
 
        return vp;
 }
@@ -205,8 +169,6 @@ void pairadd(VALUE_PAIR **first, VALUE_PAIR *add)
 {
        VALUE_PAIR *i;
 
-       if (!add) return;
-
        if (*first == NULL) {
                *first = add;
                return;
@@ -280,7 +242,7 @@ VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr)
                        vp = vp->next;
                        continue;
                }
-               if ((n = malloc(sizeof(*n))) == NULL) {
+               if ((n = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == NULL) {
                        librad_log("out of memory");
                        return first;
                }
@@ -314,13 +276,19 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
        VALUE_PAIR *found;
        int has_password = 0;
 
+       if (*to == NULL) {
+               *to = *from;
+               *from = NULL;
+               return;
+       }
+
        /*
         *      First, see if there are any passwords here, and
         *      point "tailto" to the end of the "to" list.
         */
        tailto = to;
        for(i = *to; i; i = i->next) {
-               if (i->attribute == PW_USER_PASSWORD ||
+               if (i->attribute == PW_PASSWORD ||
                    i->attribute == PW_CRYPT_PASSWORD)
                        has_password = 1;
                tailto = &i->next;
@@ -331,40 +299,17 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
         */
        for(i = *from; i; i = next) {
                next = i->next;
-
                /*
                 *      If there was a password in the "to" list,
                 *      do not move any other password from the
                 *      "from" to the "to" list.
                 */
                if (has_password &&
-                   (i->attribute == PW_USER_PASSWORD ||
+                   (i->attribute == PW_PASSWORD ||
                     i->attribute == PW_CRYPT_PASSWORD)) {
                        tailfrom = i;
                        continue;
                }
-
-               switch (i->operator) {
-                       /*
-                        *      These are COMPARISON attributes
-                        *      from a check list, and are not
-                        *      supposed to be copied!
-                        */
-                       case T_OP_NE:
-                       case T_OP_GE:
-                       case T_OP_GT:
-                       case T_OP_LE:
-                       case T_OP_LT:
-                       case T_OP_CMP_TRUE:
-                       case T_OP_CMP_FALSE:
-                       case T_OP_CMP_EQ:
-                               tailfrom = i;
-                               continue;
-
-                       default:
-                               break;
-               }
-
                /*
                 *      If the attribute is already present in "to",
                 *      do not move it from "from" to "to". We make
@@ -378,14 +323,14 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
                        switch (i->operator) {
 
                          /*
-                          *    If matching attributes are found,
-                          *    delete them.
+                          *  If a similar attribute is found,
+                          *  delete it.
                           */
                        case T_OP_SUB:          /* -= */
                                if (found) {
-                                       if (!i->vp_strvalue[0] ||
-                                           (strcmp((char *)found->vp_strvalue,
-                                                   (char *)i->vp_strvalue) == 0)){
+                                       if (!i->strvalue[0] ||
+                                           (strcmp((char *)found->strvalue,
+                                                   (char *)i->strvalue) == 0)){
                                                pairdelete(to, found->attribute);
 
                                                /*
@@ -413,29 +358,29 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
 
                        case T_OP_REG_EQ:
                          if (found &&
-                             (i->vp_strvalue[0] == 's')) {
+                             (i->strvalue[0] == 's')) {
                            regex_t             reg;
                            regmatch_t          match[1];
 
                            char *str;
                            char *p, *q;
 
-                           p = i->vp_strvalue + 1;
+                           p = i->strvalue + 1;
                            q = strchr(p + 1, *p);
                            if (!q || (q[strlen(q) - 1] != *p)) {
                              tailfrom = i;
                              continue;
                            }
-                           str = strdup(i->vp_strvalue + 2);
+                           str = strdup(i->strvalue + 2);
                            q = strchr(str, *p);
                            *(q++) = '\0';
                            q[strlen(q) - 1] = '\0';
 
                            regcomp(&reg, str, 0);
-                           if (regexec(&reg, found->vp_strvalue,
+                           if (regexec(&reg, found->strvalue,
                                        1, match, 0) == 0) {
                              fprintf(stderr, "\"%s\" will have %d to %d replaced with %s\n",
-                                     found->vp_strvalue, match[0].rm_so,
+                                     found->strvalue, match[0].rm_so,
                                      match[0].rm_eo, q);
 
                            }
@@ -465,32 +410,15 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
                           */
                        case T_OP_SET:          /* := */
                                if (found) {
-                                       VALUE_PAIR *mynext = found->next;
-
-                                       /*
-                                        *      Do NOT call pairdelete()
-                                        *      here, due to issues with
-                                        *      re-writing "request->username".
-                                        *
-                                        *      Everybody calls pairmove,
-                                        *      and expects it to work.
-                                        *      We can't update request->username
-                                        *      here, so instead we over-write
-                                        *      the vp that it's pointing to.
-                                        */
-                                       memcpy(found, i, sizeof(*found));
-                                       found->next = mynext;
-
-                                       pairdelete(&found->next, found->attribute);
-
+                                       pairdelete(to, found->attribute);
                                        /*
                                         *      'tailto' may have been
                                         *      deleted...
                                         */
-                                       for(j = found; j; j = j->next) {
+                                       tailto = to;
+                                       for(j = *to; j; j = j->next) {
                                                tailto = &j->next;
                                        }
-                                       continue;
                                }
                                break;
 
@@ -612,7 +540,7 @@ static char *mystrtok(char **ptr, const char *sep)
  *     Turn printable string into time_t
  *     Returns -1 on error, 0 on OK.
  */
-static int gettime(const char *valstr, uint32_t *lvalue)
+static int gettime(const char *valstr, time_t *lvalue)
 {
        int             i;
        time_t          t;
@@ -634,7 +562,7 @@ static int gettime(const char *valstr, uint32_t *lvalue)
        memset(tm, 0, sizeof(*tm));
        tm->tm_isdst = -1;      /* don't know, and don't care about DST */
 
-       strlcpy(buf, valstr, sizeof(buf));
+       strNcpy(buf, valstr, sizeof(buf));
 
        p = buf;
        f[0] = mystrtok(&p, " \t");
@@ -644,21 +572,6 @@ static int gettime(const char *valstr, uint32_t *lvalue)
        if (!f[0] || !f[1] || !f[2]) return -1;
 
        /*
-        *      The time has a colon, where nothing else does.
-        *      So if we find it, bubble it to the back of the list.
-        */
-       if (f[3]) {
-               for (i = 0; i < 3; i++) {
-                       if (strchr(f[i], ':')) {
-                               p = f[3];
-                               f[3] = f[i];
-                               f[i] = p;
-                               break;
-                       }
-               }
-       }
-
-       /*
         *  The month is text, which allows us to find it easily.
         */
        tm->tm_mon = 12;
@@ -725,11 +638,8 @@ static int gettime(const char *valstr, uint32_t *lvalue)
                *(f[1]++) = '\0'; /* nuke it, and point to MM:SS */
 
                f[2] = strchr(f[1], ':'); /* find : separator */
-               if (f[2]) {
-                 *(f[2]++) = '\0';     /* nuke it, and point to SS */
-               } else {
-                 strcpy(f[2], "0");    /* assignment would discard const */
-               }
+               if (!f[2]) return -1;
+               *(f[2]++) = '\0';       /* nuke it, and point to SS */
 
                tm->tm_hour = atoi(f[0]);
                tm->tm_min = atoi(f[1]);
@@ -747,14 +657,8 @@ static int gettime(const char *valstr, uint32_t *lvalue)
        return 0;
 }
 
-
 /*
  *  Parse a string value into a given VALUE_PAIR
- *
- *  FIXME: we probably want to fix this function to accept
- *  octets as values for any type of attribute.  We should then
- *  double-check the parsed value, to be sure it's legal for that
- *  type (length, etc.)
  */
 VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
 {
@@ -764,10 +668,10 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
 
        /*
         *      Even for integers, dates and ip addresses we
-        *      keep the original string in vp->vp_strvalue.
+        *      keep the original string in vp->strvalue.
         */
-       strlcpy((char *)vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
-       vp->length = strlen(vp->vp_strvalue);
+       strNcpy((char *)vp->strvalue, value, sizeof(vp->strvalue));
+       vp->length = strlen(vp->strvalue);
 
        switch(vp->type) {
                case PW_TYPE_STRING:
@@ -778,14 +682,6 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
 
                case PW_TYPE_IPADDR:
                        /*
-                        *      It's a comparison, not a real IP.
-                        */
-                       if ((vp->operator == T_OP_REG_EQ) ||
-                           (vp->operator == T_OP_REG_NE)) {
-                               break;
-                       }
-
-                       /*
                         *      FIXME: complain if hostname
                         *      cannot be resolved, or resolve later!
                         */
@@ -798,100 +694,38 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                                p = NULL;
                                cs = value;
                        }
-
-                       {
-                               lrad_ipaddr_t ipaddr;
-
-                               if (ip_hton(cs, AF_INET, &ipaddr) < 0) {
-                                       librad_log("Failed to find IP address for %s", cs);
-                                       return NULL;
-                               }
-
-                               vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
-                       }
+                       vp->lvalue = librad_dodns ? ip_getaddr(cs) :
+                                                   ip_addr(cs);
                        if (s) free(s);
                        vp->length = 4;
                        break;
-
-               case PW_TYPE_BYTE:
-                       /*
-                        *      Note that ALL integers are unsigned!
-                        */
-                       vp->vp_integer = (uint32_t) strtoul(value, &p, 10);
-                       if (!*p) {
-                               if (vp->vp_integer > 255) {
-                                       librad_log("Byte value \"%s\" is larger than 255", value);
-                                       return NULL;
-                               }
-                               vp->length = 1;
-                               break;
-                       }
-
-                       /*
-                        *      Look for the named value for the given
-                        *      attribute.
-                        */
-                       if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
-                               librad_log("Unknown value %s for attribute %s",
-                                          value, vp->name);
-                               return NULL;
-                       }
-                       vp->vp_integer = dval->value;
-                       vp->length = 1;
-                       break;
-
-               case PW_TYPE_SHORT:
-                       /*
-                        *      Note that ALL integers are unsigned!
-                        */
-                       vp->vp_integer = (uint32_t) strtoul(value, &p, 10);
-                       if (!*p) {
-                               if (vp->vp_integer > 65535) {
-                                       librad_log("Byte value \"%s\" is larger than 65535", value);
-                                       return NULL;
-                               }
-                               vp->length = 2;
-                               break;
-                       }
-
-                       /*
-                        *      Look for the named value for the given
-                        *      attribute.
-                        */
-                       if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
-                               librad_log("Unknown value %s for attribute %s",
-                                          value, vp->name);
-                               return NULL;
-                       }
-                       vp->vp_integer = dval->value;
-                       vp->length = 2;
-                       break;
-
                case PW_TYPE_INTEGER:
                        /*
+                        *      If it starts with a digit, it must
+                        *      be a number (or a range).
+                        *
                         *      Note that ALL integers are unsigned!
                         */
-                       vp->vp_integer = (uint32_t) strtoul(value, &p, 10);
-                       if (!*p) {
+                       if (strspn(value, "0123456789") == strlen(value)) {
+                               vp->lvalue = (uint32_t) strtoul(value, NULL, 10);
                                vp->length = 4;
-                               break;
                        }
-
                        /*
                         *      Look for the named value for the given
                         *      attribute.
                         */
-                       if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
+                       else if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
                                librad_log("Unknown value %s for attribute %s",
                                           value, vp->name);
                                return NULL;
+                       } else {
+                               vp->lvalue = dval->value;
+                               vp->length = 4;
                        }
-                       vp->vp_integer = dval->value;
-                       vp->length = 4;
                        break;
 
                case PW_TYPE_DATE:
-                       if (gettime(value, &vp->vp_date) < 0) {
+                       if (gettime(value, (time_t *)&vp->lvalue) < 0) {
                                librad_log("failed to parse time string "
                                           "\"%s\"", value);
                                return NULL;
@@ -903,9 +737,14 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                        if (strncasecmp(value, "0x", 2) == 0) {
                                vp->type = PW_TYPE_OCTETS;
                                goto do_octets;
-                       }
+                       }                       
 
+                       /*
+                        *      Special case to convert filter to binary
+                        */
+                       strNcpy(vp->strvalue, value, sizeof(vp->strvalue));
                        if (ascend_parse_filter(vp) < 0 ) {
+                         fprintf(stderr, "FUCK %s\n", value);
                                librad_log("failed to parse Ascend binary attribute: %s",
                                           librad_errstr);
                                return NULL;
@@ -924,7 +763,7 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                        if (strncasecmp(value, "0x", 2) == 0) {
                                uint8_t *us;
                                cp = value + 2;
-                               us = vp->vp_octets;
+                               us = vp->strvalue;
                                vp->length = 0;
 
 
@@ -936,10 +775,9 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                                        librad_log("Hex string is not an even length string.");
                                        return NULL;
                                }
-
-
-                               while (*cp &&
-                                      (vp->length < MAX_STRING_LEN)) {
+                               
+                               
+                               while (*cp && vp->length < MAX_STRING_LEN) {
                                        unsigned int tmp;
 
                                        if (sscanf(cp, "%02x", &tmp) != 1) {
@@ -951,62 +789,32 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                                        *(us++) = tmp;
                                        vp->length++;
                                }
+                               *us = '\0';
                        }
                        break;
 
                case PW_TYPE_IFID:
-                       if (ifid_aton(value, (unsigned char *) vp->vp_strvalue) == NULL) {
+                       if (ifid_aton(value, vp->strvalue) == NULL) {
                                librad_log("failed to parse interface-id "
                                           "string \"%s\"", value);
                                return NULL;
                        }
                        vp->length = 8;
-                       vp->vp_strvalue[vp->length] = '\0';
+                       vp->strvalue[vp->length] = '\0';
                        break;
 
                case PW_TYPE_IPV6ADDR:
-                       if (inet_pton(AF_INET6, value, vp->vp_strvalue) <= 0) {
+                       if (ipv6_addr(value, vp->strvalue) < 0) {
                                librad_log("failed to parse IPv6 address "
                                           "string \"%s\"", value);
                                return NULL;
                        }
                        vp->length = 16; /* length of IPv6 address */
-                       vp->vp_strvalue[vp->length] = '\0';
+                       vp->strvalue[vp->length] = '\0';
                        break;
                        /*
                         *  Anything else.
                         */
-               case PW_TYPE_IPV6PREFIX:
-                       p = strchr(value, '/');
-                       if (!p || ((p - value) >= 256)) {
-                               librad_log("invalid IPv6 prefix "
-                                          "string \"%s\"", value);
-                               return NULL;
-                       } else {
-                               unsigned int prefix;
-                               char buffer[256], *eptr;
-
-                               memcpy(buffer, value, p - value);
-                               buffer[p - value] = '\0';
-
-                               if (inet_pton(AF_INET6, buffer, vp->vp_strvalue + 2) <= 0) {
-                                       librad_log("failed to parse IPv6 address "
-                                                  "string \"%s\"", value);
-                                       return NULL;
-                               }
-
-                               prefix = strtoul(p + 1, &eptr, 10);
-                               if ((prefix > 128) || *eptr) {
-                                       librad_log("failed to parse IPv6 address "
-                                                  "string \"%s\"", value);
-                                       return NULL;
-                               }
-                               vp->vp_strvalue[1] = prefix;
-                       }
-                       vp->vp_strvalue[0] = '\0';
-                       vp->length = 16 + 2;
-                       break;
-
                default:
                        librad_log("unknown attribute type %d", vp->type);
                        return NULL;
@@ -1028,6 +836,7 @@ static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
        int             attr;
        const char      *p;
        VALUE_PAIR      *vp;
+       DICT_ATTR       *da;
 
        /*
         *      Unknown attributes MUST be of type 'octets'
@@ -1045,6 +854,7 @@ static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
                p += strspn(p, "0123456789");
                if (*p != 0) goto error;
 
+
                /*
                 *      Vendor-%d-Attr-%d
                 */
@@ -1080,7 +890,7 @@ static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
                int vendor;
                char buffer[256];
 
-               if (((size_t) (p - attribute)) >= sizeof(buffer)) goto error;
+               if ((p - attribute) >= sizeof(buffer)) goto error;
 
                memcpy(buffer, attribute, p - attribute);
                buffer[p - attribute] = '\0';
@@ -1105,20 +915,83 @@ static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
        }
 
        /*
-        *      We've now parsed the attribute properly, Let's create
-        *      it.  This next stop also looks the attribute up in the
-        *      dictionary, and creates the appropriate type for it.
+        *      We've now parsed the attribute properly, and verified
+        *      it to have value 'octets'.  Let's create it.
         */
-       if ((vp = paircreate(attr, PW_TYPE_OCTETS)) == NULL) {
+       if ((vp = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == NULL) {
                librad_log("out of memory");
                return NULL;
        }
+       memset(vp, 0, sizeof(VALUE_PAIR));
+       vp->type = PW_TYPE_OCTETS;
 
+       /*
+        *      It may not be valid hex characters.  If not, die.
+        */
        if (pairparsevalue(vp, value) == NULL) {
                pairfree(&vp);
                return NULL;
        }
+
+       /*
+        *      Dictionary type over-rides what the caller says.
+        *      This "converts" the parsed value into the appropriate
+        *      type.
+        *
+        *      Also, normalize the name of the attribute...
+        *
+        *      Much of this code is copied from paircreate()
+        */
+       if ((da = dict_attrbyvalue(attr)) != NULL) {
+               strcpy(vp->name, da->name);
+               vp->type = da->type;
+               vp->flags = da->flags;
+
+               /*
+                *      Sanity check the type for length.  We don't
+                *      want to look at attributes which are of the
+                *      wrong length.
+                */
+               switch (vp->type) {
+               case PW_TYPE_DATE:
+               case PW_TYPE_INTEGER:
+               case PW_TYPE_IPADDR: /* always kept in network byte order */
+                       if (vp->length != 4) {
+                       length_error:
+                               pairfree(&vp);
+                               librad_log("Attribute has invalid length");
+                               return NULL;
+                       }
+                       memcpy(&vp->lvalue, vp->strvalue, sizeof(vp->lvalue));
+                       break;
+
+               case PW_TYPE_IFID:
+                       if (vp->length != 8) goto length_error;
+                       break;
+
+               case PW_TYPE_IPV6ADDR:
+                       if (vp->length != 16) goto length_error;
+                       break;
+
+#ifdef ASCEND_BINARY
+               case PW_TYPE_ABINARY:
+                       if (vp->length != 32) goto length_error;
+                       break;
+#endif
+               default:        /* string, octets, etc. */
+                       break;
+               }
+
+       } else if (VENDOR(attr) == 0) {
+               sprintf(vp->name, "Attr-%u", attr);
+       } else {
+               sprintf(vp->name, "Vendor-%u-Attr-%u",
+                       VENDOR(attr), attr & 0xffff);
+       }
+
+       vp->attribute = attr;
        vp->operator = (operator == 0) ? T_OP_EQ : operator;
+       vp->next = NULL;
 
        return vp;
 }
@@ -1145,12 +1018,7 @@ VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
        found_tag = 0;
        tag = 0;
 
-       ts = strrchr(attribute, ':');
-       if (ts && !ts[1]) {
-               librad_log("Invalid tag for attribute %s", attribute);
-               return NULL;
-       }
-
+       ts = strrchr( attribute, ':' );
        if (ts && ts[1]) {
                 /* Colon found with something behind it */
                 if (ts[1] == '*' && ts[2] == 0) {
@@ -1178,11 +1046,18 @@ VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
                return pairmake_any(attribute, value, operator);
        }
 
-       if ((vp = pairalloc(da)) == NULL) {
+       if ((vp = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == NULL) {
                librad_log("out of memory");
                return NULL;
        }
+
+       memset(vp, 0, sizeof(VALUE_PAIR));
+       vp->attribute = da->attr;
+       vp->type = da->type;
        vp->operator = (operator == 0) ? T_OP_EQ : operator;
+       strcpy(vp->name, da->name);
+       vp->flags = da->flags;
+       vp->next = NULL;
 
        /*      Check for a tag in the 'Merit' format of:
         *      :Tag:Value.  Print an error if we already found
@@ -1229,7 +1104,7 @@ VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
                 */
        case T_OP_CMP_TRUE:
        case T_OP_CMP_FALSE:
-               vp->vp_strvalue[0] = '\0';
+               vp->strvalue[0] = '\0';
                vp->length = 0;
                return vp;
                break;
@@ -1273,14 +1148,6 @@ VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
 #endif
        }
 
-       /*
-        *      FIXME: if (strcasecmp(attribute, vp->name) != 0)
-        *      then the user MAY have typed in the attribute name
-        *      as Vendor-%d-Attr-%d, and the value MAY be octets.
-        *
-        *      We probably want to fix pairparsevalue to accept
-        *      octets as values for any attribute.
-        */
        if (value && (pairparsevalue(vp, value) == NULL)) {
                pairbasicfree(vp);
                return NULL;
@@ -1289,29 +1156,6 @@ VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator)
        return vp;
 }
 
-
-/*
- *     [a-zA-Z0-9_-:]+
- */
-static const int valid_attr_name[256] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-       0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
-       0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
 /*
  *     Read a valuepair from a buffer, and advance pointer.
  *     Sets *eol to T_EOL if end of line was encountered.
@@ -1320,59 +1164,34 @@ VALUE_PAIR *pairread(char **ptr, LRAD_TOKEN *eol)
 {
        char            buf[64];
        char            attr[64];
-       char            value[512];
-       char            *p, *q;
+       char            value[520];
+       char            *p;
        LRAD_TOKEN      token, t, xlat;
        VALUE_PAIR      *vp;
-       size_t          len;
 
-       *eol = T_OP_INVALID;
+       *eol = T_INVALID;
 
-       p = *ptr;
-       while ((*p == ' ') || (*p == '\t')) p++;
+       /* Get attribute. */
+       token = gettoken(ptr, attr, sizeof(attr));
 
-       if (!*p) {
-               *eol = T_OP_INVALID;
-               librad_log("No token read where we expected an attribute name");
-               return NULL;
-       }
-
-       if (*p == '#') {
-               *eol = T_HASH;
+       /*  If it's a comment, then exit, as we haven't read a pair */
+       if (token == T_HASH) {
+               *eol = token;
                librad_log("Read a comment instead of a token");
                return NULL;
        }
 
-       q = attr;
-       for (len = 0; len < sizeof(attr); len++) {
-               if (valid_attr_name[(int)*p]) {
-                       *q++ = *p++;
-                       continue;
-               }
-               break;
-       }
-
-       if (len == sizeof(attr)) {
-               *eol = T_OP_INVALID;
-               librad_log("Attribute name is too long");
+       /*  It's not a comment, so it MUST be an attribute */
+       if ((token == T_EOL) ||
+           (attr[0] == 0)) {
+               librad_log("No token read where we expected an attribute name");
                return NULL;
        }
 
-       /*
-        *      We may have Foo-Bar:= stuff, so back up.
-        */
-       if (attr[len - 1] == ':') {
-               p--;
-               len--;
-       }
-
-       attr[len] = '\0';
-       *ptr = p;
-
-       /* Now we should have an operator here. */
+       /* Now we should have an '=' here. */
        token = gettoken(ptr, buf, sizeof(buf));
        if (token < T_EQSTART || token > T_EQEND) {
-               librad_log("expecting operator");
+               librad_log("expecting '='");
                return NULL;
        }
 
@@ -1398,7 +1217,6 @@ VALUE_PAIR *pairread(char **ptr, LRAD_TOKEN *eol)
                *ptr = p;
        }
 
-       vp = NULL;
        switch (xlat) {
                /*
                 *      Make the full pair now.
@@ -1413,17 +1231,13 @@ VALUE_PAIR *pairread(char **ptr, LRAD_TOKEN *eol)
        case T_DOUBLE_QUOTED_STRING:
                p = strchr(value, '%');
                if (p && (p[1] == '{')) {
-                       if (strlen(value) >= sizeof(vp->vp_strvalue)) {
-                               librad_log("Value too long");
-                               return NULL;
-                       }
                        vp = pairmake(attr, NULL, token);
                        if (!vp) {
-                               *eol = T_OP_INVALID;
+                               *eol = T_INVALID;
                                return NULL;
                        }
 
-                       strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
+                       strNcpy(vp->strvalue, value, sizeof(vp->strvalue));
                        vp->flags.do_xlat = 1;
                        vp->length = 0;
                } else {
@@ -1436,28 +1250,23 @@ VALUE_PAIR *pairread(char **ptr, LRAD_TOKEN *eol)
                 *      Mark the pair to be allocated later.
                 */
        case T_BACK_QUOTED_STRING:
-               if (strlen(value) >= sizeof(vp->vp_strvalue)) {
-                       librad_log("Value too long");
-                       return NULL;
-               }
-
                vp = pairmake(attr, NULL, token);
                if (!vp) {
-                       *eol = T_OP_INVALID;
+                       *eol = T_INVALID;
                        return NULL;
                }
 
                vp->flags.do_xlat = 1;
-               strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
+               strNcpy(vp->strvalue, value, sizeof(vp->strvalue));
                vp->length = 0;
                break;
        }
 
        /*
-        *      If we didn't make a pair, return an error.
+        *      If we didn't make a pair, return an error.
         */
        if (!vp) {
-               *eol = T_OP_INVALID;
+               *eol = T_INVALID;
                return NULL;
        }
 
@@ -1472,7 +1281,7 @@ LRAD_TOKEN userparse(char *buffer, VALUE_PAIR **first_pair)
 {
        VALUE_PAIR      *vp;
        char            *p;
-       LRAD_TOKEN      last_token = T_OP_INVALID;
+       LRAD_TOKEN      last_token = T_INVALID;
        LRAD_TOKEN      previous_token;
 
        /*
@@ -1542,7 +1351,7 @@ VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix)
                last_token = userparse(buf, &vp);
                if (!vp) {
                        if (last_token != T_EOL) {
-                               librad_perror("%s", errprefix);
+                               librad_perror(errprefix);
                                error = 1;
                                break;
                        }
@@ -1560,170 +1369,3 @@ VALUE_PAIR *readvp2(FILE *fp, int *pfiledone, const char *errprefix)
        return error ? NULL: list;
 }
 
-
-
-/*
- *     Compare two pairs, using the operator from "one".
- *
- *     i.e. given two attributes, it does:
- *
- *     (two->data) (one->operator) (one->data)
- *
- *     e.g. "foo" != "bar"
- *
- *     Returns true (comparison is true), or false (comparison is not true);
- */
-int paircmp(VALUE_PAIR *one, VALUE_PAIR *two)
-{
-       int compare;
-
-       switch (one->operator) {
-       case T_OP_CMP_TRUE:
-               return (two != NULL);
-
-       case T_OP_CMP_FALSE:
-               return (two == NULL);
-
-               /*
-                *      One is a regex, compile it, print two to a string,
-                *      and then do string comparisons.
-                */
-       case T_OP_REG_EQ:
-       case T_OP_REG_NE:
-#ifndef HAVE_REGEX_H
-               return -1;
-#else
-               {
-                       regex_t reg;
-                       char buffer[MAX_STRING_LEN * 4 + 1];
-
-                       compare = regcomp(&reg, one->vp_strvalue,
-                                         REG_EXTENDED);
-                       if (compare != 0) {
-                               regerror(compare, &reg, buffer, sizeof(buffer));
-                               librad_log("Illegal regular expression in attribute: %s: %s",
-                                          one->name, buffer);
-                               return -1;
-                       }
-
-                       vp_prints_value(buffer, sizeof(buffer), two, 0);
-
-                       /*
-                        *      Don't care about substring matches,
-                        *      oh well...
-                        */
-                       compare = regexec(&reg, buffer, 0, NULL, 0);
-
-                       regfree(&reg);
-                       if (one->operator == T_OP_REG_EQ) return (compare == 0);
-                       return (compare != 0);
-               }
-#endif
-
-       default:                /* we're OK */
-               break;
-       }
-
-       /*
-        *      After doing the previous check for special comparisons,
-        *      do the per-type comparison here.
-        */
-       switch (one->type) {
-       case PW_TYPE_ABINARY:
-       case PW_TYPE_OCTETS:
-       {
-               size_t length;
-               const uint8_t *p, *q;
-
-               if (one->length < two->length) {
-                       length = one->length;
-               } else {
-                       length = two->length;
-               }
-
-               p = two->vp_octets;
-               q = one->vp_octets;
-               while (length) {
-                       compare = ((int) *p) - ((int) *q);
-                       if (compare != 0) goto type_switch;
-               }
-
-               /*
-                *      Contents are the same.  The return code
-                *      is therefore the difference in lengths.
-                *
-                *      i.e. "0x00" is smaller than "0x0000"
-                */
-               compare = two->length - one->length;
-       }
-               break;
-
-       case PW_TYPE_STRING:
-               if (one->flags.caseless) {
-                       compare = strcasecmp(two->vp_strvalue,
-                                            one->vp_strvalue);
-               } else {
-                       compare = strcmp(two->vp_strvalue,
-                                        one->vp_strvalue);
-               }
-               break;
-
-       case PW_TYPE_BYTE:
-       case PW_TYPE_SHORT:
-       case PW_TYPE_INTEGER:
-       case PW_TYPE_DATE:
-               compare = two->vp_integer - one->vp_integer;
-               break;
-
-       case PW_TYPE_IPADDR:
-               compare = ntohl(two->vp_ipaddr) - ntohl(one->vp_ipaddr);
-               break;
-
-       case PW_TYPE_IPV6ADDR:
-               compare = memcmp(&two->vp_ipv6addr, &one->vp_ipv6addr,
-                                sizeof(two->vp_ipv6addr));
-               break;
-
-       case PW_TYPE_IPV6PREFIX:
-               compare = memcmp(&two->vp_ipv6prefix, &one->vp_ipv6prefix,
-                                sizeof(two->vp_ipv6prefix));
-               break;
-
-       case PW_TYPE_IFID:
-               compare = memcmp(&two->vp_ifid, &one->vp_ifid,
-                                sizeof(two->vp_ifid));
-               break;
-
-       default:
-               return 0;       /* unknown type */
-       }
-
-       /*
-        *      Now do the operator comparison.
-        */
- type_switch:
-       switch (one->operator) {
-       case T_OP_CMP_EQ:
-               return (compare == 0);
-
-       case T_OP_NE:
-               return (compare != 0);
-
-       case T_OP_LT:
-               return (compare < 0);
-
-       case T_OP_GT:
-               return (compare > 0);
-
-       case T_OP_LE:
-               return (compare <= 0);
-
-       case T_OP_GE:
-               return (compare >= 0);
-
-       default:
-               return 0;
-       }
-
-       return 0;
-}
diff --git a/src/main/00-OLD/Make.inc b/src/main/00-OLD/Make.inc
new file mode 100644 (file)
index 0000000..44defb7
--- /dev/null
@@ -0,0 +1,117 @@
+#
+# Makefile     RADIUS - 
+#              Remote Authentication Dial In User Service
+#
+#
+
+SERVER_OBJS    = radiusd.o dict.o files.o util.o md5.o attrprint.o \
+                       acct.o radius.o pam.o log.o version.o proxy.o \
+                       exec.o auth.o timestr.o cache.o
+SERVERDBM_OBJS = radiusddbm.o dict.o filesdbm.o util.o md5.o attrprint.o \
+                       acct.o radius.o pam.o log.o versiondbm.o proxy.o \
+                       exec.o auth.o timestr.o cache.o
+SERVER_SRCS    = radiusd.c dict.c files.c util.c md5.c attrprint.c acct.c \
+                       radius.c pam.c log.c version.c proxy.c \
+                       exec.c auth.c timestr.c cache.c
+INCLUDES       = radius.h conf.h
+
+all:   radiusd radwho radzap raduse radtest
+
+dbm:   radiusd.dbm builddbm
+
+radiusd: $(SERVER_OBJS)
+       $(CC) $(LDFLAGS) -o radiusd $(SERVER_OBJS) $(LIBS) $(LCRYPT) $(PAMLIB)
+
+radiusd.dbm: $(SERVERDBM_OBJS)
+       $(CC) $(LDFLAGS) -o radiusd.dbm $(SERVERDBM_OBJS) $(LIBS) $(LCRYPT) \
+                        $(DBMLIB) $(PAMLIB)
+
+radiusd.o: radiusd.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c radiusd.c
+
+radiusddbm.o: radiusd.c $(INCLUDES)
+       $(CC) $(CFLAGS) $(DBM) -c radiusd.c -o radiusddbm.o
+
+acct.o: acct.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c acct.c
+
+attrprint.o: attrprint.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c attrprint.c
+
+dict.o: dict.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c dict.c
+
+files.o: files.c $(INCLUDES)
+       $(CC) $(CFLAGS) $(PAM) -c files.c
+
+filesdbm.o: files.c $(INCLUDES)
+       $(CC) $(CFLAGS) $(DBM) $(PAM) -o filesdbm.o -c files.c
+
+radius.o: radius.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c radius.c
+
+util.o: util.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c util.c
+
+pam.o:  pam.c $(INCLUDES)
+       $(CC) $(CFLAGS) $(PAM) -c pam.c
+
+cache.o:  cache.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c cache.c 
+
+proxy.o:  proxy.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c proxy.c
+
+exec.o:  exec.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c exec.c
+
+auth.o:  auth.c $(INCLUDES)
+       $(CC) $(CFLAGS) $(PAM) -c auth.c
+
+version.o: version.c $(INCLUDES)
+       $(CC) $(CFLAGS) -o version.o -c version.c
+
+versiondbm.o: version.c $(INCLUDES)
+       $(CC) $(CFLAGS) $(DBM) -o versiondbm.o -c version.c
+
+radtest: radtest.o md5.o util.o dict.o attrprint.o log.o
+       $(CC) $(LDFLAGS) -o radtest radtest.o md5.o util.o \
+               dict.o attrprint.o log.o $(LIBS)
+
+radtest.o: radtest.c $(INCLUDES)
+       $(CC) $(CFLAGS) -c radtest.c
+
+md5.o: md5.c md5.h
+       $(CC) $(CFLAGS) -c md5.c
+
+builddbm: builddbm.o
+       $(CC) $(LDFLAGS) -o builddbm builddbm.o $(DBMLIB) $(LIBS)
+
+builddbm.o: builddbm.c
+       $(CC) $(CFLAGS) -c $(DBM) builddbm.c
+
+radwho: radwho.o util.o
+       $(CC) $(LDFLAGS) -o radwho radwho.o util.o $(LIBS)
+
+raduse: raduse.o
+       $(CC) $(LDFLAGS) -o raduse raduse.o $(LIBS)
+
+radzap: radzap.o util.o
+       $(CC) $(LDFLAGS) -o radzap radzap.o util.o $(LIBS)
+
+lint:
+       -lint -hbacvx -DLINT $(SERVER_SRCS)
+       -lint -hbacvx -DLINT ../radpass.c ../md5.c ../util.c
+
+clean:
+       rm -f *.o radiusd radwho raduse radtest radzap builddbm radiusd.dbm
+       rm -f ../build ../debian/substvars ../debian/files
+
+install:
+       install -m 755 -s radiusd $(SBINDIR)/radiusd
+       install -m 755 -s radwho  $(BINDIR)
+       install -m 755 -s raduse  $(BINDIR)
+       install -m 755 -s radzap  $(BINDIR)
+       install -m 755    checkrad.pl $(SBINDIR)/checkrad
+       install -m 755    radlast $(BINDIR)
+
diff --git a/src/main/00-OLD/Makefile b/src/main/00-OLD/Makefile
new file mode 100644 (file)
index 0000000..47ff6d2
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Makefile     Radius Makefile for Linux (2.0.x, lib5 or libc6)
+#
+#
+
+#
+#      Autoselect -lshadow and -lcrypt
+#
+ifneq ($(wildcard /usr/lib/libshadow.a),)
+LSHADOW        = -lshadow
+endif
+ifneq ($(wildcard /usr/lib/libcrypt.a),)
+LCRYPT = -lcrypt
+endif
+
+CC     = gcc
+CFLAGS = -Wall -g # -DNOSHADOW
+LDFLAGS        = # -s # tatic
+LIBS   = $(LSHADOW)
+
+DBM    = -DNDBM
+DBMLIB = -ldb
+
+# Uncomment these if you want PAM support
+#PAM   = -DPAM
+#PAMLIB        = -lpam -ldl
+
+BINDIR  = /usr/local/bin
+SBINDIR = /usr/local/sbin
+
+include Make.inc
diff --git a/src/main/00-OLD/Makefile.BSD b/src/main/00-OLD/Makefile.BSD
new file mode 100644 (file)
index 0000000..900c5e4
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Makefile     Radius Makefile for BSD (FreeBSD, NetBSD, etc)
+#
+#
+
+CC     = gcc
+CFLAGS = -Wall -g -DNOSHADOW
+LDFLAGS        = # -s #tatic
+LIBS   =
+LCRYPT = -lcrypt
+
+DBM     = -DNDBM
+DBMLIB  = #-ldb
+
+#PAM   = -DPAM
+#PAMLIB        = -lpam
+
+BINDIR  = /usr/local/bin
+SBINDIR = /usr/local/sbin
+
+.include "Make.inc"
diff --git a/src/main/00-OLD/Makefile.lnx b/src/main/00-OLD/Makefile.lnx
new file mode 100644 (file)
index 0000000..47ff6d2
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Makefile     Radius Makefile for Linux (2.0.x, lib5 or libc6)
+#
+#
+
+#
+#      Autoselect -lshadow and -lcrypt
+#
+ifneq ($(wildcard /usr/lib/libshadow.a),)
+LSHADOW        = -lshadow
+endif
+ifneq ($(wildcard /usr/lib/libcrypt.a),)
+LCRYPT = -lcrypt
+endif
+
+CC     = gcc
+CFLAGS = -Wall -g # -DNOSHADOW
+LDFLAGS        = # -s # tatic
+LIBS   = $(LSHADOW)
+
+DBM    = -DNDBM
+DBMLIB = -ldb
+
+# Uncomment these if you want PAM support
+#PAM   = -DPAM
+#PAMLIB        = -lpam -ldl
+
+BINDIR  = /usr/local/bin
+SBINDIR = /usr/local/sbin
+
+include Make.inc
diff --git a/src/main/00-OLD/Makefile.osf b/src/main/00-OLD/Makefile.osf
new file mode 100644 (file)
index 0000000..5414fd3
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Makefile     Radius Makefile for OSF/Unix (Digital)
+#
+#              Add "-DOSFC2" to CFLAGS and "-lsecurity" to LIBS
+#              if you want to compile for OSF with C2 security
+#
+
+CC     = gcc
+CFLAGS = -g -Wall -Wno-unused -DNOSHADOW
+LDFLAGS        = # -s #tatic
+LIBS   = 
+LCRYPT =
+
+DBM     = #-DNDBM
+DBMLIB  = #-ldb
+
+#PAM   = -DPAM
+#PAMLIB        = -lpam
+
+BINDIR  = /usr/local/bin
+SBINDIR = /usr/local/sbin
+
+include Make.inc
diff --git a/src/main/00-OLD/Makefile.sunos5 b/src/main/00-OLD/Makefile.sunos5
new file mode 100644 (file)
index 0000000..6cecbaf
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Makefile     Radius Makefile for Solaris 2.5.x
+#
+
+CC     = gcc
+CFLAGS = -g # -DNOSHADOW
+LDFLAGS        = # -s #tatic
+LIBS   = -lsocket -lnsl
+LCRYPT =
+
+DBM     = #-DNDBM
+DBMLIB  = #-ldb
+
+#PAM   = -DPAM
+#PAMLIB        = -lpam
+
+BINDIR  = /usr/local/bin
+SBINDIR = /usr/local/sbin
+
+include Make.inc
index 5993bc4..ef86887 100644 (file)
@@ -4,19 +4,18 @@
 
 include ../../Make.inc
 
-SERVER_SRCS    = acct.c auth.c client.c conffile.c crypt.c exec.c files.c \
-                 listen.c log.c mainconfig.c modules.c modcall.c \
-                 radiusd.c radius_snmp.c \
-                 session.c smux.c threads.c util.c valuepair.c version.c  \
-                 xlat.c event.c realms.c
+SERVER_SRCS    = acct.c auth.c client.c conffile.c exec.c files.c log.c   \
+                 mainconfig.c modules.c modcall.c nas.c proxy.c radiusd.c \
+                 radius_snmp.c request_list.c session.c smux.c threads.c  \
+                 util.c valuepair.c version.c timestr.c xlat.c
 
 SERVER_OBJS    += $(SERVER_SRCS:.c=.lo)
 
 INCLUDES       = ../include/autoconf.h ../include/conf.h    \
                  ../include/libradius.h ../include/radius.h \
-                 ../include/radiusd.h ../include/ident.h
+                 ../include/radiusd.h
 
-CFLAGS         += -I$(top_builddir)/src
+CFLAGS         += -I../include
 CFLAGS         += -DHOSTINFO=\"${HOSTINFO}\"
 CFLAGS         += -DRADIUSD_VERSION=\"${RADIUSD_VERSION}\"
 CFLAGS         += $(SNMP_INCLUDE)
@@ -24,15 +23,7 @@ CFLAGS               += $(OPENSSL_INCLUDE)
 VFLAGS         = -DRADIUSD_MAJOR_VERSION=$(RADIUSD_MAJOR_VERSION)
 VFLAGS         += -DRADIUSD_MINOR_VERSION=$(RADIUSD_MINOR_VERSION)
 MODULE_LIBS    = $(STATIC_MODULES)
-BINARIES       = radiusd radwho radclient
-
-#
-#  The RADIUS sniffer
-#
-PCAP_LIBS      = @PCAP_LIBS@
-ifneq ($(PCAP_LIBS),)
-BINARIES       += radsniff
-endif
+BINARIES       = radiusd radclient radrelay radwho
 
 #
 #  Not using shared libraries, add in ALL known static modules
@@ -49,15 +40,21 @@ SUB_MODULES += rlm_eap_peap rlm_eap_mschapv2 rlm_eap_gtc
 SUB_MODULES += rlm_sql_db2 rlm_sql_freetds rlm_sql_iodbc rlm_sql_mysql
 SUB_MODULES += rlm_sql_oracle rlm_sql_postgresql rlm_sql_sybase rlm_sql_unixodbc
 LIBS        += $(shell test -f ../modules/rlm_eap/libeap/libeap.la && echo ../modules/rlm_eap/libeap/libeap.la)
+ifneq ($(OPENSSL_LIBS),)
+LIBS += $(OPENSSL_LIBS)
+endif
 
 MODULE_LIBS    += $(shell for x in $(MODULES);do test -f ../modules/$$x/$$x.la && echo -dlpreopen ../modules/$$x/$$x.la;done)
 MODULE_LIBS    += $(shell for x in $(SUB_MODULES);do test -f ../modules/*/types/$$x/$$x.la && echo -dlpreopen ../modules/*/types/$$x/$$x.la;done)
 MODULE_LIBS    += $(shell for x in $(SUB_MODULES);do test -f ../modules/*/drivers/$$x/$$x.la && echo -dlpreopen ../modules/*/drivers/$$x/$$x.la;done)
-MODULE_OBJS     += $(shell for x in $(MODULES);do test -f ../modules/$$x/$$x.la && echo ../modules/$$x/$$x.la;done)
-MODULE_OBJS     += $(shell for x in $(SUB_MODULES);do test -f ../modules/*/types/$$x/$$x.la && echo ../modules/*/types/$$x/$$x.la;done)
+MODULE_OBJS     += $(shell for x in $(MODULES);do test -f ../modules/$$x/$$x.la && echo ../modules/$$x/$$x.la;done)     
+MODULE_OBJS     += $(shell for x in $(SUB_MODULES);do test -f ../modules/*/types/$$x/$$x.la && echo ../modules/*/types/$$x/$$x.la;done)         
 MODULE_OBJS     += $(shell for x in $(SUB_MODULES);do test -f ../modules/*/drivers/$$x/$$x.la && echo ../modules/*/drivers/$$x/$$x.la;done)
 endif
 
+LIBS           += ../lib/libradius.la
+
+
 all: $(BINARIES)
 
 $(SERVER_OBJS): $(INCLUDES)
@@ -65,10 +62,10 @@ $(SERVER_OBJS): $(INCLUDES)
 radiusd: $(SERVER_OBJS) $(MODULE_OBJS) ../lib/libradius.la
        $(LIBTOOL) --mode=link $(CC) -export-dynamic -dlopen self \
                $(LDFLAGS) -pie $(LINK_MODE) -o $@ $(SERVER_OBJS)      \
-               $(MODULE_LIBS) ../lib/libradius.la $(LIBS) $(SNMP_LIBS) \
-               $(LCRYPT) $(PTHREADLIB) $(LIBLTDL) $(OPENSSL_LIBS)
+               $(MODULE_LIBS) $(LIBS) $(SNMP_LIBS) $(PTHREADLIB) \
+               $(LIBLTDL) $(OPENSSL_LIBS)
 
-radiusd.lo: radiusd.c  ../include/modules.h ../include/modcall.h ../include/modpriv.h
+radiusd.lo: radiusd.c ../include/request_list.h ../include/modules.h ../include/modcall.h ../include/modpriv.h
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radiusd.c
 
 acct.lo: acct.c ../include/modules.h
@@ -83,18 +80,12 @@ client.lo: client.c ../include/conffile.h
 conffile.lo: conffile.c ../include/conffile.h ../include/modules.h
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c conffile.c
 
-crypt.lo: crypt.c
-       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c crypt.c
-
 exec.lo: exec.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c exec.c
 
 files.lo: files.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c files.c
 
-listen.lo: listen.c
-       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c listen.c
-
 log.lo: log.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c log.c
 
@@ -107,14 +98,17 @@ modcall.lo: modcall.c
 modules.lo: modules.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(VFLAGS) $(INCLTDL) -c modules.c
 
+nas.lo: nas.c
+       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c nas.c
+
+proxy.lo: proxy.c
+       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c proxy.c
+
 radius_snmp.lo: radius_snmp.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radius_snmp.c
 
-event.lo: event.c
-       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c event.c
-
-realms.lo: realms.c
-       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c realms.c
+request_list.lo: request_list.c
+       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c request_list.c
 
 session.lo: session.c ../include/modules.h
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c session.c
@@ -125,6 +119,9 @@ smux.lo: smux.c
 threads.lo: threads.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c threads.c
 
+timestr.lo: timestr.c
+       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c timestr.c
+
 util.lo: util.c
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c util.c
 
@@ -145,19 +142,19 @@ radclient.lo: radclient.c $(INCLUDES)
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radclient.c
 
 radclient: radclient.lo ../lib/libradius.la
-       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radclient radclient.lo ../lib/libradius.la $(LIBS)
+       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radclient radclient.lo $(LIBS)
 
-radsniff.lo: radsniff.c $(INCLUDES) ../include/radsniff.h
-       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radsniff.c
+radrelay.lo: radrelay.c $(INCLUDES)
+       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radrelay.c
 
-radsniff: radsniff.lo ../lib/libradius.la
-       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radsniff radsniff.lo ../lib/libradius.la $(LIBS) $(PCAP_LIBS)
+radrelay: radrelay.lo util.lo nas.lo client.lo log.lo conffile.lo files.lo xlat.lo ../lib/libradius.la
+       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radrelay radrelay.lo util.lo nas.lo client.lo log.lo conffile.lo files.lo xlat.lo $(LIBS)
 
 radwho.lo: radwho.c $(INCLUDES)
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radwho.c
 
 radwho: radwho.lo util.lo log.lo conffile.lo ../lib/libradius.la
-       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radwho radwho.lo util.lo log.lo conffile.lo ../lib/libradius.la $(LIBS)
+       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radwho radwho.lo util.lo log.lo conffile.lo $(LIBS)
 
 
 clean:
@@ -166,10 +163,8 @@ clean:
 install:
        $(LIBTOOL) --mode=install $(INSTALL) -m 755 $(INSTALLSTRIP) radiusd$(EXEEXT)    $(R)$(sbindir)
        $(LIBTOOL) --mode=install $(INSTALL) -m 755 $(INSTALLSTRIP) radclient$(EXEEXT)  $(R)$(bindir)
+       $(LIBTOOL) --mode=install $(INSTALL) -m 755 $(INSTALLSTRIP) radrelay$(EXEEXT)   $(R)$(bindir)
        $(LIBTOOL) --mode=install $(INSTALL) -m 755 $(INSTALLSTRIP) radwho$(EXEEXT)     $(R)$(bindir)
-ifneq ($(PCAP_LIBS),)
-       $(LIBTOOL) --mode=install $(INSTALL) -m 755 $(INSTALLSTRIP) radsniff$(EXEEXT)   $(R)$(bindir)
-endif
        $(INSTALL) -m 755    checkrad.pl                $(R)$(sbindir)/checkrad
        $(INSTALL) -m 755    radlast                    $(R)$(bindir)
        $(INSTALL) -m 755    radtest                    $(R)$(bindir)
index f31c092..09f0412 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2000  Alan Curry <pacman@world.std.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "autoconf.h"
+
+#include <stdlib.h>
+
+#include "radiusd.h"
+#include "modules.h"
 
 /*
  *     rad_accounting: call modules.
@@ -43,7 +46,10 @@ int rad_accounting(REQUEST *request)
         *      Run the modules only once, before proxying.
         */
        if (!request->proxy) {
+               char            *exec_program;
+               int             exec_wait;
                VALUE_PAIR      *vp;
+               int             rcode;
                int             acct_type = 0;
 
                result = module_preacct(request);
@@ -79,8 +85,8 @@ int rad_accounting(REQUEST *request)
                 */
                vp = pairfind(request->config_items, PW_ACCT_TYPE);
                if (vp) {
-                       DEBUG2("  Found Acct-Type %s", vp->vp_strvalue);
-                       acct_type = vp->vp_integer;
+                       DEBUG2("  Found Acct-Type %s", vp->strvalue);
+                       acct_type = vp->lvalue;
                }
                result = module_accounting(acct_type, request);
                switch (result) {
@@ -111,6 +117,62 @@ int rad_accounting(REQUEST *request)
                }
 
                /*
+                *      See if we need to execute a program.
+                *      FIXME: somehow cache this info, and only execute the
+                *      program when we receive an Accounting-START packet.
+                *      Only at that time we know dynamic IP etc.
+                */
+               exec_program = NULL;
+               exec_wait = 0;
+               if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM)) != NULL) {
+                       exec_wait = 0;
+                       exec_program = strdup((char *)vp->strvalue);
+                       pairdelete(&request->reply->vps, PW_EXEC_PROGRAM);
+               }
+
+               if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) {
+                       free(exec_program);
+                       exec_wait = 1;
+                       exec_program = strdup((char *)vp->strvalue);
+                       pairdelete(&request->reply->vps, PW_EXEC_PROGRAM_WAIT);
+               }
+
+               /*
+                *      If we want to exec a program, but wait for it,
+                *      do it first before sending the reply, or
+                *      proxying the packet.
+                *
+                *      If we're NOT waiting, then also do this now, but
+                *      don't check the return code.
+                */
+               if (exec_program) {
+                       /*
+                        *      Wait for the answer.
+                        *      Don't look for a user message.
+                        *      Do look for returned VP's.
+                        */
+                       rcode = radius_exec_program(exec_program, request,
+                                                   exec_wait, NULL, 0,
+                                                   request->packet->vps, &vp);
+                       free(exec_program);
+
+                       /*
+                        *      Always add the value-pairs to the reply.
+                        *
+                        *      If we're not waiting, then the pairs
+                        *      will be empty, so this won't matter.
+                        */
+                       pairmove(&request->reply->vps, &vp);
+                       pairfree(&vp);
+
+                       if (exec_wait) {
+                               if (rcode != 0) {
+                                       return result;
+                               }
+                       }
+               }
+
+               /*
                 *      Maybe one of the preacct modules has decided
                 *      that a proxy should be used.
                 */
@@ -121,9 +183,10 @@ int rad_accounting(REQUEST *request)
                         *      Check whether Proxy-To-Realm is
                         *      a LOCAL realm.
                         */
-                       realm = realm_find(vp->vp_strvalue);
-                       if (realm && !realm->acct_pool) {
-                               DEBUG("rad_accounting: Cancelling proxy to realm %s, as it is a LOCAL realm.", realm->name);
+                       realm = realm_find(vp->strvalue, TRUE);
+                       if (realm != NULL &&
+                           realm->acct_ipaddr == htonl(INADDR_NONE)) {
+                               DEBUG("rad_accounting: Cancelling proxy to realm %s, as it is a LOCAL realm.", realm->realm);
                                pairdelete(&request->config_items, PW_PROXY_TO_REALM);
                        } else {
                                /*
index 1a9b418..2b57e71 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Jeff Carneal <jeff@apex.net>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
 
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#include "radiusd.h"
+#include "modules.h"
+
 /*
  *     Return a short string showing the terminal server, port
  *     and calling station ID.
@@ -43,16 +50,62 @@ char *auth_name(char *buf, size_t buflen, REQUEST *request, int do_cli) {
        if ((cli = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) == NULL)
                do_cli = 0;
        if ((pair = pairfind(request->packet->vps, PW_NAS_PORT)) != NULL)
-               port = pair->vp_integer;
+               port = pair->lvalue;
 
        snprintf(buf, buflen, "from client %.128s port %u%s%.128s",
-                       client_name_old(&request->packet->src_ipaddr), port,
-                       (do_cli ? " cli " : ""), (do_cli ? (char *)cli->vp_strvalue : ""));
+                       client_name(request->packet->src_ipaddr), port,
+                       (do_cli ? " cli " : ""), (do_cli ? (char *)cli->strvalue : ""));
 
        return buf;
 }
 
 
+/*
+ *     Check if account has expired, and if user may login now.
+ */
+static int check_expiration(REQUEST *request)
+{
+       VALUE_PAIR *check_item;
+       VALUE_PAIR *vp;
+
+       check_item = pairfind(request->config_items, PW_EXPIRATION);
+
+       if (!check_item)  return 0;
+
+       /*
+        *      Has this user's password expired?
+        *
+        *      If so, remove ALL reply attributes,
+        *      and add our own Reply-Message, saying
+        *      why they're being rejected.
+        */
+       if (((time_t) check_item->lvalue) <= request->timestamp) {
+               vp = pairmake("Reply-Message",
+                             "Password Has Expired\r\n",
+                             T_OP_ADD);
+               pairfree(&request->reply->vps);
+               request->reply->vps = vp;
+               return -1;
+       }
+
+#define EXP_TIMEOUT ((uint32_t) (((time_t) check_item->lvalue) - request->timestamp))
+       /*
+        *      Otherwise, set the Session-Timeout based on expiration.
+        */
+       vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT);
+       if (!vp) {
+               vp = pairmake("Session-Timeout", "0", T_OP_SET);
+               if (!vp) return -1; /* out of memory */
+               
+               vp->lvalue = EXP_TIMEOUT;
+               pairadd(&request->reply->vps, vp);
+       } else if (vp->lvalue > EXP_TIMEOUT) {
+               vp->lvalue = EXP_TIMEOUT;
+       } /* else Session-Timeout is smaller than Expiration, leave it alone */
+
+       return 0;
+}
+
 
 /*
  * Make sure user/pass are clean
@@ -84,7 +137,7 @@ static int rad_authlog(const char *msg, REQUEST *request, int goodpass) {
        if (username == NULL) {
                strcpy(clean_username, "<no User-Name attribute>");
        } else {
-               librad_safeprint((char *)username->vp_strvalue,
+               librad_safeprint((char *)username->strvalue,
                                username->length,
                                clean_username, sizeof(clean_username));
        }
@@ -94,21 +147,11 @@ static int rad_authlog(const char *msg, REQUEST *request, int goodpass) {
         */
        if (mainconfig.log_auth_badpass || mainconfig.log_auth_goodpass) {
                if (!request->password) {
-                       VALUE_PAIR *auth_type;
-
-                       auth_type = pairfind(request->config_items,
-                                            PW_AUTH_TYPE);
-                       if (auth_type && (auth_type->vp_strvalue[0] != '\0')) {
-                               snprintf(clean_password, sizeof(clean_password),
-                                        "<via Auth-Type = %s>",
-                                        auth_type->vp_strvalue);
-                       } else {
-                               strcpy(clean_password, "<no User-Password attribute>");
-                       }
-               } else if (pairfind(request->packet->vps, PW_CHAP_PASSWORD)) {
+                       strcpy(clean_password, "<no User-Password attribute>");
+               } else if (request->password->attribute == PW_CHAP_PASSWORD) {
                        strcpy(clean_password, "<CHAP-Password>");
                } else {
-                       librad_safeprint((char *)request->password->vp_strvalue,
+                       librad_safeprint((char *)request->password->strvalue,
                                         request->password->length,
                                         clean_password, sizeof(clean_password));
                }
@@ -143,13 +186,13 @@ static int rad_authlog(const char *msg, REQUEST *request, int goodpass) {
  *
  *     NOTE: NOT the same as the RLM_ values !
  */
-static int rad_check_password(REQUEST *request)
+int rad_check_password(REQUEST *request)
 {
        VALUE_PAIR *auth_type_pair;
        VALUE_PAIR *cur_config_item;
        VALUE_PAIR *password_pair;
        VALUE_PAIR *auth_item;
-       uint8_t my_chap[MAX_STRING_LEN];
+       char string[MAX_STRING_LEN];
        int auth_type = -1;
        int result;
        int auth_type_count = 0;
@@ -162,11 +205,11 @@ static int rad_check_password(REQUEST *request)
         */
        cur_config_item = request->config_items;
        while(((auth_type_pair = pairfind(cur_config_item, PW_AUTH_TYPE))) != NULL) {
-               auth_type = auth_type_pair->vp_integer;
+               auth_type = auth_type_pair->lvalue;
                auth_type_count++;
 
                DEBUG2("  rad_check_password:  Found Auth-Type %s",
-                               auth_type_pair->vp_strvalue);
+                               auth_type_pair->strvalue);
                cur_config_item = auth_type_pair->next;
 
                if (auth_type == PW_AUTHTYPE_REJECT) {
@@ -177,7 +220,7 @@ static int rad_check_password(REQUEST *request)
 
        if (( auth_type_count > 1) && (debug_flag)) {
                radlog(L_ERR, "Warning:  Found %d auth-types on request for user '%s'",
-                       auth_type_count, request->username->vp_strvalue);
+                       auth_type_count, request->username->strvalue);
        }
 
        /*
@@ -191,30 +234,8 @@ static int rad_check_password(REQUEST *request)
                return 0;
        }
 
-       password_pair =  pairfind(request->config_items, PW_USER_PASSWORD);
-       if (password_pair &&
-           pairfind(request->config_items, PW_CLEARTEXT_PASSWORD)) {
-               pairdelete(&request->config_items, PW_USER_PASSWORD);
-               password_pair = NULL;
-       }
-
-       if (password_pair) {
-               DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-               DEBUG("!!!    Replacing User-Password in config items with Cleartext-Password.     !!!");
-               DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-               DEBUG("!!! Please update your configuration so that the \"known good\"               !!!");
-               DEBUG("!!! clear text password is in Cleartext-Password, and not in User-Password. !!!");
-               DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-               password_pair->attribute = PW_CLEARTEXT_PASSWORD;
-               strlcpy(password_pair->name, "Cleartext-Password",
-                       sizeof(password_pair->name));
-       }
-
        /*
-        *      Find the "known good" password.
-        *
-        *      FIXME: We should get rid of these hacks, and replace
-        *      them with a module.
+        *      Find the password from the users file.
         */
        if ((password_pair = pairfind(request->config_items, PW_CRYPT_PASSWORD)) != NULL) {
                /*
@@ -223,7 +244,20 @@ static int rad_check_password(REQUEST *request)
                 */
                if (auth_type == -1) auth_type = PW_AUTHTYPE_CRYPT;
        } else {
-               password_pair = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
+               password_pair = pairfind(request->config_items, PW_PASSWORD);
+               if (!password_pair) {
+                       password_pair = pairfind(request->config_items,
+                                                PW_CLEARTEXT_PASSWORD);
+                       if (password_pair) {
+                               VALUE_PAIR *old;
+
+                               old = pairmake("User-Password",
+                                              password_pair->strvalue,
+                                              T_OP_SET);
+                               if (old) pairadd(&request->config_items, old);
+                       }
+               }
+               
        }
 
        if (auth_type < 0) {
@@ -264,8 +298,8 @@ static int rad_check_password(REQUEST *request)
                                return -1;
                        }
 
-                       switch (lrad_crypt_check((char *)auth_item->vp_strvalue,
-                                                                        (char *)password_pair->vp_strvalue)) {
+                       switch (lrad_crypt_check((char *)auth_item->strvalue,
+                                                                        (char *)password_pair->strvalue)) {
                        case -1:
                          rad_authlog("Login incorrect "
                                                  "(system failed to supply an encrypted password for comparison)", request, 0);
@@ -282,10 +316,7 @@ static int rad_check_password(REQUEST *request)
                         *      authentication fails.
                         */
                        auth_item = request->password;
-                       if (!auth_item)
-                               auth_item = pairfind(request->packet->vps,
-                                                    PW_CHAP_PASSWORD);
-                       if (!auth_item) {
+                       if (auth_item == NULL) {
                                DEBUG2("auth: No User-Password or CHAP-Password attribute in the request");
                                return -1;
                        }
@@ -303,9 +334,9 @@ static int rad_check_password(REQUEST *request)
                        /*
                         *      Local password is just plain text.
                         */
-                       if (auth_item->attribute == PW_USER_PASSWORD) {
-                               if (strcmp((char *)password_pair->vp_strvalue,
-                                          (char *)auth_item->vp_strvalue) != 0) {
+                       if (auth_item->attribute == PW_PASSWORD) {
+                               if (strcmp((char *)password_pair->strvalue,
+                                          (char *)auth_item->strvalue) != 0) {
                                        DEBUG2("auth: user supplied User-Password does NOT match local User-Password");
                                        return -1;
                                }
@@ -319,13 +350,13 @@ static int rad_check_password(REQUEST *request)
                                return -1;
                        }
 
-                       rad_chap_encode(request->packet, my_chap,
-                                       auth_item->vp_octets[0], password_pair);
+                       rad_chap_encode(request->packet, string,
+                                       auth_item->strvalue[0], password_pair);
 
                        /*
                         *      Compare them
                         */
-                       if (memcmp(my_chap + 1, auth_item->vp_strvalue + 1,
+                       if (memcmp(string + 1, auth_item->strvalue + 1,
                                   CHAP_VALUE_LENGTH) != 0) {
                                DEBUG2("auth: user supplied CHAP-Password does NOT match local User-Password");
                                return -1;
@@ -393,8 +424,8 @@ int rad_postauth(REQUEST *request)
         */
        vp = pairfind(request->config_items, PW_POST_AUTH_TYPE);
        if (vp) {
-               DEBUG2("  Found Post-Auth-Type %s", vp->vp_strvalue);
-               postauth_type = vp->vp_integer;
+               DEBUG2("  Found Post-Auth-Type %s", vp->strvalue);
+               postauth_type = vp->lvalue;
        }
        result = module_post_auth(postauth_type, request);
        switch (result) {
@@ -414,6 +445,7 @@ int rad_postauth(REQUEST *request)
                 */
                case RLM_MODULE_HANDLED:
                        /* FIXME */
+                       result = RLM_MODULE_OK;
                        break;
                /*
                 *      The module had a number of OK return codes.
@@ -429,6 +461,31 @@ int rad_postauth(REQUEST *request)
 }
 
 /*
+ *     Before sending an Access-Reject, call the modules in the
+ *     Post-Auth-Type REJECT stanza.
+ */
+static int rad_postauth_reject(REQUEST *request)
+{
+       int             result;
+       VALUE_PAIR      *tmp;
+       DICT_VALUE      *dval;
+
+       dval = dict_valbyname(PW_POST_AUTH_TYPE, "REJECT");
+       if (dval) {
+               /* Overwrite the Post-Auth-Type with the value REJECT */
+               pairdelete(&request->config_items, PW_POST_AUTH_TYPE);
+               tmp = paircreate(PW_POST_AUTH_TYPE, PW_TYPE_INTEGER);
+               tmp->lvalue = dval->value;
+               pairadd(&request->config_items, tmp);
+               result = rad_postauth(request);
+       } else {
+               /* No REJECT stanza */
+               result = RLM_MODULE_OK;
+       }
+       return result;
+}
+
+/*
  *     Process and reply to an authentication request
  *
  *     The return value of this function isn't actually used right now, so
@@ -438,14 +495,18 @@ int rad_authenticate(REQUEST *request)
 {
        VALUE_PAIR      *namepair;
        VALUE_PAIR      *check_item;
+       VALUE_PAIR      *reply_item;
        VALUE_PAIR      *auth_item;
        VALUE_PAIR      *module_msg;
        VALUE_PAIR      *tmp = NULL;
-       int             result;
+       int             result, r;
        char            umsg[MAX_STRING_LEN + 1];
        const char      *user_msg = NULL;
        const char      *password;
-       char            logstr[1024];
+       char            *exec_program;
+       int             exec_wait;
+       int             seen_callback_id;
+       char            buf[1024], logstr[1024];
        char            autz_retry = 0;
        int             autz_type = 0;
 
@@ -467,7 +528,7 @@ int rad_authenticate(REQUEST *request)
                                radlog(L_ERR|L_CONS, "Not enough memory");
                                exit(1);
                        }
-                       tmp->vp_integer = PW_AUTHTYPE_ACCEPT;
+                       tmp->lvalue = PW_AUTHTYPE_ACCEPT;
                        pairadd(&request->config_items, tmp);
                        break;
                /*
@@ -489,6 +550,7 @@ int rad_authenticate(REQUEST *request)
                        rad_authlog("Login incorrect (Home Server says so)",
                                    request, 0);
                        request->reply->code = PW_AUTHENTICATION_REJECT;
+                       rad_postauth_reject(request);
                        return RLM_MODULE_REJECT;
                }
        }
@@ -506,7 +568,7 @@ int rad_authenticate(REQUEST *request)
         */
        if (!request->password) {
                request->password = pairfind(request->packet->vps,
-                                            PW_USER_PASSWORD);
+                                            PW_PASSWORD);
        }
 
        /*
@@ -514,14 +576,14 @@ int rad_authenticate(REQUEST *request)
         */
        auth_item = request->password;
        if (auth_item) {
-               password = (const char *)auth_item->vp_strvalue;
+               password = (const char *)auth_item->strvalue;
 
        } else {
                /*
                 *      Maybe there's a CHAP-Password?
                 */
                if ((auth_item = pairfind(request->packet->vps,
-                                         PW_CHAP_PASSWORD)) != NULL) {
+                               PW_CHAP_PASSWORD)) != NULL) {
                        password = "<CHAP-PASSWORD>";
 
                } else {
@@ -555,7 +617,7 @@ autz_redo:
                                        PW_MODULE_FAILURE_MESSAGE)) != NULL) {
                                char msg[MAX_STRING_LEN + 16];
                                snprintf(msg, sizeof(msg), "Invalid user (%s)",
-                                        module_msg->vp_strvalue);
+                                        module_msg->strvalue);
                                rad_authlog(msg,request,0);
                        } else {
                                rad_authlog("Invalid user", request, 0);
@@ -566,8 +628,8 @@ autz_redo:
        if (!autz_retry) {
                tmp = pairfind(request->config_items, PW_AUTZ_TYPE);
                if (tmp) {
-                       DEBUG2("  Found Autz-Type %s", tmp->vp_strvalue);
-                       autz_type = tmp->vp_integer;
+                       DEBUG2("  Found Autz-Type %s", tmp->strvalue);
+                       autz_type = tmp->lvalue;
                        autz_retry = 1;
                        goto autz_redo;
                }
@@ -587,9 +649,9 @@ autz_redo:
                 *      Catch users who set Proxy-To-Realm to a LOCAL
                 *      realm (sigh).
                 */
-               realm = realm_find(tmp->vp_strvalue);
-               if (realm && !realm->auth_pool) {
-                       DEBUG2("  WARNING: You set Proxy-To-Realm = %s, but it is a LOCAL realm!  Cancelling invalid proxy request.", realm->name);
+               realm = realm_find(tmp->strvalue, 0);
+               if (realm && (realm->ipaddr == htonl(INADDR_NONE))) {
+                       DEBUG2("  WARNING: You set Proxy-To-Realm = %s, but it is a LOCAL realm!  Cancelling invalid proxy request.", realm->realm);
                } else {
                        /*
                         *      Don't authenticate, as the request is
@@ -608,6 +670,8 @@ autz_redo:
         *      Validate the user
         */
        do {
+               if ((result = check_expiration(request)) < 0)
+                               break;
                result = rad_check_password(request);
                if (result > 0) {
                        /* don't reply! */
@@ -630,7 +694,7 @@ autz_redo:
                        char msg[MAX_STRING_LEN+19];
 
                        snprintf(msg, sizeof(msg), "Login incorrect (%s)",
-                                module_msg->vp_strvalue);
+                                module_msg->strvalue);
                        rad_authlog(msg, request, 0);
                } else {
                        rad_authlog("Login incorrect", request, 0);
@@ -638,10 +702,10 @@ autz_redo:
 
                /* double check: maybe the secret is wrong? */
                if ((debug_flag > 1) && (auth_item != NULL) &&
-                               (auth_item->attribute == PW_USER_PASSWORD)) {
-                       char *p;
+                               (auth_item->attribute == PW_PASSWORD)) {
+                       u_char *p;
 
-                       p = auth_item->vp_strvalue;
+                       p = auth_item->strvalue;
                        while (*p != '\0') {
                                if (!isprint((int) *p)) {
                                        log_debug("  WARNING: Unprintable characters in the password.\n\t  Double-check the shared secret on the server and the NAS!");
@@ -654,12 +718,12 @@ autz_redo:
 
        if (result >= 0 &&
            (check_item = pairfind(request->config_items, PW_SIMULTANEOUS_USE)) != NULL) {
-               int r, session_type = 0;
+               int session_type = 0;
 
                tmp = pairfind(request->config_items, PW_SESSION_TYPE);
                if (tmp) {
-                       DEBUG2("  Found Session-Type %s", tmp->vp_strvalue);
-                       session_type = tmp->vp_integer;
+                       DEBUG2("  Found Session-Type %s", tmp->strvalue);
+                       session_type = tmp->lvalue;
                }
 
                /*
@@ -667,7 +731,7 @@ autz_redo:
                 *      for the Simultaneous-Use parameter.
                 */
                if (namepair &&
-                   (r = module_checksimul(session_type, request, check_item->vp_integer)) != 0) {
+                   (r = module_checksimul(session_type, request, check_item->lvalue)) != 0) {
                        char mpp_ok = 0;
 
                        if (r == 2){
@@ -675,16 +739,16 @@ autz_redo:
                                VALUE_PAIR *port_limit;
 
                                if ((port_limit = pairfind(request->reply->vps, PW_PORT_LIMIT)) != NULL &&
-                                       port_limit->vp_integer > check_item->vp_integer){
+                                       port_limit->lvalue > check_item->lvalue){
                                        DEBUG2("main auth: MPP is OK");
                                        mpp_ok = 1;
                                }
                        }
                        if (!mpp_ok){
-                               if (check_item->vp_integer > 1) {
+                               if (check_item->lvalue > 1) {
                                snprintf(umsg, sizeof(umsg),
                                                        "\r\nYou are already logged in %d times  - access denied\r\n\n",
-                                                       (int)check_item->vp_integer);
+                                                       (int)check_item->lvalue);
                                        user_msg = umsg;
                                } else {
                                        user_msg = "\r\nYou are already logged in - access denied\r\n\n";
@@ -701,7 +765,7 @@ autz_redo:
                                request->reply->vps = tmp;
 
                                snprintf(logstr, sizeof(logstr), "Multiple logins (max %d) %s",
-                                       check_item->vp_integer,
+                                       check_item->lvalue,
                                        r == 2 ? "[MPP attempt]" : "");
                                rad_authlog(logstr, request, 1);
 
@@ -710,11 +774,71 @@ autz_redo:
                }
        }
 
+       if (result >= 0 &&
+           (check_item = pairfind(request->config_items, PW_LOGIN_TIME)) != NULL) {
+
+               /*
+                *      Authentication is OK. Now see if this
+                *      user may login at this time of the day.
+                */
+               r = timestr_match((char *)check_item->strvalue,
+                                 request->timestamp);
+
+               if (r == 0) {   /* unlimited */
+                       /*
+                        *      Do nothing: login-time is OK.
+                        */
+
+                       /*
+                        *      Session-Timeout needs to be at least
+                        *      60 seconds, some terminal servers
+                        *      ignore smaller values.
+                        */
+               } else if (r < 60) {
+                       /*
+                        *      User called outside allowed time interval.
+                        */
+                       result = -1;
+                       user_msg = "You are calling outside your allowed timespan\r\n";
+
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
+                       pairfree(&request->reply->vps);
+
+                       tmp = pairmake("Reply-Message", user_msg, T_OP_SET);
+                       request->reply->vps = tmp;
+
+                       snprintf(logstr, sizeof(logstr), "Outside allowed timespan (time allowed %s)",
+                                check_item->strvalue);
+                       rad_authlog(logstr, request, 1);
+
+               } else if (r > 0) {
+
+                       /*
+                        *      User is allowed, but set Session-Timeout.
+                        */
+                       if ((reply_item = pairfind(request->reply->vps,
+                                       PW_SESSION_TIMEOUT)) != NULL) {
+                               if (reply_item->lvalue > (unsigned) r)
+                                       reply_item->lvalue = r;
+                       } else {
+                               if ((reply_item = paircreate(
+                                               PW_SESSION_TIMEOUT,
+                                               PW_TYPE_INTEGER)) == NULL) {
+                                       radlog(L_ERR|L_CONS, "no memory");
+                                       exit(1);
+                               }
+                               reply_item->lvalue = r;
+                               pairadd(&request->reply->vps, reply_item);
+                       }
+               }
+       }
+
        /*
         *      Result should be >= 0 here - if not, it means the user
         *      is rejected, so we just process post-auth and return.
         */
        if (result < 0) {
+               rad_postauth_reject(request);
                return RLM_MODULE_REJECT;
        }
 
@@ -741,10 +865,10 @@ autz_redo:
                 */
                if ((vpPortId = pairfind(request->packet->vps,
                                         PW_NAS_PORT)) != NULL) {
-                 unsigned long tvalue = ntohl(tmp->vp_integer);
-                 tmp->vp_integer = htonl(tvalue + vpPortId->vp_integer);
+                 unsigned long tvalue = ntohl(tmp->lvalue);
+                 tmp->lvalue = htonl(tvalue + vpPortId->lvalue);
                  tmp->flags.addport = 0;
-                 ip_ntoa(tmp->vp_strvalue, tmp->vp_integer);
+                 ip_ntoa(tmp->strvalue, tmp->lvalue);
                } else {
                        DEBUG2("WARNING: No NAS-Port attribute in request.  CANNOT return a Framed-IP-Address + NAS-Port.\n");
                        pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);
@@ -752,6 +876,129 @@ autz_redo:
        }
 
        /*
+        *      See if we need to execute a program.
+        *      FIXME: somehow cache this info, and only execute the
+        *      program when we receive an Accounting-START packet.
+        *      Only at that time we know dynamic IP etc.
+        */
+       exec_program = NULL;
+       exec_wait = 0;
+       if ((auth_item = pairfind(request->reply->vps, PW_EXEC_PROGRAM)) != NULL) {
+               exec_wait = 0;
+               exec_program = strdup((char *)auth_item->strvalue);
+               pairdelete(&request->reply->vps, PW_EXEC_PROGRAM);
+       }
+       if ((auth_item = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) {
+               free(exec_program);
+               exec_wait = 1;
+               exec_program = strdup((char *)auth_item->strvalue);
+               pairdelete(&request->reply->vps, PW_EXEC_PROGRAM_WAIT);
+       }
+
+       /*
+        *      Hack - allow % expansion in certain value strings.
+        *      This is nice for certain Exec-Program programs.
+        */
+       seen_callback_id = 0;
+       if ((auth_item = pairfind(request->reply->vps, PW_CALLBACK_ID)) != NULL) {
+               seen_callback_id = 1;
+               radius_xlat(buf, sizeof(auth_item->strvalue),
+                           (char *)auth_item->strvalue, request, NULL);
+               strNcpy((char *)auth_item->strvalue, buf,
+                       sizeof(auth_item->strvalue));
+               auth_item->length = strlen((char *)auth_item->strvalue);
+       }
+
+
+       /*
+        *      If we want to exec a program, but wait for it,
+        *      do it first before sending the reply.
+        */
+       if (exec_program && exec_wait) {
+               r = radius_exec_program(exec_program, request,
+                                       exec_wait,
+                                       NULL, 0,
+                                       request->packet->vps, &tmp);
+               free(exec_program);
+               exec_program = NULL;
+
+               /*
+                *      Always add the value-pairs to the reply.
+                */
+               pairmove(&request->reply->vps, &tmp);
+               pairfree(&tmp);
+
+               if (r < 0) {
+                       /*
+                        *      Error. radius_exec_program() returns -1 on
+                        *      fork/exec errors.
+                        */
+                       user_msg = "Access denied (external check failed)";
+                       tmp = pairmake("Reply-Message", user_msg, T_OP_SET);
+                       pairadd(&request->reply->vps, tmp);
+
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
+                       rad_authlog("Login incorrect (external check failed)",
+                                   request, 0);
+                       rad_postauth_reject(request);
+
+                       return RLM_MODULE_REJECT;
+               }
+               if (r > 0) {
+                       /*
+                        *      Reject. radius_exec_program() returns >0
+                        *      if the exec'ed program had a non-zero
+                        *      exit status.
+                        */
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
+                       rad_authlog("Login incorrect (external check said so)",
+                                   request, 0);
+                       rad_postauth_reject(request);
+
+                       return RLM_MODULE_REJECT;
+               }
+       }
+
+       /*
+        *      Delete "normal" A/V pairs when using callback.
+        *
+        *      FIXME: This is stupid. The portmaster should accept
+        *      these settings instead of insisting on using a
+        *      dialout location.
+        *
+        *      FIXME2: Move this into the above exec thingy?
+        *      (if you knew how I use the exec_wait, you'd understand).
+        */
+       if (seen_callback_id) {
+               pairdelete(&request->reply->vps, PW_FRAMED_PROTOCOL);
+               pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);
+               pairdelete(&request->reply->vps, PW_FRAMED_IP_NETMASK);
+               pairdelete(&request->reply->vps, PW_FRAMED_ROUTE);
+               pairdelete(&request->reply->vps, PW_FRAMED_MTU);
+               pairdelete(&request->reply->vps, PW_FRAMED_COMPRESSION);
+               pairdelete(&request->reply->vps, PW_FILTER_ID);
+               pairdelete(&request->reply->vps, PW_PORT_LIMIT);
+               pairdelete(&request->reply->vps, PW_CALLBACK_NUMBER);
+       }
+
+       /*
+        *      Filter (possibly multiple) Reply-Message attributes
+        *      through radius_xlat, modifying them in place.
+        */
+       if (user_msg == NULL) {
+               reply_item = pairfind(request->reply->vps, PW_REPLY_MESSAGE);
+               while (reply_item) {
+                       radius_xlat(buf, sizeof(reply_item->strvalue),
+                                   (char *)reply_item->strvalue, request, NULL);
+                       strNcpy((char *)reply_item->strvalue, buf,
+                               sizeof(reply_item->strvalue));
+                       reply_item->length = strlen((char *)reply_item->strvalue);
+                       user_msg = NULL;
+                       reply_item = pairfind(reply_item->next, PW_REPLY_MESSAGE);
+               }
+       }
+
+       /*
         *      Set the reply to Access-Accept, if it hasn't already
         *      been set to something.  (i.e. Access-Challenge)
         */
@@ -762,15 +1009,23 @@ autz_redo:
                char msg[MAX_STRING_LEN+12];
 
                snprintf(msg, sizeof(msg), "Login OK (%s)",
-                        module_msg->vp_strvalue);
+                        module_msg->strvalue);
                rad_authlog(msg, request, 1);
        } else {
                rad_authlog("Login OK", request, 1);
        }
 
-       /*
-        *      Run the modules in the 'post-auth' section.
-        */
+       if (exec_program && !exec_wait) {
+               /*
+                *      No need to check the exit status here.
+                */
+               radius_exec_program(exec_program, request, exec_wait,
+                                   NULL, 0, request->packet->vps, NULL);
+       }
+
+       if (exec_program)
+               free(exec_program);
+
        result = rad_postauth(request);
 
        return result;
index 9f8573b..c156436 100644 (file)
@@ -60,7 +60,7 @@ $snmp_version = "2c";
 $rusers                = "@RUSERS@";
 $naspass       = "$raddbdir/naspasswd";
 
-# Community string. Change this if yours isn't "public".
+# Community string. Change this if yours isn't "public". 
 $cmmty_string  = "public";
 # path to finger command
 $finger = "/usr/bin/finger";
@@ -121,10 +121,10 @@ sub naspasswd {
        close NFD;
        if ($password eq "" && !$emptyok) {
                print LOG "checkrad: password for $ARGV[1] is null; " .
-                       "possible match for $ARGV[3] on " .
+                       "possible match for $ARGV[3] on " . 
                        "port $ARGV[2]\n" if ($debug);
                print STDERR "checkrad: password for $ARGV[1] is null; " .
-                       "possible match for $ARGV[3] on port $ARGV[2]\n";
+                       "possible match for $ARGV[3] on port $ARGV[2]\n"; 
        }
        ($login, $password);
 }
@@ -262,7 +262,7 @@ sub snmpget {
 
 #
 #      Strip domains, prefixes and suffixes from username
-#
+#      
 #      Known prefixes: (P)PP, (S)LIP e (C)SLIP
 #      Known suffixes: .ppp, .slip e .cslip
 #
@@ -603,7 +603,7 @@ sub portslave_finger {
 #      (this routine by Alexis C. Villalon <alexisv@compass.com.ph>).
 #      You must have the Net::Telnet module from CPAN for this to work.
 #      You must also have your /etc/raddb/naspasswd made up.
-#
+# 
 sub tc_tccheck {
        #
        #       Localize all variables first.
@@ -680,7 +680,7 @@ sub tc_tccheck {
                $user =~ s/^[PSC]//;
                $user =~ s/\.(ppp|slip|cslip)$//;
                $port =~ s/^S//;
-               #
+               #               
                #       HACK: because "show sessions" shows max. 15 characters
                #       we only compare up to the length of $user if the
                #       unstripped name had 15 chars.
@@ -718,7 +718,7 @@ sub cyclades_telnet {
        #
        my ($pr, $pr_login, $pr_passwd, $pr_prompt, $endlist, @list, $port, $user);
        #
-       #       This variable must match PathRAS' command prompt
+       #       This variable must match PathRAS' command prompt 
        #       string as entered in menu option 6.2.
        #       The value below matches the default command prompt.
        #
@@ -735,7 +735,7 @@ sub cyclades_telnet {
        return 2 unless (check_net_telnet());
 
        #
-       #       Get login name and password for NAS
+       #       Get login name and password for NAS 
        #       from $naspass file.
        #
        ($pr_login, $pr_passwd) = naspasswd($ARGV[1], 1);
@@ -761,18 +761,18 @@ sub cyclades_telnet {
        #
        if ($pr->waitfor(Match => '/login : $/i') == 1) {
                $pr->print($pr_login);
-       } else {
+       } else { 
                print LOG " Error: sending login name to PathRAS\n" if ($debug);
                $pr->close;
-               return 2;
+               return 2;       
        }
 
        if ($pr->waitfor(Match => '/password : $/i') == 1) {
                $pr->print($pr_passwd);
-       } else {
+       } else { 
                print LOG " Error: sending password to PathRAS.\n" if ($debug);
                $pr->close;
-               return 2;
+               return 2;       
        }
 
        $pr->print();
@@ -782,7 +782,7 @@ sub cyclades_telnet {
        #
        if ($pr->waitfor(Match => $pr_prompt) == 1) {
                $pr->print('6');
-       } else {
+       } else { 
                print LOG "  Error: acessing menu option '6'.\n" if ($debug);
                $pr->close;
                return 2;
@@ -792,13 +792,13 @@ sub cyclades_telnet {
        #
        if ($pr->waitfor(Match => $pr_prompt) == 1) {
                @list = $pr->cmd(String => '8', Prompt => $endlist);
-       } else {
+       } else { 
                print LOG "  Error: acessing menu option '8'.\n" if ($debug);
                $pr->close;
                return 2;
        }
        #
-       #       Since we got the info we want, let's close
+       #       Since we got the info we want, let's close 
        #       the telnet session
        #
        $pr->close;
@@ -843,9 +843,9 @@ sub patton_snmp {
    $oid = '.1.3.6.1.4.1.1768.5.100.1.56.' . hex $ARGV[4];
    #
    # Check if the session still active
-   #
+   # 
    if (snmpget($ARGV[1], "monitor", "$oid") == 0) {
-      print LOG "  Session $ARGV[4] still active on NAS " .
+      print LOG "  Session $ARGV[4] still active on NAS " . 
        "$ARGV[1], port $ARGV[2], for user $ARGV[3].\n" if ($debug);
       return 1;
    }
@@ -886,7 +886,7 @@ sub digitro_rusers {
 sub cyclades_snmp {
    my ($oid, $ret);
    local $_;
-
+   
    $oid = ".1.3.6.1.4.1.2925.3.3.6.1.1.2";
 
    $_ = snmpwalk($ARGV[1],"$cmmty_string",$oid);
@@ -898,7 +898,7 @@ sub cyclades_snmp {
 #      3Com/USR HiPer Arc Total Control.
 #      This works with HiPer Arc 4.0.30
 #      (this routine by Igor Brezac <igor@ipass.net>)
-#
+# 
 
 #       This routine modified by Dan Halverson <danh@tbc.net>
 #       to suport additional versions of Hiper Arc
@@ -920,7 +920,7 @@ sub usrhiper_snmp {
 # If password is defined in naspasswd file, use it as community, otherwise use $cmmty_string
                if ($password eq '') {
                    $password = "$cmmty_string";
-               }
+               }       
        }
        my ($ver) = get_hiper_ver(usrm=>$usrm, target=>$ARGV[1], community=>$password);
        $oidext = get_oidext(ver=>$ver, tty=>$ARGV[2]);
@@ -948,7 +948,7 @@ sub get_hiper_ver {
     return($ver);
 }
 
-#
+#     
 #   Add additional OID checks below before the else.
 #   Else is for 4.0.30
 #
@@ -990,8 +990,8 @@ sub usrnet_telnet {
 
        #
        #       Communicate with Netserver using Net::Telnet, then access
-       #       list connectionsto see who are logged in.
-       #
+       #       list connectionsto see who are logged in. 
+       # 
        $telnet = new Net::Telnet (Timeout => 5,
                                   Prompt => '/\>/');
        $telnet->open($terminalserver);
@@ -1022,7 +1022,7 @@ sub usrnet_telnet {
                if ( /mod\:/ ) {
                        ($port, $user, $dummy) = split;
                        #
-                       # Strip out any prefixes and suffixes
+                       # Strip out any prefixes and suffixes 
                        # from the username
                        #
                        # uncomment this if you use the standard
@@ -1039,7 +1039,7 @@ sub usrnet_telnet {
                        };
                };
        };
-       print LOG
+       print LOG 
        "  $ARGV[3] not found on Netserver logged users list " if ($debug);
        0;
 }
@@ -1049,16 +1049,16 @@ sub usrnet_telnet {
 #
 #      ___ versanet_snmp 1.0 by support@versanetcomm.com ___ July 1999
 #      Versanet Enterprise MIB Base: 1.3.6.1.4.1.2180
-#
+#   
 #      VN2001/2002 use slot/port number to locate modems. To use snmp get we
 #      have to translate the original port number into a slot/port pair.
 #
 $vsm     = '.iso.org.dod.internet.private.enterprises.2180';
 sub versanet_snmp {
-
+        
        print LOG "argv[2] = $ARGV[2] " if ($debug);
        $port = $ARGV[2]%8;
-       $port = 8 if ($port eq 0);
+       $port = 8 if ($port eq 0);        
        print LOG "port = $port " if ($debug);
        $slot = (($ARGV[2]-$port)/8)+1;
        print LOG "slot = $slot" if ($debug);
@@ -1067,12 +1067,12 @@ sub versanet_snmp {
 #      Note: the "$cmmty_string" string above could be replaced by the public
 #            community string defined in Versanet VN2001/VN2002.
 #
-         print LOG "  user at slot $slot port $port: $loginname\n" if ($debug);          ($loginname eq $ARGV[3]) ? 1 : 0;
+         print LOG "  user at slot $slot port $port: $loginname\n" if ($debug);          ($loginname eq $ARGV[3]) ? 1 : 0;     
 }
 
 
 # 1999/08/24 Chris Shenton <chris@shenton.org>
-# Check Bay8000 NAS (aka: Annex) using finger.
+# Check Bay8000 NAS (aka: Annex) using finger. 
 # Returns from "finger @bay" like:
 #   Port  What User         Location         When          Idle  Address
 #   asy2  PPP  bill         ---              9:33am         :08  192.168.1.194
@@ -1160,7 +1160,7 @@ sub mikrotik_snmp {
   # Set SNMP version
   # MikroTik only supports version 1
   $snmp_version = "1";
-
   # Look up community string in naspasswd file.
   ($login, $password) = naspasswd($ARGV[1], 1);
   if ($login && $login ne 'SNMP') {
@@ -1168,14 +1168,14 @@ sub mikrotik_snmp {
       print LOG "Error: Need SNMP community string for $ARGV[1]\n";
     }
     return 2;
-  } else {
+  } else { 
   # If password is defined in naspasswd file, use it as community,
   # otherwise use $cmmty_string
     if ($password eq '') {
       $password = "$cmmty_string";
     }
   }
-
   # We want interface descriptions
   $oid = "ifDescr";
 
@@ -1224,7 +1224,7 @@ sub mikrotik_telnet {
 
   # Dont just exit when there is error
   $t->errmode('return');
-
+                       
   # Telnet to terminal server
   $t->open($terminalserver) or return 2;
 
@@ -1286,7 +1286,7 @@ sub mikrotik_telnet {
 
   if( $output =~ /name="$user"/ ) {
     $username_seen++;
-  }
+  } 
 
   #lets return something
   if ($username_seen > 0) {
@@ -1311,30 +1311,30 @@ sub redback_telnet {
        print LOG " Error: No context defined\n" if ($debug);
        return 2;
     }
-
+    
     # Get loggin information
     ($root, $password) = naspasswd($terminalserver, 1);
     return 2 if ($password eq "");
-
+    
     $operprompt = '/\[.*\].*>$/';
     $adminprompt = '/\[.*\].*#$/';
-
+    
     # Logging to the RedBack NAS
     $t = new Net::Telnet (Timeout => 5, Prompt => $operprompt);
     $t->input_log("./debug");
     $t->open($terminalserver);
     $t->login($root, $password);
-
+    
     #Enable us
     $t->print('ena');
     $t->waitfor('/Password/');
     $t->print($password);
     $t->waitfor($adminprompt);
     $t->prompt($adminprompt);
-
+    
     #Switch context
     $t->cmd(String => "context $context");
-
+    
     #Ask the question
     @lines = $t->cmd(String => "show subscribers active
 $user\@$context");
index d25b5dc..1a80a3d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * client.c    Read clients into memory.
+ * files.c     Read config files into memory.
  *
  * Version:     $Id$
  *
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/radius_snmp.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
 
 #include <sys/stat.h>
 
-#include <ctype.h>
-#include <fcntl.h>
-
-struct radclient_list {
-       /*
-        *      FIXME: One set of trees for IPv4, and another for IPv6?
-        */
-       rbtree_t        *trees[129]; /* for 0..128, inclusive. */
-       int             min_prefix;
-};
-
-
-#ifdef WITH_SNMP
-static rbtree_t                *tree_num;      /* client numbers 0..N */
-static int             tree_num_max;
-#endif
-
-/*
- *     Callback for freeing a client.
- */
-void client_free(RADCLIENT *client)
-{
-       free(client->longname);
-       free(client->secret);
-       free(client->shortname);
-       free(client->nastype);
-       free(client->login);
-       free(client->password);
-
-#ifdef WITH_SNMP
-       free(client->auth);
-       free(client->acct);
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
 #endif
 
-       free(client);
-}
-
-
-/*
- *     Callback for comparing two clients.
- */
-static int client_ipaddr_cmp(const void *one, const void *two)
-{
-       const RADCLIENT *a = one;
-       const RADCLIENT *b = two;
-
-       return lrad_ipaddr_cmp(&a->ipaddr, &b->ipaddr);
-}
-
-#ifdef WITH_SNMP
-static int client_num_cmp(const void *one, const void *two)
-{
-       const RADCLIENT *a = one;
-       const RADCLIENT *b = two;
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <fcntl.h>
 
-       return (a->number - b->number);
-}
-#endif
+#include "radiusd.h"
+#include "conffile.h"
 
 /*
  *     Free a RADCLIENT list.
  */
-void clients_free(RADCLIENT_LIST *clients)
+void clients_free(RADCLIENT *cl)
 {
-       int i;
-
-       if (!clients) return;
+       RADCLIENT *next;
 
-       for (i = 0; i <= 128; i++) {
-               if (clients->trees[i]) rbtree_free(clients->trees[i]);
-               clients->trees[i] = NULL;
+       while(cl) {
+               next = cl->next;
+               free(cl);
+               cl = next;
        }
-
-       if (clients == mainconfig.clients) {
-#ifdef WITH_SNMP
-               if (tree_num) rbtree_free(tree_num);
-               tree_num = NULL;
-               tree_num_max = 0;
-#endif
-               mainconfig.clients = NULL;
-       }
-
-       free(clients);
-}
-
-/*
- *     Return a new, initialized, set of clients.
- */
-RADCLIENT_LIST *clients_init(void)
-{
-       RADCLIENT_LIST *clients = calloc(1, sizeof(RADCLIENT_LIST));
-
-       if (!clients) return NULL;
-
-       clients->min_prefix = 128;
-
-       return clients;
 }
 
 
 /*
- *     Sanity check a client.
+ *     Read the clients file.
  */
-static int client_sane(RADCLIENT *client)
+int read_clients_file(const char *file)
 {
-       switch (client->ipaddr.af) {
-       case AF_INET:
-               if (client->prefix > 32) {
-                       return 0;
+       FILE *fp;
+       RADCLIENT *c;
+       char buffer[256];
+       char hostnm[256];
+       char secret[256];
+       char shortnm[256];
+       uint32_t mask;
+       int lineno = 0;
+       char *p;
+       int got_clients = FALSE;
+
+       clients_free(mainconfig.clients);
+       mainconfig.clients = NULL;
+
+       if ((fp = fopen(file, "r")) == NULL) {
+               /* The clients file is no longer required.  All configuration
+                  information is read from radiusd.conf and friends.  If
+                  clients exists it will be used, but if it doesn't no harm
+                  done. */
+               return 0;
+       }
+
+       while(fgets(buffer, 256, fp) != NULL) {
+               lineno++;
+               if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
+                       radlog(L_ERR, "%s[%d]: line too long", file, lineno);
+                       return -1;
                }
 
                /*
-                *      Zero out the subnet bits.
+                *      Skip whitespace.
                 */
-               if (client->prefix < 32) {
-                       uint32_t mask = ~0;
-
-                       mask <<= (32 - client->prefix);
-                       client->ipaddr.ipaddr.ip4addr.s_addr &= htonl(mask);
-               }
-               break;
+               p = buffer;
+               while (*p &&
+                               ((*p == ' ') || (*p == '\t')))
+                       p++;
 
-       case AF_INET6:
-               if (client->prefix > 128) return 0;
-
-               if (client->prefix < 128) {
-                       int i;
-                       uint32_t mask, *addr;
-
-                       addr = (uint32_t *) &client->ipaddr.ipaddr.ip6addr;
-
-                       for (i = client->prefix; i < 128; i += 32) {
-                               mask = ~0;
-                               mask <<= ((128 - i) & 0x1f);
-                               addr[i / 32] &= mask;
-                       }
+               /*
+                *      Skip comments and blank lines.
+                */
+               if ((*p == '#') || (*p == '\n') || (*p == '\r'))
+                       continue;
+
+               if (!getword(&p, hostnm, sizeof(hostnm)) ||
+                               !getword(&p, secret, sizeof(secret))) {
+                       radlog(L_ERR, "%s[%d]: unexpected end of line",
+                                       file, lineno);
+                       return -1;
                }
-               break;
-
-       default:
-               return 0;
-       }
-
-       return 1;
-}
 
+               (void)getword(&p, shortnm, sizeof(shortnm));
 
-/*
- *     Add a client to the tree.
- */
-int client_add(RADCLIENT_LIST *clients, RADCLIENT *client)
-{
-       /*
-        *      Allow clients to be NULL if mainconfig.clients is NULL.
-        */
+               /*
+                *      Look for a mask in the hostname
+                */
+               p = strchr(hostnm, '/');
+               mask = ~0;
 
-       if (!client || (!clients && (mainconfig.clients != NULL))) {
-               return 0;
-       }
+               if (p) {
+                       int mask_length;
 
-       if (!clients) {
-               clients = clients_init();
-               if (!clients) return 0;
-               rad_assert(mainconfig.clients == NULL);
-               mainconfig.clients = clients;
-       }
+                       *p = '\0';
+                       p++;
 
-       if (client->prefix < 0) {
-               return 0;
-       }
+                       mask_length = atoi(p);
+                       if ((mask_length < 0) || (mask_length > 32)) {
+                               radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.",
+                                      file, lineno, p);
+                               return -1;
+                       }
 
-       if (!client_sane(client)) return 0;
+                       if (mask_length == 0) {
+                               mask = 0;
+                       } else {
+                               mask = ~0 << (32 - mask_length);
+                       }
+               }
 
-       /*
-        *      Create a tree for it.
-        */
-       if (!clients->trees[client->prefix]) {
-               clients->trees[client->prefix] = rbtree_create(client_ipaddr_cmp,
-                                                              client_free, 0);
-               if (!clients->trees[client->prefix]) {
-                       return 0;
+               /*
+                *      Double-check lengths to be sure they're sane
+                */
+               if (strlen(hostnm) >= sizeof(c->longname)) {
+                       radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(hostnm),
+                              (int) sizeof(c->longname) - 1);
+                       return -1;
+               }
+               if (strlen(secret) >= sizeof(c->secret)) {
+                       radlog(L_ERR, "%s[%d]: secret of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(secret),
+                              (int) sizeof(c->secret) - 1);
+                       return -1;
+               }
+               if (strlen(shortnm) > sizeof(c->shortname)) {
+                       radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(shortnm),
+                              (int) sizeof(c->shortname) - 1);
+                       return -1;
                }
-       }
 
-       /*
-        *      Duplicate?
-        */
-       if (!rbtree_insert(clients->trees[client->prefix], client)) {
-               return 0;
-       }
+               /*
+                *      It should be OK now, let's create the buffer.
+                */
+               got_clients = TRUE;
+               c = rad_malloc(sizeof(RADCLIENT));
+               memset(c, 0, sizeof(*c));
 
-#ifdef WITH_SNMP
-       if (!tree_num) {
-               tree_num = rbtree_create(client_num_cmp, NULL, 0);
-       }
+               c->ipaddr = ip_getaddr(hostnm);
+               if (c->ipaddr == INADDR_NONE) {
+                       clients_free(c);
+                       radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
+                                       file, lineno, hostnm);
+                       return -1;
+               }
+               c->netmask = htonl(mask);
+               c->ipaddr &= c->netmask; /* addr & mask are in network order */
 
+               strcpy((char *)c->secret, secret);
+               strcpy(c->shortname, shortnm);
 
-       /*
-        *      Catch clients added by rlm_sql.
-        */
-       if (!client->auth) {
-               client->auth = rad_malloc(sizeof(*client->auth));
-               memset(client->auth, 0, sizeof(*client->auth));
-       }
+               /*
+                *      Only do DNS lookups for machines.  Just print
+                *      the network as the long name.
+                */
+               if ((~mask) == 0) {
+                       NAS *nas;
+                       ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
+
+                       /*
+                        *      Pull information over from the NAS.
+                        */
+                       nas = nas_find(c->ipaddr);
+                       if (nas) {
+                               /*
+                                *      No short name in the 'clients' file,
+                                *      try copying one over from the
+                                *      'naslist' file.
+                                */
+                               if (c->shortname[0] == '\0') {
+                                       strcpy(c->shortname, nas->shortname);
+                               }
+
+                               /*
+                                *  Copy the nastype over, too.
+                                */
+                               strcpy(c->nastype, nas->nastype);
+                       }
+               } else {
+                       hostnm[strlen(hostnm)] = '/';
+                       strNcpy(c->longname, hostnm, sizeof(c->longname));
+               }
 
-       if (!client->acct) {
-               client->acct = rad_malloc(sizeof(*client->acct));
-               memset(client->acct, 0, sizeof(*client->acct));
+               c->next = mainconfig.clients;
+               mainconfig.clients = c;
        }
+       fclose(fp);
 
-
-       client->number = tree_num_max;
-       tree_num_max++;
-       if (tree_num) rbtree_insert(tree_num, client);
-#endif
-
-       if (client->prefix < clients->min_prefix) {
-               clients->min_prefix = client->prefix;
+       if (got_clients) {
+               radlog(L_INFO, "Using deprecated clients file.  Support for this will go away soon.");
        }
 
-       return 1;
-}
-
-
-/*
- *     Find a client in the RADCLIENTS list by number.
- *     This is a support function for the SNMP code.
- */
-RADCLIENT *client_findbynumber(const RADCLIENT_LIST *clients,
-                              int number)
-{
-#ifdef WITH_SNMP
-       if (!clients) return NULL;
-
-       if (number >= tree_num_max) return NULL;
-
-       if (tree_num) {
-               RADCLIENT myclient;
-
-               myclient.number = number;
-
-               return rbtree_finddata(tree_num, &myclient);
-       }
-#endif
-       return NULL;
+       return 0;
 }
 
 
 /*
  *     Find a client in the RADCLIENTS list.
  */
-RADCLIENT *client_find(const RADCLIENT_LIST *clients,
-                      const lrad_ipaddr_t *ipaddr)
+RADCLIENT *client_find(uint32_t ipaddr)
 {
-       int i, max_prefix;
-       RADCLIENT myclient;
-
-       if (!clients || !ipaddr) return NULL;
-
-       switch (ipaddr->af) {
-       case AF_INET:
-               max_prefix = 32;
-               break;
-
-       case AF_INET6:
-               max_prefix = 128;
-               break;
-
-       default :
-               return NULL;
-       }
-
-       for (i = max_prefix; i >= clients->min_prefix; i--) {
-               void *data;
-
-               myclient.prefix = i;
-               myclient.ipaddr = *ipaddr;
-               client_sane(&myclient); /* clean up the ipaddress */
-
-               if (!clients->trees[i]) continue;
+       RADCLIENT *cl;
+       RADCLIENT *match = NULL;
 
-               data = rbtree_finddata(clients->trees[i], &myclient);
-               if (data) {
-                       return data;
+       for (cl = mainconfig.clients; cl; cl = cl->next) {
+               if ((ipaddr & cl->netmask) == cl->ipaddr) {
+                       if ((!match) ||
+                           (ntohl(cl->netmask) > ntohl(match->netmask))) {
+                               match = cl;
+                       }
                }
        }
 
-       return NULL;
+       return match;
 }
 
-
 /*
- *     Old wrapper for client_find
+ *     Walk the RADCLIENT list displaying the clients.  This function
+ *     is for debugging purposes.
  */
-RADCLIENT *client_find_old(const lrad_ipaddr_t *ipaddr)
+void client_walk(void)
 {
-       return client_find(mainconfig.clients, ipaddr);
-}
+       RADCLIENT *cl;
+       char host_ipaddr[16];
 
+       for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
+               radlog(L_ERR, "client: client_walk: %s\n",
+                               ip_ntoa(host_ipaddr, cl->ipaddr));
+}
 
 /*
  *     Find the name of a client (prefer short name).
  */
-const char *client_name(const RADCLIENT_LIST *clients,
-                       const lrad_ipaddr_t *ipaddr)
+const char *client_name(uint32_t ipaddr)
 {
        /* We don't call this unless we should know about the client. */
        RADCLIENT *cl;
-       char host_ipaddr[128];
+       char host_ipaddr[16];
 
-       if ((cl = client_find(clients, ipaddr)) != NULL) {
-               if (cl->shortname && cl->shortname[0])
+       if ((cl = client_find(ipaddr)) != NULL) {
+               if (cl->shortname[0])
                        return cl->shortname;
                else
                        return cl->longname;
@@ -356,163 +288,7 @@ const char *client_name(const RADCLIENT_LIST *clients,
         * If you see lots of these, then there's something wrong.
         */
        radlog(L_ERR, "Trying to look up name of unknown client %s.\n",
-              ip_ntoh(ipaddr, host_ipaddr, sizeof(host_ipaddr)));
+              ip_ntoa(host_ipaddr, ipaddr));
 
        return "UNKNOWN-CLIENT";
 }
-
-const char *client_name_old(const lrad_ipaddr_t *ipaddr)
-{
-       return client_name(mainconfig.clients, ipaddr);
-}
-
-static const CONF_PARSER client_config[] = {
-       { "secret",  PW_TYPE_STRING_PTR,
-         offsetof(RADCLIENT, secret), 0, NULL },
-       { "shortname",  PW_TYPE_STRING_PTR,
-         offsetof(RADCLIENT, shortname), 0, NULL },
-       { "nastype",  PW_TYPE_STRING_PTR,
-         offsetof(RADCLIENT, nastype), 0, NULL },
-       { "login",  PW_TYPE_STRING_PTR,
-         offsetof(RADCLIENT, login), 0, NULL },
-       { "password",  PW_TYPE_STRING_PTR,
-         offsetof(RADCLIENT, password), 0, NULL },
-
-       { NULL, -1, 0, NULL, NULL }
-};
-
-
-/*
- *     Create the linked list of clients from the new configuration
- *     type.  This way we don't have to change too much in the other
- *     source-files.
- */
-RADCLIENT_LIST *clients_parse_section(const char *filename,
-                                     CONF_SECTION *section)
-{
-       CONF_SECTION    *cs;
-       RADCLIENT       *c;
-       char            *hostnm, *prefix_ptr = NULL;
-       const char      *name2;
-       RADCLIENT_LIST  *clients;
-
-       /*
-        *      Be forgiving.  If there's already a clients, return
-        *      it.  Otherwise create a new one.
-        */
-       clients = cf_data_find(section, "clients");
-       if (clients) return clients;
-
-       clients = clients_init();
-       if (!clients) return NULL;
-
-       /*
-        *      Associate the clients structure with the section, where
-        *      it will be freed once the section is freed.
-        */
-       if (cf_data_add(section, "clients", clients, clients_free) < 0) {
-               radlog(L_ERR, "%s[%d]: Failed to associate clients with section %s",
-                      filename, cf_section_lineno(section),
-                      cf_section_name1(section));
-               clients_free(clients);
-               return NULL;
-       }
-
-       for (cs = cf_subsection_find_next(section, NULL, "client");
-            cs != NULL;
-            cs = cf_subsection_find_next(section, cs, "client")) {
-               name2 = cf_section_name2(cs);
-               if (!name2) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: Missing client name",
-                              filename, cf_section_lineno(cs));
-                       return NULL;
-               }
-               /*
-                * Check the lengths, we don't want any core dumps
-                */
-               hostnm = name2;
-               prefix_ptr = strchr(hostnm, '/');
-
-               /*
-                * The size is fine.. Let's create the buffer
-                */
-               c = rad_malloc(sizeof(*c));
-               memset(c, 0, sizeof(*c));
-
-#ifdef WITH_SNMP
-               c->auth = rad_malloc(sizeof(*c->auth));
-               memset(c->auth, 0, sizeof(*c->auth));
-
-               c->acct = rad_malloc(sizeof(*c->acct));
-               memset(c->acct, 0, sizeof(*c->acct));
-#endif
-
-               if (cf_section_parse(cs, c, client_config) < 0) {
-                       client_free(c);
-                       radlog(L_CONS|L_ERR, "%s[%d]: Error parsing client section.",
-                              filename, cf_section_lineno(cs));
-                       return NULL;
-               }
-
-               /*
-                * Look for prefixes.
-                */
-               c->prefix = -1;
-               if (prefix_ptr) {
-                       c->prefix = atoi(prefix_ptr + 1);
-                       if ((c->prefix < 0) || (c->prefix > 128)) {
-                               client_free(c);
-                               radlog(L_ERR, "%s[%d]: Invalid Prefix value '%s' for IP.",
-                                               filename, cf_section_lineno(cs), prefix_ptr + 1);
-                               return NULL;
-                       }
-                       /* Replace '/' with '\0' */
-                       *prefix_ptr = '\0';
-               }
-
-               /*
-                * Always get the numeric representation of IP
-                */
-               if (ip_hton(hostnm, AF_UNSPEC, &c->ipaddr) < 0) {
-                       client_free(c);
-                       radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s: %s",
-                              filename, cf_section_lineno(cs),
-                              hostnm, librad_errstr);
-                       return NULL;
-               } else {
-                       char buffer[256];
-                       ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
-                       c->longname = strdup(buffer);
-               }
-
-               /*
-                *      This makes later life easier.
-                */
-               if (!c->shortname) c->shortname = strdup(c->longname);
-
-               if (c->prefix < 0) switch (c->ipaddr.af) {
-               case AF_INET:
-                       c->prefix = 32;
-                       break;
-               case AF_INET6:
-                       c->prefix = 128;
-                       break;
-               default:
-                       break;
-               }
-
-               /*
-                *      FIXME: Add the client as data via cf_data_add,
-                *      for migration issues.
-                */
-
-               if (!client_add(clients, c)) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: Failed to add client %s",
-                              filename, cf_section_lineno(cs), hostnm);
-                       client_free(c);
-                       return NULL;
-               }
-       }
-
-       return clients;
-}
index e8d10b7..8c1743e 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#include <stdlib.h>
+#include <string.h>
 
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
 
 #ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
+#include       <sys/stat.h>
 #endif
 
-#include <ctype.h>
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "conffile.h"
+#include "token.h"
+#include "modules.h"
+
+static const char rcsid[] =
+"$Id$";
+
+#define xstrdup strdup
 
 typedef enum conf_type {
-       CONF_ITEM_INVALID = 0,
        CONF_ITEM_PAIR,
-       CONF_ITEM_SECTION,
-       CONF_ITEM_DATA
+       CONF_ITEM_SECTION
 } CONF_ITEM_TYPE;
 
 struct conf_item {
@@ -63,40 +70,13 @@ struct conf_pair {
 };
 struct conf_part {
        CONF_ITEM item;
-       const char *name1;
-       const char *name2;
-       struct conf_item *children;
-       struct conf_item *tail; /* for speed */
-       CONF_SECTION    *template;
-       rbtree_t        *pair_tree; /* and a partridge.. */
-       rbtree_t        *section_tree; /* no jokes here */
-       rbtree_t        *name2_tree; /* for sections of the same name2 */
-       rbtree_t        *data_tree;
-       void            *base;
-       int depth;
+       char *name1;
+       char *name2;
+       void *base;
        const CONF_PARSER *variables;
+       struct conf_item *children;
 };
 
-
-/*
- *     Internal data that is associated with a configuration section,
- *     so that we don't have to track it separately.
- */
-struct conf_data {
-       CONF_ITEM  item;
-       const char *name;
-       int        flag;
-       void       *data;       /* user data */
-       void       (*free)(void *); /* free user data function */
-};
-
-
-static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
-                               void *data, void (*data_free)(void *),
-                               int flag);
-static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,
-                                  int flag);
-
 /*
  *     Isolate the scary casts in these tiny provably-safe functions
  */
@@ -127,34 +107,20 @@ CONF_ITEM *cf_sectiontoitem(CONF_SECTION *cs)
        return (CONF_ITEM *)cs;
 }
 
-static CONF_DATA *cf_itemtodata(CONF_ITEM *ci)
-{
-       if (ci == NULL)
-               return NULL;
-       rad_assert(ci->type == CONF_ITEM_DATA);
-       return (CONF_DATA *)ci;
-}
-static CONF_ITEM *cf_datatoitem(CONF_DATA *cd)
-{
-       if (cd == NULL)
-               return NULL;
-       return (CONF_ITEM *)cd;
-}
-
 /*
  *     Create a new CONF_PAIR
  */
 static CONF_PAIR *cf_pair_alloc(const char *attr, const char *value,
-                               LRAD_TOKEN operator, CONF_SECTION *parent)
+               LRAD_TOKEN operator, CONF_SECTION *parent)
 {
        CONF_PAIR *cp;
 
-       cp = rad_malloc(sizeof(*cp));
-       memset(cp, 0, sizeof(*cp));
+       cp = (CONF_PAIR *)rad_malloc(sizeof(CONF_PAIR));
+       memset(cp, 0, sizeof(CONF_PAIR));
        cp->item.type = CONF_ITEM_PAIR;
        cp->item.parent = parent;
-       cp->attr = strdup(attr);
-       cp->value = strdup(value);
+       cp->attr = xstrdup(attr);
+       cp->value = xstrdup(value);
        cp->operator = operator;
 
        return cp;
@@ -180,83 +146,6 @@ void cf_pair_free(CONF_PAIR **cp)
        *cp = NULL;
 }
 
-
-static void cf_data_free(CONF_DATA **cd)
-{
-       if (!cd || !*cd) return;
-
-       if ((*cd)->flag != 0) free((*cd)->name);
-       if (!(*cd)->free) {
-               free((*cd)->data);
-       } else {
-               ((*cd)->free)((*cd)->data);
-       }
-#ifndef NDEBUG
-       memset(*cd, 0, sizeof(*cd));
-#endif
-       free(*cd);
-       *cd = NULL;
-}
-
-/*
- *     rbtree callback function
- */
-static int pair_cmp(const void *a, const void *b)
-{
-       const CONF_PAIR *one = a;
-       const CONF_PAIR *two = b;
-
-       return strcmp(one->attr, two->attr);
-}
-
-
-/*
- *     rbtree callback function
- */
-static int section_cmp(const void *a, const void *b)
-{
-       const CONF_SECTION *one = a;
-       const CONF_SECTION *two = b;
-
-       return strcmp(one->name1, two->name1);
-}
-
-
-/*
- *     rbtree callback function
- */
-static int name2_cmp(const void *a, const void *b)
-{
-       const CONF_SECTION *one = a;
-       const CONF_SECTION *two = b;
-
-       rad_assert(strcmp(one->name1, two->name1) == 0);
-
-       if (!one->name2 && !two->name2) return 0;
-       if (!one->name2) return -1;
-       if (!two->name2) return +1;
-
-       return strcmp(one->name2, two->name2);
-}
-
-
-/*
- *     rbtree callback function
- */
-static int data_cmp(const void *a, const void *b)
-{
-       int rcode;
-
-       const CONF_DATA *one = a;
-       const CONF_DATA *two = b;
-
-       rcode = one->flag - two->flag;
-       if (rcode != 0) return rcode;
-
-       return strcmp(one->name, two->name);
-}
-
-
 /*
  *     Free strings we've parsed into data structures.
  */
@@ -266,42 +155,33 @@ static void cf_section_parse_free(void *base, const CONF_PARSER *variables)
 
        /*
         *      Don't automatically free the strings if we're being
-        *      called from a module.  This is also for clients.c,
-        *      where client_free() expects to be able to free the
-        *      client structure.  If we moved everything to key off
-        *      of the config files, we might solve some problems...
+        *      called from a module.
         */
-       if (!variables) return;
-
+       if (base || !variables) return;
+       
        /*
         *      Free up dynamically allocated string pointers.
         */
        for (i = 0; variables[i].name != NULL; i++) {
                char **p;
 
-               if ((variables[i].type != PW_TYPE_STRING_PTR) &&
-                   (variables[i].type != PW_TYPE_FILENAME)) {
+               if (variables[i].type != PW_TYPE_STRING_PTR) {
                        continue;
                }
 
                /*
-                *      No base struct offset, data must be the pointer.
-                *      If data doesn't exist, ignore the entry, there
-                *      must be something wrong.
+                *      Prefer the data, if it's there.
+                *      Else use the base + offset.
                 */
-               if (!base) {
-                       if (!variables[i].data) {
-                               continue;
-                       }
-
-                       p = (char **) variables[i].data;;
+               if (!variables[i].data) {
+                       continue;
+               }
 
-               } else if (variables[i].data) {
-                       p = (char **) variables[i].data;;
+               /*
+                *      FIXME: Add base
+                */
+               p = (char **) (variables[i].data);
 
-               } else {
-                       p = (char **) (((char *)base) + variables[i].offset);
-               }
 
                free(*p);
                *p = NULL;
@@ -310,6 +190,27 @@ static void cf_section_parse_free(void *base, const CONF_PARSER *variables)
 
 
 /*
+ *     Allocate a CONF_SECTION
+ */
+static CONF_SECTION *cf_section_alloc(const char *name1, const char *name2,
+                                     CONF_SECTION *parent, const char *cf)
+{
+       CONF_SECTION    *cs;
+
+       if (name1 == NULL || !name1[0])
+               name1 = "main";
+
+       cs = (CONF_SECTION *)rad_malloc(sizeof(CONF_SECTION));
+       memset(cs, 0, sizeof(CONF_SECTION));
+       cs->item.type = CONF_ITEM_SECTION;
+       cs->item.parent = parent;
+       cs->name1 = strdup(name1);
+       cs->name2 = (name2 && *name2) ? xstrdup(name2) : NULL;
+
+       return cs;
+}
+
+/*
  *     Free a CONF_SECTION
  */
 void cf_section_free(CONF_SECTION **cs)
@@ -324,29 +225,12 @@ void cf_section_free(CONF_SECTION **cs)
 
        for (ci = (*cs)->children; ci; ci = next) {
                next = ci->next;
-
-               switch (ci->type) {
-               case CONF_ITEM_PAIR: {
-                               CONF_PAIR *pair = cf_itemtopair(ci);
-                               cf_pair_free(&pair);
-                       }
-                       break;
-
-               case CONF_ITEM_SECTION: {
-
-                               CONF_SECTION *section = cf_itemtosection(ci);
-                               cf_section_free(&section);
-                       }
-                       break;
-
-               case CONF_ITEM_DATA: {
-                               CONF_DATA *data = cf_itemtodata(ci);
-                               cf_data_free(&data);
-                       }
-                       break;
-
-               default:        /* should really be an error. */
-                       break;
+               if (ci->type==CONF_ITEM_PAIR) {
+                       CONF_PAIR *pair = cf_itemtopair(ci);
+                       cf_pair_free(&pair);
+               } else {
+                       CONF_SECTION *section = cf_itemtosection(ci);
+                       cf_section_free(&section);
                }
        }
 
@@ -354,14 +238,6 @@ void cf_section_free(CONF_SECTION **cs)
                free((*cs)->name1);
        if ((*cs)->name2)
                free((*cs)->name2);
-       if ((*cs)->pair_tree)
-               rbtree_free((*cs)->pair_tree);
-       if ((*cs)->section_tree)
-               rbtree_free((*cs)->section_tree);
-       if ((*cs)->name2_tree)
-               rbtree_free((*cs)->name2_tree);
-       if ((*cs)->data_tree)
-               rbtree_free((*cs)->data_tree);
 
        /*
         * And free the section
@@ -374,148 +250,33 @@ void cf_section_free(CONF_SECTION **cs)
        *cs = NULL;
 }
 
-
-/*
- *     Allocate a CONF_SECTION
- */
-static CONF_SECTION *cf_section_alloc(const char *name1, const char *name2,
-                                     CONF_SECTION *parent)
-{
-       CONF_SECTION    *cs;
-
-       if (!name1) return NULL;
-
-       cs = rad_malloc(sizeof(*cs));
-       memset(cs, 0, sizeof(*cs));
-       cs->item.type = CONF_ITEM_SECTION;
-       cs->item.parent = parent;
-       cs->name1 = strdup(name1);
-       if (!cs->name1) {
-               cf_section_free(&cs);
-               return NULL;
-       }
-
-       if (name2 && *name2) {
-               cs->name2 = strdup(name2);
-               if (!cs->name2) {
-                       cf_section_free(&cs);
-                       return NULL;
-               }
-       }
-       cs->pair_tree = rbtree_create(pair_cmp, NULL, 0);
-       if (!cs->pair_tree) {
-               cf_section_free(&cs);
-               return NULL;
-       }
-
-       /*
-        *      Don't create a data tree, it may not be needed.
-        */
-
-       /*
-        *      Don't create the section tree here, it may not
-        *      be needed.
-        */
-
-       if (parent) cs->depth = parent->depth + 1;
-
-       return cs;
-}
-
-
 /*
  *     Add an item to a configuration section.
  */
-static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
+static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci_new)
 {
-       if (!cs->children) {
-               rad_assert(cs->tail == NULL);
-               cs->children = ci;
-       } else {
-               rad_assert(cs->tail != NULL);
-               cs->tail->next = ci;
-       }
-
-       /*
-        *      Update the trees (and tail) for each item added.
-        */
-       for (/* nothing */; ci != NULL; ci = ci->next) {
-               cs->tail = ci;
-
-               /*
-                *      For fast lookups, pair's and sections get
-                *      added to rbtree's.
-                */
-               switch (ci->type) {
-                       case CONF_ITEM_PAIR:
-                               rbtree_insert(cs->pair_tree, ci);
-                               break;
-
-                       case CONF_ITEM_SECTION: {
-                               const CONF_SECTION *cs_new = cf_itemtosection(ci);
-
-                               if (!cs->section_tree) {
-                                       cs->section_tree = rbtree_create(section_cmp, NULL, 0);
-                                       /* ignore any errors */
-                               }
-
-                               if (cs->section_tree) {
-                                       rbtree_insert(cs->section_tree, cs_new);                                }
-
-                               /*
-                                *      Two names: find the named instance.
-                                */
-                               if (cs_new->name2) {
-                                       CONF_SECTION *old_cs;
-
-                                       /*
-                                        *      Find the FIRST
-                                        *      CONF_SECTION having
-                                        *      the given name1, and
-                                        *      create a new tree
-                                        *      under it.
-                                        */
-                                       old_cs = rbtree_finddata(cs->section_tree, cs_new);
-                                       if (!old_cs) return; /* this is a bad error! */
-
-                                       if (!old_cs->name2_tree) {
-                                               old_cs->name2_tree = rbtree_create(name2_cmp,
-                                                                                  NULL, 0);
-                                       }
-                                       if (old_cs->name2_tree) {
-                                               rbtree_insert(old_cs->name2_tree, cs_new);
-                                       }
-                               } /* had a name2 */
-                               break;
-                       } /* was a section */
-
-                       case CONF_ITEM_DATA:
-                               if (!cs->data_tree) {
-                                       cs->data_tree = rbtree_create(data_cmp, NULL, 0);
-                               }
-                               if (cs->data_tree) {
-                                       rbtree_insert(cs->data_tree, ci);
-                               }
-                               break;
+       CONF_ITEM *ci;
 
-                       default: /* FIXME: assert & error! */
-                               break;
+       for (ci = cs->children; ci && ci->next; ci = ci->next)
+               ;
 
-               } /* switch over conf types */
-       } /* loop over ci */
+       if (ci == NULL)
+               cs->children = ci_new;
+       else
+               ci->next = ci_new;
 }
 
 /*
  *     Expand the variables in an input string.
  */
 static const char *cf_expand_variables(const char *cf, int *lineno,
-                                      const CONF_SECTION *outercs,
+                                      CONF_SECTION *outercs,
                                       char *output, const char *input)
 {
        char *p;
        const char *end, *ptr;
        char name[8192];
-       const CONF_SECTION *parentcs;
+       CONF_SECTION *parentcs;
 
        /*
         *      Find the master parent conf section.
@@ -537,12 +298,7 @@ static const char *cf_expand_variables(const char *cf, int *lineno,
                if ((*ptr == '$') && (ptr[1] == '{')) {
                        int up;
                        CONF_PAIR *cp;
-                       const CONF_SECTION *cs;
-
-                       /*
-                        *      FIXME: Add support for ${foo:-bar},
-                        *      like in xlat.c
-                        */
+                       CONF_SECTION *cs;
 
                        /*
                         *      Look for trailing '}', and log a
@@ -649,9 +405,7 @@ static const char *cf_expand_variables(const char *cf, int *lineno,
                                                if (!up) cp = cf_pair_find(parentcs, name);
                                        }
                                        if (cp == NULL) {
-                                               radlog(L_ERR, "config: No such configuration item %s in section %s when expanding string \"%s\"", name,
-                                                      cf_section_name1(cs),
-                                                      input);
+                                               radlog(L_ERR, "config: No such entry %s for string %s", name, input);
                                                return NULL;
                                        }
                                }
@@ -714,268 +468,165 @@ static const char *cf_expand_variables(const char *cf, int *lineno,
 
 
 /*
- *     Parses an item (not a CONF_ITEM) into the specified format,
- *     with a default value.
- *
- *     Returns -1 on error, 0 for correctly parsed, and 1 if the
- *     default value was used.  Note that the default value will be
- *     used ONLY if the CONF_PAIR is NULL.
+ *     Parse a configuration section into user-supplied variables.
  */
-int cf_item_parse(CONF_SECTION *cs, const char *name,
-                 int type, void *data, const char *dflt)
+int cf_section_parse(CONF_SECTION *cs, void *base,
+                    const CONF_PARSER *variables)
 {
-       int rcode = 0;
+       int i;
+       int rcode;
        char **q;
+       CONF_PAIR *cp;
+       CONF_SECTION *subsection;
+       uint32_t ipaddr;
+       char buffer[8192];
        const char *value;
-       lrad_ipaddr_t ipaddr;
-       const CONF_PAIR *cp;
-       char ipbuf[128];
-
-       cp = cf_pair_find(cs, name);
-       if (cp) {
-               value = cp->value;
-
-       } else if (!dflt) {
-               return 1;       /* nothing to parse, return default value */
-
-       } else {
-               rcode = 1;
-               value = dflt;
-       }
+       void *data;
 
-       switch (type) {
-       case PW_TYPE_BOOLEAN:
-               /*
-                *      Allow yes/no and on/off
-                */
-               if ((strcasecmp(value, "yes") == 0) ||
-                   (strcasecmp(value, "on") == 0)) {
-                       *(int *)data = 1;
-               } else if ((strcasecmp(value, "no") == 0) ||
-                          (strcasecmp(value, "off") == 0)) {
-                       *(int *)data = 0;
+       /*
+        *      Handle the user-supplied variables.
+        */
+       for (i = 0; variables[i].name != NULL; i++) {
+               value = variables[i].dflt;
+               if (variables[i].data) {
+                       data = variables[i].data; /* prefer this. */
+               } else if (base) {
+                       data = ((char *)base) + variables[i].offset;
                } else {
-                       *(int *)data = 0;
-                       radlog(L_ERR, "Bad value \"%s\" for boolean variable %s", value, name);
-                       return -1;
-               }
-               DEBUG2("\t%s = %s", name, value);
-               break;
-
-       case PW_TYPE_INTEGER:
-               *(int *)data = strtol(value, 0, 0);
-               DEBUG2("\t%s = %d", name, *(int *)data);
-               break;
-
-       case PW_TYPE_STRING_PTR:
-               q = (char **) data;
-               if (*q != NULL) {
-                       free(*q);
+                       data = variables[i].data;
                }
 
-               /*
-                *      Expand variables which haven't already been
-                *      expanded automagically when the configuration
-                *      file was read.
-                */
-               if (value == dflt) {
-                       char buffer[8192];
+               cp = cf_pair_find(cs, variables[i].name);
+               if (cp) {
+                       value = cp->value;
+               }
 
-                       int lineno = cs->item.lineno;
+               switch (variables[i].type)
+               {
+               case PW_TYPE_SUBSECTION:
+                       subsection = cf_section_sub_find(cs,variables[i].name);
 
                        /*
-                        *      FIXME: sizeof(buffer)?
+                        *      If the configuration section is NOT there,
+                        *      then ignore it.
+                        *
+                        *      FIXME! This is probably wrong... we should
+                        *      probably set the items to their default values.
                         */
-                       value = cf_expand_variables("?",
-                                                   &lineno,
-                                                   cs, buffer, value);
-                       if (!value) return -1;
-               }
+                       if (subsection == NULL) {
+                               break;
+                       }
 
-               DEBUG2("\t%s = \"%s\"", name, value ? value : "(null)");
-               *q = value ? strdup(value) : NULL;
-               break;
+                       rcode = cf_section_parse(subsection, base,
+                                                (CONF_PARSER *) data);
+                       if (rcode < 0) {
+                               cf_section_parse_free(base, variables);
+                               return -1;
+                       }
+                       break;
 
-               /*
-                *      This is the same as PW_TYPE_STRING_PTR,
-                *      except that we also "stat" the file, and
-                *      cache the result.
-                */
-       case PW_TYPE_FILENAME:
-               q = (char **) data;
-               if (*q != NULL) {
-                       free(*q);
-               }
+               case PW_TYPE_BOOLEAN:
+                       /*
+                        *      Allow yes/no and on/off
+                        */
+                       if ((strcasecmp(value, "yes") == 0) ||
+                                       (strcasecmp(value, "on") == 0)) {
+                               *(int *)data = 1;
+                       } else if ((strcasecmp(value, "no") == 0) ||
+                                               (strcasecmp(value, "off") == 0)) {
+                               *(int *)data = 0;
+                       } else {
+                               *(int *)data = 0;
+                               radlog(L_ERR, "Bad value \"%s\" for boolean variable %s", value, variables[i].name);
+                               cf_section_parse_free(base, variables);
+                               return -1;
+                       }
+                       DEBUG2(" %s: %s = %s",
+                                       cs->name1,
+                                       variables[i].name,
+                                       value);
+                       break;
 
-               /*
-                *      Expand variables which haven't already been
-                *      expanded automagically when the configuration
-                *      file was read.
-                */
-               if (value == dflt) {
-                       char buffer[8192];
+               case PW_TYPE_INTEGER:
+                       *(int *)data = strtol(value, 0, 0);
+                       DEBUG2(" %s: %s = %d",
+                                       cs->name1,
+                                       variables[i].name,
+                                       *(int *)data);
+                       break;
 
-                       int lineno = cs->item.lineno;
+               case PW_TYPE_STRING_PTR:
+                       q = (char **) data;
+                       if (*q != NULL) {
+                               free(*q);
+                       }
 
                        /*
-                        *      FIXME: sizeof(buffer)?
+                        *      Expand variables while parsing,
+                        *      but ONLY expand ones which haven't already
+                        *      been expanded.
                         */
-                       value = cf_expand_variables("?",
-                                                   &lineno,
-                                                   cs, buffer, value);
-                       if (!value) return -1;
-               }
-
-               DEBUG2("\t%s = \"%s\"", name, value ? value : "(null)");
-               *q = value ? strdup(value) : NULL;
-
-               /*
-                *      And now we "stat" the file.
-                */
-               if (*q) {
-                       struct stat buf;
+                       if (value && (value == variables[i].dflt)) {
+                               value = cf_expand_variables("?",
+                                                           &cs->item.lineno,
+                                                           cs, buffer, value);
+                               if (!value) {
+                                       cf_section_parse_free(base, variables);
+                                       return -1;
+                               }
+                       }
 
-                       if (stat(*q, &buf) == 0) {
-                               time_t *mtime;
+                       DEBUG2(" %s: %s = \"%s\"",
+                                       cs->name1,
+                                       variables[i].name,
+                                       value ? value : "(null)");
+                       *q = value ? strdup(value) : NULL;
+                       break;
 
-                               mtime = rad_malloc(sizeof(*mtime));
-                               *mtime = buf.st_mtime;
-                               /* FIXME: error? */
-                               cf_data_add_internal(cs, *q, mtime, free,
-                                                    PW_TYPE_FILENAME);
+               case PW_TYPE_IPADDR:
+                       /*
+                        *      Allow '*' as any address
+                        */
+                       if (strcmp(value, "*") == 0) {
+                               *(uint32_t *) data = 0;
+                               break;
                        }
-               }
-               break;
-
-       case PW_TYPE_IPADDR:
-               /*
-                *      Allow '*' as any address
-                */
-               if (strcmp(value, "*") == 0) {
-                       *(uint32_t *) data = htonl(INADDR_ANY);
-                       DEBUG2("\t%s = *", name);
+                       ipaddr = ip_getaddr(value);
+                       if (ipaddr == 0) {
+                               radlog(L_ERR, "Can't find IP address for host %s", value);
+                               cf_section_parse_free(base, variables);
+                               return -1;
+                       }
+                       DEBUG2(" %s: %s = %s IP address [%s]",
+                                       cs->name1,
+                                       variables[i].name,
+                                       value, ip_ntoa(buffer, ipaddr));
+                       *(uint32_t *) data = ipaddr;
                        break;
-               }
-               if (ip_hton(value, AF_INET, &ipaddr) < 0) {
-                       radlog(L_ERR, "Can't find IP address for host %s", value);
-                       return -1;
-               }
-               DEBUG2("\t%s = %s IP address [%s]", name, value,
-                              ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
-               *(uint32_t *) data = ipaddr.ipaddr.ip4addr.s_addr;
-               break;
-
-       case PW_TYPE_IPV6ADDR:
-               if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
-                       radlog(L_ERR, "Can't find IPv6 address for host %s", value);
+
+               default:
+                       radlog(L_ERR, "type %d not supported yet", variables[i].type);
+                       cf_section_parse_free(base, variables);
                        return -1;
-               }
-               DEBUG2("\t%s = %s IPv6 address [%s]", name, value,
-                              ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
-               memcpy(data, &ipaddr.ipaddr.ip6addr,
-                      sizeof(ipaddr.ipaddr.ip6addr));
-               break;
-
-       default:
-               radlog(L_ERR, "type %d not supported yet", type);
-               return -1;
-               break;
-       } /* switch over variable type */
-
-       return rcode;
+                       break;
+               } /* switch over variable type */
+       } /* for all variables in the configuration section */
+
+       cs->base = base;
+       cs->variables = variables;
+
+       return 0;
 }
 
-static const char *parse_spaces = "                                                                                                                                                                                                                                                                ";
 
 /*
- *     Parse a configuration section into user-supplied variables.
+ *     Read a part of the config file.
  */
-int cf_section_parse(CONF_SECTION *cs, void *base,
-                    const CONF_PARSER *variables)
+static CONF_SECTION *cf_section_read(const char *cf, int *lineno, FILE *fp,
+                                    const char *name1, const char *name2,
+                                    CONF_SECTION *parent)
 {
-       int i;
-       void *data;
-
-       if (!cs->name2) {
-               DEBUG2("%.*s%s {", cs->depth, parse_spaces,
-                      cs->name1);
-       } else {
-               DEBUG2("%.*s%s %s {", cs->depth, parse_spaces,
-                      cs->name1, cs->name2);
-       }
-
-       /*
-        *      Handle the known configuration parameters.
-        */
-       for (i = 0; variables[i].name != NULL; i++) {
-               /*
-                *      Handle subsections specially
-                */
-               if (variables[i].type == PW_TYPE_SUBSECTION) {
-                       const CONF_SECTION *subcs;
-                       subcs = cf_section_sub_find(cs, variables[i].name);
-
-                       /*
-                        *      If the configuration section is NOT there,
-                        *      then ignore it.
-                        *
-                        *      FIXME! This is probably wrong... we should
-                        *      probably set the items to their default values.
-                        */
-                       if (!subcs) continue;
-
-                       if (!variables[i].dflt) {
-                               DEBUG2("Internal sanity check 1 failed in cf_section_parse");
-                               goto error;
-                       }
-
-                       if (cf_section_parse(subcs, base,
-                                            (const CONF_PARSER *) variables[i].dflt) < 0) {
-                               goto error;
-                       }
-                       continue;
-               } /* else it's a CONF_PAIR */
-
-               if (variables[i].data) {
-                       data = variables[i].data; /* prefer this. */
-               } else if (base) {
-                       data = ((char *)base) + variables[i].offset;
-               } else {
-                       DEBUG2("Internal sanity check 2 failed in cf_section_parse");
-                       goto error;
-               }
-
-               /*
-                *      Parse the pair we found, or a default value.
-                */
-               if (cf_item_parse(cs, variables[i].name, variables[i].type,
-                                 data, variables[i].dflt) < 0) {
-                       goto error;
-               }
-       } /* for all variables in the configuration section */
-
-       DEBUG2("%.*s}", cs->depth, parse_spaces);
-
-       cs->base = base;
-       cs->variables = variables;
-
-       return 0;
-
- error:
-       DEBUG2("%.*s}", cs->depth, parse_spaces);
-       cf_section_parse_free(base, variables);
-       return -1;
-}
-
-
-/*
- *     Read a part of the config file.
- */
-static int cf_section_read(const char *file, int *lineno, FILE *fp,
-                          CONF_SECTION *current)
-
-{
-       CONF_SECTION *this, *css;
+       CONF_SECTION *cs, *css;
        CONF_PAIR *cpn;
        char *ptr;
        const char *value;
@@ -987,7 +638,21 @@ static int cf_section_read(const char *file, int *lineno, FILE *fp,
        char *cbuf = buf;
        int len;
 
-       this = current;         /* add items here */
+       /*
+        *      Ensure that the user can't add CONF_SECTIONs
+        *      with 'internal' names;
+        */
+       if ((name1 != NULL) && (name1[0] == '_')) {
+               radlog(L_ERR, "%s[%d]: Illegal configuration section name",
+                       cf, *lineno);
+               return NULL;
+       }
+
+       /*
+        *      Allocate new section.
+        */
+       cs = cf_section_alloc(name1, name2, parent, cf);
+       cs->item.lineno = *lineno;
 
        /*
         *      Read, checking for line continuations ('\\' at EOL)
@@ -1007,10 +672,11 @@ static int cf_section_read(const char *file, int *lineno, FILE *fp,
                 *      We've filled the buffer, and there isn't
                 *      a CR in it.  Die!
                 */
-               if ((cbuf[len - 1] != '\n') && !feof(fp)) {
+               if (cbuf[len - 1] != '\n') {
                        radlog(L_ERR, "%s[%d]: Line too long",
-                              file, *lineno);
-                       return -1;
+                              cf, *lineno);
+                       cf_section_free(&cs);
+                       return NULL;
                }
 
                /*
@@ -1025,8 +691,9 @@ static int cf_section_read(const char *file, int *lineno, FILE *fp,
                if ((len > 0) && (cbuf[len - 1] == '\\')) {
                        if (len >= (sizeof(buf) - 5)) {
                                radlog(L_ERR, "%s[%d]: Line too long",
-                                      file, *lineno);
-                               return -1;
+                                      cf, *lineno);
+                               cf_section_free(&cs);
+                               return NULL;
                        }
 
                        cbuf[len - 1] = '\0';
@@ -1044,25 +711,11 @@ static int cf_section_read(const char *file, int *lineno, FILE *fp,
                ptr = cbuf = buf;
                t1 = gettoken(&ptr, buf1, sizeof(buf1));
 
-               if ((*buf1 == '#') || (*buf1 == '\0')) {
-                       continue;
-               }
-
                /*
-                *      The caller eats "name1 name2 {", and calls us
-                *      for the data inside of the section.  So if we
-                *      receive a closing brace, then it must mean the
-                *      end of the section.
+                *      Skip comments and blank lines immediately.
                 */
-              if (t1 == T_RCBRACE) {
-                      if (this == current) {
-                              radlog(L_ERR, "%s[%d]: Too many closing braces",
-                                     file, *lineno);
-                              return -1;
-
-                      }
-                      this = this->item.parent;
-                      continue;
+               if ((*buf1 == '#') || (*buf1 == '\0')) {
+                       continue;
                }
 
                /*
@@ -1072,274 +725,222 @@ static int cf_section_read(const char *file, int *lineno, FILE *fp,
                 *      I really really really hate this file.  -cparker
                 */
                if (strcasecmp(buf1, "$INCLUDE") == 0) {
+
+                       CONF_SECTION      *is;
+
                        t2 = getword(&ptr, buf2, sizeof(buf2));
 
-                       value = cf_expand_variables(file, lineno, this, buf, buf2);
-                       if (!value) return -1;
+                       value = cf_expand_variables(cf, lineno, cs, buf, buf2);
+                       if (value == NULL) {
+                               cf_section_free(&cs);
+                               return NULL;
+                       }
 
-#ifdef HAVE_DIRENT_H
-                       /*
-                        *      $INCLUDE foo/
-                        *
-                        *      Include ALL non-"dot" files in the directory.
-                        *      careful!
-                        */
-                       if (value[strlen(value) - 1] == '/') {
-                               DIR             *dir;
-                               struct dirent   *dp;
-                               struct stat stat_buf;
-
-                               DEBUG2( "Config:   including files in directory: %s", value );
-                               dir = opendir(value);
-                               if (!dir) {
-                                       radlog(L_ERR, "%s[%d]: Error reading directory %s: %s",
-                                              file, *lineno, value,
-                                              strerror(errno));
-                                       return -1;
-                               }
+                       DEBUG2( "Config:   including file: %s", value );
 
-                               /*
-                                *      Read the directory, ignoring "." files.
-                                */
-                               while ((dp = readdir(dir)) != NULL) {
-                                       const char *p;
+                       if ((is = conf_read(cf, *lineno, value, cs)) == NULL) {
+                               cf_section_free(&cs);
+                               return NULL;
+                       }
 
-                                       if (dp->d_name[0] == '.') continue;
+                       /*
+                        *      Add the included conf to our CONF_SECTION
+                        */
+                       if (is != NULL) {
+                               if (is->children != NULL) {
+                                       CONF_ITEM *ci;
 
                                        /*
-                                        *      Check for valid characters
+                                        *      Re-write the parent of the
+                                        *      moved children to be the
+                                        *      upper-layer section.
                                         */
-                                       for (p = dp->d_name; *p != '\0'; p++) {
-                                               if (isalpha((int)*p) ||
-                                                   isdigit((int)*p) ||
-                                                   (*p == '_') ||
-                                                   (*p == '.')) continue;
-                                               break;
+                                       for (ci = is->children; ci; ci = ci->next) {
+                                               ci->parent = cs;
                                        }
-                                       if (*p != '\0') continue;
 
-                                       snprintf(buf2, sizeof(buf2), "%s%s",
-                                                value, dp->d_name);
-                                       if ((stat(buf2, &stat_buf) != 0) ||
-                                           S_ISDIR(stat_buf.st_mode)) continue;
                                        /*
-                                        *      Read the file into the current
-                                        *      configuration sectoin.
+                                        *      If there are children, then
+                                        *      move them up a layer.
                                         */
-                                       if (cf_file_include(buf2, this) < 0) {
-                                               closedir(dir);
-                                               return -1;
+                                       if (is->children) {
+                                               cf_item_add(cs, is->children);
                                        }
+                                       is->children = NULL;
                                }
-                               closedir(dir);
-                       }  else
-#endif
-                       { /* it was a normal file */
-                               if (cf_file_include(value, this) < 0) {
-                                       return -1;
-                               }
+                               /*
+                                *      Always free the section for the
+                                *      $INCLUDEd file.
+                                */
+                               cf_section_free(&is);
                        }
+
                        continue;
-               } /* we were in an include */
+               }
 
                /*
-                *      Ensure that the user can't add CONF_PAIRs
-                *      with 'internal' names;
+                *      No '=': must be a section or sub-section.
                 */
-               if (buf1[0] == '_') {
-                       radlog(L_ERR, "%s[%d]: Illegal configuration pair name \"%s\"",
-                                       file, *lineno, buf1);
-                       return -1;
+               if (strchr(ptr, '=') == NULL) {
+                       t2 = gettoken(&ptr, buf2, sizeof(buf2));
+                       t3 = gettoken(&ptr, buf3, sizeof(buf3));
+               } else {
+                       t2 = gettoken(&ptr, buf2, sizeof(buf2));
+                       t3 = getword(&ptr, buf3, sizeof(buf3));
                }
 
                /*
-                *      Grab the next token.
+                *      See if it's the end of a section.
                 */
-               t2 = gettoken(&ptr, buf2, sizeof(buf2));
-               switch (t2) {
-               case T_EOL:
-               case T_HASH:
-               case T_OP_EQ:
-               case T_OP_SET:
-                       t3 = getword(&ptr, buf3, sizeof(buf3));
-                       t2 = T_OP_EQ;
-
-                       /*
-                        *      Handle variable substitution via ${foo}
-                        */
-                       value = cf_expand_variables(file, lineno, this,
-                                                   buf, buf3);
-                       if (!value) return -1;
-                       
-                       
-                       /*
-                        *      Add this CONF_PAIR to our CONF_SECTION
-                        */
-                       cpn = cf_pair_alloc(buf1, value, t2, this);
-                       cpn->item.lineno = *lineno;
-                       cf_item_add(this, cf_pairtoitem(cpn));
-                       continue;
-
-                       /*
-                        *      No '=', must be a section or sub-section.
-                        */
-               case T_BARE_WORD:
-               case T_DOUBLE_QUOTED_STRING:
-               case T_SINGLE_QUOTED_STRING:
-                       t3 = gettoken(&ptr, buf3, sizeof(buf3));
-                       if (t3 != T_LCBRACE) {
-                               radlog(L_ERR, "%s[%d]: Expecting section start brace '{' after \"%s %s\"",
-                                      file, *lineno, buf1, buf2);
-                               return -1;
+               if (t1 == T_RCBRACE) {
+                       if (name1 == NULL || buf2[0]) {
+                               radlog(L_ERR, "%s[%d]: Unexpected end of section",
+                                               cf, *lineno);
+                               cf_section_free(&cs);
+                               return NULL;
                        }
+                       return cs;
+               }
 
-               case T_LCBRACE:
-                       css = cf_section_alloc(buf1,
-                                              t2 == T_LCBRACE ? NULL : buf2,
-                                              this);
-                       if (!css) {
-                               radlog(L_ERR, "%s[%d]: Failed allocating memory for section",
-                                               file, *lineno);
-                               return -1;
+               /*
+                * Perhaps a subsection.
+                */
+               if (t2 == T_LCBRACE || t3 == T_LCBRACE) {
+                       css = cf_section_read(cf, lineno, fp, buf1,
+                                             t2==T_LCBRACE ? NULL : buf2, cs);
+                       if (css == NULL) {
+                               cf_section_free(&cs);
+                               return NULL;
                        }
-                       cf_item_add(this, cf_sectiontoitem(css));
-                       css->item.lineno = *lineno;
+                       cf_item_add(cs, cf_sectiontoitem(css));
 
-                       /*
-                        *      The current section is now the child section.
-                        */
-                       this = css;
                        continue;
+               }
 
-               default:
-                       radlog(L_ERR, "%s[%d]: Parse error after \"%s\"",
-                              file, *lineno, buf1);
-                       return -1;
+               /*
+                *      Ignore semi-colons.
+                */
+               if (*buf2 == ';')
+                       *buf2 = '\0';
+
+               /*
+                *      Must be a normal attr = value line.
+                */
+               if (buf1[0] != 0 && buf2[0] == 0 && buf3[0] == 0) {
+                       t2 = T_OP_EQ;
+               } else if (buf1[0] == 0 || buf2[0] == 0 ||
+                          (t2 < T_EQSTART || t2 > T_EQEND)) {
+                       radlog(L_ERR, "%s[%d]: Line is not in 'attribute = value' format",
+                                       cf, *lineno);
+                       cf_section_free(&cs);
+                       return NULL;
+               }
+
+               /*
+                *      Ensure that the user can't add CONF_PAIRs
+                *      with 'internal' names;
+                */
+               if (buf1[0] == '_') {
+                       radlog(L_ERR, "%s[%d]: Illegal configuration pair name \"%s\"",
+                                       cf, *lineno, buf1);
+                       cf_section_free(&cs);
+                       return NULL;
+               }
+
+               /*
+                *      Handle variable substitution via ${foo}
+                */
+               value = cf_expand_variables(cf, lineno, cs, buf, buf3);
+               if (!value) {
+                       cf_section_free(&cs);
+                       return NULL;
                }
+
+
+               /*
+                *      Add this CONF_PAIR to our CONF_SECTION
+                */
+               cpn = cf_pair_alloc(buf1, value, t2, parent);
+               cpn->item.lineno = *lineno;
+               cf_item_add(cs, cf_pairtoitem(cpn));
        }
 
        /*
         *      See if EOF was unexpected ..
         */
-       if (feof(fp) && (this != current)) {
-               radlog(L_ERR, "%s[%d]: EOF reached without closing brace for section %s starting at line %d",
-                      file, *lineno,
-                      cf_section_name1(this), cf_section_lineno(this));
-               return -1;
+       if (name1 != NULL) {
+               radlog(L_ERR, "%s[%d]: Unexpected end of file", cf, *lineno);
+               cf_section_free(&cs);
+               return NULL;
        }
 
-       return 0;
+       return cs;
 }
 
 /*
- *     Include one config file in another.
+ *     Read the config file.
  */
-int cf_file_include(const char *file, CONF_SECTION *cs)
+CONF_SECTION *conf_read(const char *fromfile, int fromline,
+                       const char *conffile, CONF_SECTION *parent)
 {
        FILE            *fp;
        int             lineno = 0;
+       CONF_SECTION    *cs;
        struct stat     statbuf;
-       time_t          *mtime;
+       char            buf[8192];
 
-       DEBUG2( "Config:   including file: %s", file);
+       buf[0] = '\0';
+       if (fromfile) {
+               snprintf(buf, sizeof(buf), "%s[%d]: ", fromfile, fromline);
+       }
 
-       if (stat(file, &statbuf) == 0) {
-#ifdef S_IWOTH
+       if (stat(conffile, &statbuf) == 0) {
                if ((statbuf.st_mode & S_IWOTH) != 0) {
-                       radlog(L_ERR|L_CONS, "Configuration file %s is globally writable.  Refusing to start due to insecure configuration.",
-                              file);
-                       return -1;
+                       radlog(L_ERR|L_CONS, "%sConfiguration file %s is globally writable.  Refusing to start due to insecure configuration.",
+                              buf[0] ? buf : "", conffile);
+                       return NULL;
                }
-#endif
 
-#ifdef S_IROTH
                if (0 && (statbuf.st_mode & S_IROTH) != 0) {
-                       radlog(L_ERR|L_CONS, "Configuration file %s is globally readable.  Refusing to start due to insecure configuration.",
-                              file);
-                       return -1;
+                       radlog(L_ERR|L_CONS, "%sConfiguration file %s is globally readable.  Refusing to start due to insecure configuration.",
+                              buf[0] ? buf : "", conffile);
+                       return NULL;
                }
-#endif
-       }
-
-       fp = fopen(file, "r");
-       if (!fp) {
-               radlog(L_ERR|L_CONS, "Unable to open file \"%s\": %s",
-                      file, strerror(errno));
-               return -1;
        }
 
-       /*
-        *      Read the section.  It's OK to have EOF without a
-        *      matching close brace.
-        */
-       if (cf_section_read(file, &lineno, fp, cs) < 0) {
-               fclose(fp);
-               return -1;
+       if ((fp = fopen(conffile, "r")) == NULL) {
+               radlog(L_ERR|L_CONS, "%sUnable to open file \"%s\": %s",
+                      buf[0] ? buf : "", conffile, strerror(errno));
+               return NULL;
        }
 
-       /*
-        *      Add the filename to the section
-        */
-       mtime = rad_malloc(sizeof(*mtime));
-       *mtime = statbuf.st_mtime;
-       /* FIXME: error? */
-       cf_data_add_internal(cs, file, mtime, free,
-                            PW_TYPE_FILENAME);
+       cs = cf_section_read(conffile, &lineno, fp, NULL, NULL, parent);
 
        fclose(fp);
-       return 0;
-}
-
-/*
- *     Bootstrap a config file.
- */
-CONF_SECTION *cf_file_read(const char *file)
-{
-       CONF_SECTION *cs;
-
-       cs = cf_section_alloc("main", NULL, NULL);
-       if (!cs) return NULL;
-
-       if (cf_file_include(file, cs) < 0) {
-               cf_section_free(&cs);
-               return NULL;
-       }
 
        return cs;
 }
 
+
 /*
  * Return a CONF_PAIR within a CONF_SECTION.
  */
-CONF_PAIR *cf_pair_find(const CONF_SECTION *cs, const char *name)
+CONF_PAIR *cf_pair_find(CONF_SECTION *section, const char *name)
 {
        CONF_ITEM       *ci;
-       CONF_PAIR       *cp = NULL;
-
-       if (!cs) cs = mainconfig.config;
 
-       /*
-        *      Find the name in the tree, for speed.
-        */
-       if (name) {
-               CONF_PAIR mycp;
-
-               mycp.attr = name;
-               cp = rbtree_finddata(cs->pair_tree, &mycp);
-       } else {
-               /*
-                *      Else find the first one that matches
-                */
-               for (ci = cs->children; ci; ci = ci->next) {
-                       if (ci->type == CONF_ITEM_PAIR) {
-                               return cf_itemtopair(ci);
-                       }
-               }
+       if (section == NULL) {
+               section = mainconfig.config;
        }
 
-       if (cp || !cs->template) return cp;
+       for (ci = section->children; ci; ci = ci->next) {
+               if (ci->type != CONF_ITEM_PAIR)
+                       continue;
+               if (name == NULL || strcmp(cf_itemtopair(ci)->attr, name) == 0)
+                       break;
+       }
 
-       return cf_pair_find(cs->template, name);
+       return cf_itemtopair(ci);
 }
 
 /*
@@ -1364,28 +965,28 @@ char *cf_pair_value(CONF_PAIR *pair)
  * Return the first label of a CONF_SECTION
  */
 
-const char *cf_section_name1(const CONF_SECTION *cs)
+char *cf_section_name1(CONF_SECTION *section)
 {
-       return (cs ? cs->name1 : NULL);
+       return (section ? section->name1 : NULL);
 }
 
 /*
  * Return the second label of a CONF_SECTION
  */
 
-const char *cf_section_name2(const CONF_SECTION *cs)
+char *cf_section_name2(CONF_SECTION *section)
 {
-       return (cs ? cs->name2 : NULL);
+       return (section ? section->name2 : NULL);
 }
 
 /*
  * Find a value in a CONF_SECTION
  */
-char *cf_section_value_find(const CONF_SECTION *cs, const char *attr)
+char *cf_section_value_find(CONF_SECTION *section, const char *attr)
 {
        CONF_PAIR       *cp;
 
-       cp = cf_pair_find(cs, attr);
+       cp = cf_pair_find(section, attr);
 
        return (cp ? cp->value : NULL);
 }
@@ -1396,8 +997,7 @@ char *cf_section_value_find(const CONF_SECTION *cs, const char *attr)
  * attr is NULL, any attr matches.
  */
 
-CONF_PAIR *cf_pair_find_next(const CONF_SECTION *cs,
-                            const CONF_PAIR *pair, const char *attr)
+CONF_PAIR *cf_pair_find_next(CONF_SECTION *section, CONF_PAIR *pair, const char *attr)
 {
        CONF_ITEM       *ci;
 
@@ -1407,7 +1007,7 @@ CONF_PAIR *cf_pair_find_next(const CONF_SECTION *cs,
         */
 
        if (pair == NULL){
-               return cf_pair_find(cs, attr);
+               return cf_pair_find(section, attr);
        }
 
        ci = cf_pairtoitem(pair)->next;
@@ -1438,22 +1038,11 @@ CONF_SECTION *cf_section_find(const char *name)
  * Find a sub-section in a section
  */
 
-CONF_SECTION *cf_section_sub_find(const CONF_SECTION *cs, const char *name)
+CONF_SECTION *cf_section_sub_find(CONF_SECTION *section, const char *name)
 {
        CONF_ITEM *ci;
 
-       /*
-        *      Do the fast lookup if possible.
-        */
-       if (name && cs->section_tree) {
-               CONF_SECTION mycs;
-
-               mycs.name1 = name;
-               mycs.name2 = NULL;
-               return rbtree_finddata(cs->section_tree, &mycs);
-       }
-
-       for (ci = cs->children; ci; ci = ci->next) {
+       for (ci = section->children; ci; ci = ci->next) {
                if (ci->type != CONF_ITEM_SECTION)
                        continue;
                if (strcmp(cf_itemtosection(ci)->name1, name) == 0)
@@ -1464,59 +1053,6 @@ CONF_SECTION *cf_section_sub_find(const CONF_SECTION *cs, const char *name)
 
 }
 
-
-/*
- *     Find a CONF_SECTION with both names.
- */
-CONF_SECTION *cf_section_sub_find_name2(const CONF_SECTION *cs,
-                                       const char *name1, const char *name2)
-{
-       CONF_ITEM    *ci;
-
-       if (!name2) return cf_section_sub_find(cs, name1);
-
-       if (!cs) cs = mainconfig.config;
-
-       if (name1 && (cs->section_tree)) {
-               CONF_SECTION mycs, *master_cs;
-
-               mycs.name1 = name1;
-               mycs.name2 = name2;
-
-               master_cs = rbtree_finddata(cs->section_tree, &mycs);
-               if (master_cs) {
-                       return rbtree_finddata(master_cs->name2_tree, &mycs);
-               }
-       }
-
-       /*
-        *      Else do it the old-fashioned way.
-        */
-       for (ci = cs->children; ci; ci = ci->next) {
-               CONF_SECTION *subcs;
-
-               if (ci->type != CONF_ITEM_SECTION)
-                       continue;
-
-               subcs = cf_itemtosection(ci);
-               if (!name1) {
-                       if (!subcs->name2) {
-                               if (strcmp(subcs->name1, name2) == 0) break;
-                       } else {
-                               if (strcmp(subcs->name2, name2) == 0) break;
-                       }
-                       continue; /* don't do the string comparisons below */
-               }
-
-               if ((strcmp(subcs->name1, name1) == 0) &&
-                   (subcs->name2 != NULL) &&
-                   (strcmp(subcs->name2, name2) == 0))
-                       break;
-       }
-
-       return cf_itemtosection(ci);
-}
-
 /*
  * Return the next subsection after a CONF_SECTION
  * with a certain name1 (char *name1). If the requested
@@ -1524,8 +1060,8 @@ CONF_SECTION *cf_section_sub_find_name2(const CONF_SECTION *cs,
  */
 
 CONF_SECTION *cf_subsection_find_next(CONF_SECTION *section,
-                                     CONF_SECTION *subsection,
-                                     const char *name1)
+               CONF_SECTION *subsection,
+               const char *name1)
 {
        CONF_ITEM       *ci;
 
@@ -1544,7 +1080,7 @@ CONF_SECTION *cf_subsection_find_next(CONF_SECTION *section,
                if (ci->type != CONF_ITEM_SECTION)
                        continue;
                if ((name1 == NULL) ||
-                   (strcmp(cf_itemtosection(ci)->name1, name1) == 0))
+                               (strcmp(cf_itemtosection(ci)->name1, name1) == 0))
                        break;
        }
 
@@ -1589,297 +1125,6 @@ int cf_item_is_pair(CONF_ITEM *item)
 }
 
 
-static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, const char *name,
-                               void *data, void (*data_free)(void *))
-{
-       CONF_DATA *cd;
-
-       cd = rad_malloc(sizeof(*cd));
-       memset(cd, 0, sizeof(*cd));
-
-       cd->item.type = CONF_ITEM_DATA;
-       cd->item.parent = parent;
-       cd->name = strdup(name);
-       cd->data = data;
-       cd->free = data_free;
-
-       return cd;
-}
-
-
-static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,
-                                  int flag)
-{
-       if (!cs || !name) return NULL;
-
-       /*
-        *      Find the name in the tree, for speed.
-        */
-       if (cs->data_tree) {
-               CONF_DATA mycd, *cd;
-
-               mycd.name = name;
-               mycd.flag = flag;
-               cd = rbtree_finddata(cs->data_tree, &mycd);
-               if (cd) return cd->data;
-       }
-
-       return NULL;
-}
-
-/*
- *     Find data from a particular section.
- */
-void *cf_data_find(CONF_SECTION *cs, const char *name)
-{
-       return cf_data_find_internal(cs, name, 0);
-}
-
-
-/*
- *     Add named data to a configuration section.
- */
-static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
-                               void *data, void (*data_free)(void *),
-                               int flag)
-{
-       CONF_DATA *cd;
-
-       if (!cs || !name) return -1;
-
-       /*
-        *      Already exists.  Can't add it.
-        */
-       if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
-
-       cd = cf_data_alloc(cs, name, data, data_free);
-       if (!cd) return -1;
-       cd->flag = flag;
-
-       cf_item_add(cs, cf_datatoitem(cd));
-
-       return 0;
-}
-
-/*
- *     Add named data to a configuration section.
- */
-int cf_data_add(CONF_SECTION *cs, const char *name,
-               void *data, void (*data_free)(void *))
-{
-       return cf_data_add_internal(cs, name, data, data_free, 0);
-}
-
-
-/*
- *     Copy CONF_DATA from src to dst
- */
-static void cf_section_copy_data(CONF_SECTION *s, CONF_SECTION *d)
-{
-
-       CONF_ITEM *cd, *next, **last;
-
-       /*
-        *      Don't check if s->data_tree is NULL.  It's child
-        *      sections may have data, even if this section doesn't.
-        */
-
-       rad_assert(d->data_tree == NULL);
-       d->data_tree = s->data_tree;
-       s->data_tree = NULL;
-
-       /*
-        *      Walk through src, moving CONF_ITEM_DATA
-        *      to dst, by hand.
-        */
-       last = &(s->children);
-       for (cd = s->children; cd != NULL; cd = next) {
-               next = cd->next;
-
-               /*
-                *      Recursively copy data from child sections.
-                */
-               if (cd->type == CONF_ITEM_SECTION) {
-                       CONF_SECTION *s1, *d1;
-
-                       s1 = cf_itemtosection(cd);
-                       d1 = cf_section_sub_find_name2(d, s1->name1, s1->name2);
-                       if (d1) {
-                               cf_section_copy_data(s1, d1);
-                       }
-                       last = &(cd->next);
-                       continue;
-               }
-
-               /*
-                *      Not conf data, remember last ptr.
-                */
-               if (cd->type != CONF_ITEM_DATA) {
-                       last = &(cd->next);
-                       continue;
-               }
-
-               /*
-                *      Remove it from the src list
-                */
-               *last = cd->next;
-               cd->next = NULL;
-
-               /*
-                *      Add it to the dst list
-                */
-               if (!d->children) {
-                       rad_assert(d->tail == NULL);
-                       d->children = cd;
-               } else {
-                       rad_assert(d->tail != NULL);
-                       d->tail->next = cd;
-               }
-               d->tail = cd;
-       }
-}
-
-/*
- *     For a CONF_DATA element, stat the filename, if necessary.
- */
-static int filename_stat(void *context, void *data)
-{
-       struct stat buf;
-       CONF_DATA *cd = data;
-
-       context = context;      /* -Wunused */
-
-       if (cd->flag != PW_TYPE_FILENAME) return 0;
-
-       if (stat(cd->name, &buf) < 0) return -1;
-
-       if (buf.st_mtime != *(time_t *) cd->data) return -1;
-
-       return 0;
-}
-
-
-/*
- *     Compare two CONF_SECTIONS.  The items MUST be in the same
- *     order.
- */
-static int cf_section_cmp(CONF_SECTION *a, CONF_SECTION *b)
-{
-       CONF_ITEM *ca = a->children;
-       CONF_ITEM *cb = b->children;
-
-       while (1) {
-               CONF_PAIR *pa, *pb;
-
-               /*
-                *      Done.  Stop.
-                */
-               if (!ca && !cb) break;
-
-               /*
-                *      Skip CONF_DATA.
-                */
-               if (ca && ca->type == CONF_ITEM_DATA) {
-                       ca = ca->next;
-                       continue;
-               }
-               if (cb && cb->type == CONF_ITEM_DATA) {
-                       cb = cb->next;
-                       continue;
-               }
-
-               /*
-                *      One is smaller than the other.  Exit.
-                */
-               if (!ca || !cb) return 0;
-
-               if (ca->type != cb->type) return 0;
-
-               /*
-                *      Deal with subsections.
-                */
-               if (ca->type == CONF_ITEM_SECTION) {
-                       CONF_SECTION *sa = cf_itemtosection(ca);
-                       CONF_SECTION *sb = cf_itemtosection(cb);
-
-                       if (!cf_section_cmp(sa, sb)) return 0;
-                       goto next;
-               }
-
-               rad_assert(ca->type == CONF_ITEM_PAIR);
-
-               pa = cf_itemtopair(ca);
-               pb = cf_itemtopair(cb);
-
-               /*
-                *      Different attr and/or value, Exit.
-                */
-               if ((strcmp(pa->attr, pb->attr) != 0) ||
-                   (strcmp(pa->value, pb->value) != 0)) return 0;
-
-
-               /*
-                *      And go to the next element.
-                */
-       next:
-               ca = ca->next;
-               cb = cb->next;
-       }
-
-       /*
-        *      Walk over the CONF_DATA, stat'ing PW_TYPE_FILENAME.
-        */
-       if (a->data_tree &&
-           (rbtree_walk(a->data_tree, InOrder, filename_stat, NULL) != 0)) {
-               return 0;
-       }
-
-       /*
-        *      They must be the same, say so.
-        */
-       return 1;
-}
-
-
-/*
- *     Migrate CONF_DATA from one section to another.
- */
-int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src)
-{
-       CONF_ITEM *ci;
-       CONF_SECTION *s, *d;
-
-       for (ci = src->children; ci != NULL; ci = ci->next) {
-               if (ci->type != CONF_ITEM_SECTION)
-                       continue;
-
-               s = cf_itemtosection(ci);
-               d = cf_section_sub_find_name2(dst, s->name1, s->name2);
-
-               if (!d) continue; /* not in new one, don't migrate it */
-
-               /*
-                *      A section of the same name is in BOTH src & dst,
-                *      compare the CONF_PAIR's.  If they're all the same,
-                *      then copy the CONF_DATA from one to the other.
-                */
-               if (cf_section_cmp(s, d)) {
-                       cf_section_copy_data(s, d);
-               }
-       }
-
-       return 1;               /* rcode means anything? */
-}
-
-int cf_section_template(CONF_SECTION *cs, CONF_SECTION *template)
-{
-       if (!cs || !template || cs->template || template->template) return -1;
-
-       cs->template = template;
-
-       return 0;
-}
-
 #if 0
 /*
  * JMG dump_config tries to dump the config structure in a readable format
@@ -1897,15 +1142,12 @@ static int dump_config_section(CONF_SECTION *cs, int indent)
         * so I had to get creative. --Pac. */
 
        for (ci = cs->children; ci; ci = ci->next) {
-               switch (ci->type) {
-               case CONF_ITEM_PAIR:
+               if (ci->type == CONF_ITEM_PAIR) {
                        cp=cf_itemtopair(ci);
                        DEBUG("%.*s%s = %s",
                                indent, "\t\t\t\t\t\t\t\t\t\t\t",
                                cp->attr, cp->value);
-                       break;
-
-               case CONF_ITEM_SECTION:
+               } else {
                        scs=cf_itemtosection(ci);
                        DEBUG("%.*s%s %s%s{",
                                indent, "\t\t\t\t\t\t\t\t\t\t\t",
@@ -1915,10 +1157,6 @@ static int dump_config_section(CONF_SECTION *cs, int indent)
                        dump_config_section(scs, indent+1);
                        DEBUG("%.*s}",
                                indent, "\t\t\t\t\t\t\t\t\t\t\t");
-                       break;
-
-               default:        /* FIXME: Do more! */
-                       break;
                }
        }
 
diff --git a/src/main/event.c b/src/main/event.c
deleted file mode 100644 (file)
index 818b5c3..0000000
+++ /dev/null
@@ -1,2124 +0,0 @@
-/*
- * event.c     Server event handling
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2007  The FreeRADIUS server project
- * Copyright 2007  Alan DeKok <aland@deployingradius.com>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/event.h>
-#include <freeradius-devel/radius_snmp.h>
-
-#include <freeradius-devel/rad_assert.h>
-
-#define USEC (1000000)
-
-/*
- *     Ridiculous amounts of local state.
- */
-static lrad_event_list_t       *el = NULL;
-static lrad_packet_list_t      *pl = NULL;
-static int                     request_num_counter = 0;
-static struct timeval          now;
-static time_t                  start_time;
-static int                     have_children;
-
-#ifdef HAVE_PTHREAD_H
-static pthread_mutex_t proxy_mutex;
-
-#define PTHREAD_MUTEX_LOCK if (have_children) pthread_mutex_lock
-#define PTHREAD_MUTEX_UNLOCK if (have_children) pthread_mutex_unlock
-#else
-/*
- *     This is easier than ifdef's throughout the code.
- */
-#define PTHREAD_MUTEX_LOCK(_x)
-#define PTHREAD_MUTEX_UNLOCK(_x)
-#endif
-
-#define INSERT_EVENT(_function, _ctx) if (!lrad_event_insert(el, _function, _ctx, &((_ctx)->when), &((_ctx)->ev))) { _rad_panic(__FILE__, __LINE__, "Failed to insert event"); }
-
-static lrad_packet_list_t *proxy_list = NULL;
-
-/*
- *     We keep the proxy FD's here.  The RADIUS Id's are marked
- *     "allocated" per Id, via a bit per proxy FD.
- */
-static int             proxy_fds[32];
-static rad_listen_t    *proxy_listeners[32];
-
-static void request_post_handler(REQUEST *request);
-static void wait_a_bit(void *ctx);
-
-static void NEVER_RETURNS _rad_panic(const char *file, unsigned int line,
-                                   const char *msg)
-{
-       radlog(L_ERR, "]%s:%d] %s", file, line, msg);
-       _exit(1);
-}
-
-#define rad_panic(x) _rad_panic(__FILE__, __LINE__, x)
-
-
-static void tv_add(struct timeval *tv, int usec_delay)
-{
-       if (usec_delay > USEC) {
-               tv->tv_sec += usec_delay / USEC;
-               usec_delay %= USEC;
-       }
-       tv->tv_usec += usec_delay;
-
-       if (tv->tv_usec > USEC) {
-               tv->tv_usec -= USEC;
-               tv->tv_sec++;
-       }
-}
-
-#ifdef WITH_SNMP
-static void snmp_inc_counters(REQUEST *request)
-{
-       if (!mainconfig.do_snmp) return;
-
-       if (request->master_state == REQUEST_COUNTED) return;
-
-       if ((request->listener->type != RAD_LISTEN_AUTH) &&
-           (request->listener->type != RAD_LISTEN_ACCT)) return;
-
-       /*
-        *      Update the SNMP statistics.
-        *
-        *      Note that we do NOT do this in a child thread.
-        *      Instead, we update the stats when a request is
-        *      deleted, because only the main server thread calls
-        *      this function, which makes it thread-safe.
-        */
-       switch (request->reply->code) {
-       case PW_AUTHENTICATION_ACK:
-               rad_snmp.auth.total_responses++;
-               rad_snmp.auth.total_access_accepts++;
-               if (request->client) request->client->auth->accepts++;
-               break;
-
-       case PW_AUTHENTICATION_REJECT:
-               rad_snmp.auth.total_responses++;
-               rad_snmp.auth.total_access_rejects++;
-               if (request->client) request->client->auth->rejects++;
-               break;
-
-       case PW_ACCESS_CHALLENGE:
-               rad_snmp.auth.total_responses++;
-               rad_snmp.auth.total_access_challenges++;
-               if (request->client) request->client->auth->challenges++;
-               break;
-
-       case PW_ACCOUNTING_RESPONSE:
-               rad_snmp.acct.total_responses++;
-               if (request->client) request->client->auth->responses++;
-               break;
-
-               /*
-                *      No response, it must have been a bad
-                *      authenticator.
-                */
-       case 0:
-               if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
-                       rad_snmp.auth.total_bad_authenticators++;
-                       if (request->client) request->client->auth->bad_authenticators++;
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       request->master_state = REQUEST_COUNTED;
-}
-#else
-#define snmp_inc_counters(_x)
-#endif
-
-
-static void remove_from_request_hash(REQUEST *request)
-{
-       if (!request->in_request_hash) return;
-
-       lrad_packet_list_yank(pl, request->packet);
-       request->in_request_hash = FALSE;
-
-       snmp_inc_counters(request);
-}
-
-
-static REQUEST *lookup_in_proxy_hash(RADIUS_PACKET *reply)
-{
-       RADIUS_PACKET **proxy_p;
-       REQUEST *request;
-
-       PTHREAD_MUTEX_LOCK(&proxy_mutex);
-       proxy_p = lrad_packet_list_find_byreply(proxy_list, reply);
-
-       if (!proxy_p) {
-               PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-               return NULL;
-       }
-
-       request = lrad_packet2myptr(REQUEST, proxy, proxy_p);
-
-       if (!request) {
-               PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-               return NULL;
-       }
-
-       request->num_proxied_responses++;
-
-       /*
-        *      Catch the most common case of everything working
-        *      correctly.
-        */
-       if (request->num_proxied_requests == request->num_proxied_responses) {
-               lrad_packet_list_yank(proxy_list, request->proxy);
-               lrad_packet_list_id_free(proxy_list, request->proxy);
-               request->in_proxy_hash = FALSE;
-       }
-
-       /*
-        *      On the FIRST reply, decrement the count of outstanding
-        *      requests.  Note that this is NOT the count of sent
-        *      packets, but whether or not the home server has
-        *      responded at all.
-        */
-       if (!request->proxy_reply &&
-           request->home_server->currently_outstanding) {
-               request->home_server->currently_outstanding--;
-       }
-
-       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-
-       return request;
-}
-
-
-static void remove_from_proxy_hash(REQUEST *request)
-{
-       if (!request->in_proxy_hash) return;
-
-       PTHREAD_MUTEX_LOCK(&proxy_mutex);
-       lrad_packet_list_yank(proxy_list, request->proxy);
-       lrad_packet_list_id_free(proxy_list, request->proxy);
-
-       /*
-        *      The home server hasn't replied, but we've given up on
-        *      this request.  Don't count this request against the
-        *      home server.
-        */
-       if (!request->proxy_reply &&
-           request->home_server->currently_outstanding) {
-               request->home_server->currently_outstanding--;
-       }
-
-       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-
-       request->in_proxy_hash = FALSE;
-}
-
-
-static int insert_into_proxy_hash(REQUEST *request)
-{
-       int i, proxy;
-       char buf[128];
-
-       rad_assert(request->proxy != NULL);
-       rad_assert(proxy_list != NULL);
-
-       request->proxy->sockfd = -1;
-
-       PTHREAD_MUTEX_LOCK(&proxy_mutex);
-
-       request->home_server->currently_outstanding++;
-
-       if (!lrad_packet_list_id_alloc(proxy_list, request->proxy)) {
-               int found;
-               rad_listen_t *proxy_listener;
-
-               /*
-                *      Allocate a new proxy fd.  This function adds it
-                *      into the list of listeners.
-                */
-               proxy_listener = proxy_new_listener();
-               if (!proxy_listener) {
-                       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-                       DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
-                       return 0;
-               }
-
-               /*
-                *      Cache it locally.
-                */
-               found = -1;
-               proxy = proxy_listener->fd;
-               for (i = 0; i < 32; i++) {
-                       DEBUG2("PROXY %d %d", i, proxy_fds[(proxy + i) & 0x1f]);
-
-                       /*
-                        *      Found a free entry.  Save the socket,
-                        *      and remember where we saved it.
-                        */
-                       if (proxy_fds[(proxy + i) & 0x1f] == -1) {
-                               found = (proxy + i) & 0x1f;
-                               proxy_fds[found] = proxy;
-                               proxy_listeners[found] = proxy_listener;
-                               break;
-                       }
-               }
-               rad_assert(found >= 0);
-
-               if (!lrad_packet_list_socket_add(proxy_list, proxy_listener->fd)) {
-                       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-                       DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
-                       return 0; /* leak proxy_listener */
-
-               }
-
-               if (!lrad_packet_list_id_alloc(proxy_list, request->proxy)) {
-                       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-                       DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
-                       return 0;
-               }
-       }
-       rad_assert(request->proxy->sockfd >= 0);
-
-       /*
-        *      FIXME: Hack until we get rid of rad_listen_t, and put
-        *      the information into the packet_list.
-        */
-       proxy = -1;
-       for (i = 0; i < 32; i++) {
-               if (proxy_fds[i] == request->proxy->sockfd) {
-                       proxy = i;
-                       break;
-               }
-       }
-
-       if (proxy < 0) {
-               PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-               DEBUG2("ERROR: All sockets are full.");
-               return 0;
-       }
-
-       rad_assert(proxy_fds[proxy] != -1);
-       rad_assert(proxy_listeners[proxy] != NULL);
-       request->proxy_listener = proxy_listeners[proxy];
-
-       if (!lrad_packet_list_insert(proxy_list, &request->proxy)) {
-               lrad_packet_list_id_free(proxy_list, request->proxy);
-               PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-               DEBUG2("ERROR: Failed to insert entry into proxy list");
-               return 0;
-       }
-
-       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-
-       DEBUG3(" proxy: allocating destination %s port %d - Id %d",
-              inet_ntop(request->proxy->dst_ipaddr.af,
-                        &request->proxy->dst_ipaddr.ipaddr, buf, sizeof(buf)),
-              request->proxy->dst_port,
-              request->proxy->id);
-
-       request->in_proxy_hash = TRUE;
-
-       return 1;
-}
-
-
-/*
- *     Called as BOTH an event, and in-line from other functions.
- */
-static void wait_for_proxy_id_to_expire(void *ctx)
-{
-       REQUEST *request = ctx;
-       home_server *home = request->home_server;
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-       rad_assert(request->proxy != NULL);
-
-       request->when = request->proxy_when;
-       request->when.tv_sec += home->response_window;
-
-       if ((request->num_proxied_requests == request->num_proxied_responses) ||
-           timercmp(&now, &request->when, >)) {
-               if (request->packet) {
-                       DEBUG2("Cleaning up request %d ID %d with timestamp +%d",
-                              request->number, request->packet->id,
-                              (unsigned int) (request->timestamp - start_time));
-               } else {
-                       DEBUG2("Cleaning up request %d with timestamp +%d",
-                              request->number,
-                              (unsigned int) (request->timestamp - start_time));
-               }
-               lrad_event_delete(el, &request->ev);
-               remove_from_proxy_hash(request);
-               remove_from_request_hash(request);
-               request_free(&request);
-               return;
-       }
-
-       INSERT_EVENT(wait_for_proxy_id_to_expire, request);
-}
-
-
-static void wait_for_child_to_die(void *ctx)
-{
-       REQUEST *request = ctx;
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-
-       if ((request->child_state == REQUEST_QUEUED) |
-           (request->child_state == REQUEST_RUNNING)) {
-               request->delay += (request->delay >> 1);
-               tv_add(&request->when, request->delay);
-
-               DEBUG2("Child is still stuck for request %d", request->number);
-
-               INSERT_EVENT(wait_for_child_to_die, request);
-               return;
-       }
-
-       DEBUG2("Child is finally responsive for request %d", request->number);
-       remove_from_request_hash(request);
-
-       if (request->proxy) {
-               wait_for_proxy_id_to_expire(request);
-               return;
-       }
-
-       request_free(&request);
-}
-
-
-static void cleanup_delay(void *ctx)
-{
-       REQUEST *request = ctx;
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-       rad_assert((request->child_state == REQUEST_CLEANUP_DELAY) ||
-                  (request->child_state == REQUEST_DONE));
-
-       remove_from_request_hash(request);
-
-       if (request->proxy && request->in_proxy_hash) {
-               wait_for_proxy_id_to_expire(request);
-               return;
-       }
-
-       DEBUG2("Cleaning up request %d ID %d with timestamp +%d",
-              request->number, request->packet->id,
-              (unsigned int) (request->timestamp - start_time));
-
-       lrad_event_delete(el, &request->ev);
-       request_free(&request);
-}
-
-
-static void reject_delay(void *ctx)
-{
-       REQUEST *request = ctx;
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-       rad_assert(request->child_state == REQUEST_REJECT_DELAY);
-
-       DEBUG2("Sending delayed reject for request %d", request->number);
-
-       request->listener->send(request->listener, request);
-
-       request->when.tv_sec += mainconfig.cleanup_delay;
-       request->child_state = REQUEST_CLEANUP_DELAY;
-
-       INSERT_EVENT(cleanup_delay, request);
-}
-
-
-static void revive_home_server(void *ctx)
-{
-       home_server *home = ctx;
-
-       home->state = HOME_STATE_ALIVE;
-       DEBUG2("Marking home server alive again... we have no idea if it really is alive or not.");
-       home->currently_outstanding = 0;
-}
-
-
-static void no_response_to_ping(void *ctx)
-{
-       REQUEST *request = ctx;
-       home_server *home = request->home_server;
-       char buffer[128];
-
-       home->num_received_pings = 0;
-
-       DEBUG2("No response to status check %d from home server %s port %d",
-              request->number,
-              inet_ntop(request->proxy->dst_ipaddr.af,
-                        &request->proxy->dst_ipaddr.ipaddr,
-                        buffer, sizeof(buffer)),
-              request->proxy->dst_port);
-
-       wait_for_proxy_id_to_expire(request);
-}
-
-
-static void received_response_to_ping(REQUEST *request)
-{
-       home_server *home = request->home_server;
-       char buffer[128];
-
-       home->num_received_pings++;
-
-       DEBUG2("Received response to status check %d (%d in current sequence)",
-              request->number, home->num_received_pings);
-
-       if (home->num_received_pings < home->num_pings_to_alive) {
-               wait_for_proxy_id_to_expire(request);
-               return;
-       }
-
-       DEBUG2("Marking home server %s port %d alive",
-              inet_ntop(request->proxy->dst_ipaddr.af,
-                        &request->proxy->dst_ipaddr.ipaddr,
-                        buffer, sizeof(buffer)),
-              request->proxy->dst_port);
-
-       if (!lrad_event_delete(el, &home->ev)) {
-               DEBUG2("Hmm... no event for home server, WTF?");
-       }
-
-       if (!lrad_event_delete(el, &request->ev)) {
-               DEBUG2("Hmm... no event for request, WTF?");
-       }
-
-       wait_for_proxy_id_to_expire(request);
-
-       home->state = HOME_STATE_ALIVE;
-       home->currently_outstanding = 0;
-}
-
-
-static void ping_home_server(void *ctx)
-{
-       uint32_t jitter;
-       home_server *home = ctx;
-       REQUEST *request;
-       VALUE_PAIR *vp;
-
-       if (home->state == HOME_STATE_ALIVE) {
-               radlog(L_INFO, "Suspicious proxy state... continuing");
-               return;
-       }
-
-       request = request_alloc();
-       request->number = request_num_counter++;
-
-       request->proxy = rad_alloc(1);
-       rad_assert(request->proxy != NULL);
-
-       gettimeofday(&request->when, NULL);
-       home->when = request->when;
-
-       if (home->ping_check == HOME_PING_CHECK_STATUS_SERVER) {
-               request->proxy->code = PW_STATUS_SERVER;
-
-               vp = pairmake("Message-Authenticator", "0x00", T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-       } else if (home->type == HOME_TYPE_AUTH) {
-               request->proxy->code = PW_AUTHENTICATION_REQUEST;
-
-               vp = pairmake("User-Name", home->ping_user_name, T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-               vp = pairmake("User-Password", home->ping_user_password, T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-               vp = pairmake("Service-Type", "Authenticate-Only", T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-               vp = pairmake("Message-Authenticator", "0x00", T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-       } else {
-               request->proxy->code = PW_ACCOUNTING_REQUEST;
-
-               vp = pairmake("User-Name", home->ping_user_name, T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-               vp = pairmake("Acct-Status-Type", "Stop", T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-               vp = pairmake("Acct-Session-Id", "00000000", T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               pairadd(&request->proxy->vps, vp);
-
-               vp = pairmake("Event-Timestamp", "0", T_OP_SET);
-               if (!vp) rad_panic("Out of memory");
-               vp->vp_date = now.tv_sec;
-               pairadd(&request->proxy->vps, vp);
-       }
-
-       vp = pairmake("NAS-Identifier", "Status Check. Are you alive?", T_OP_SET);
-       if (!vp) rad_panic("Out of memory");
-       pairadd(&request->proxy->vps, vp);
-
-       request->proxy->dst_ipaddr = home->ipaddr;
-       request->proxy->dst_port = home->port;
-       request->home_server = home;
-
-       rad_assert(request->proxy_listener == NULL);
-
-       if (!insert_into_proxy_hash(request)) {
-               DEBUG2("Failed inserting status check %d into proxy hash.  Discarding it.",
-                      request->number);
-               request_free(&request);
-               return;
-       }
-       rad_assert(request->proxy_listener != NULL);
-       request->proxy_listener->send(request->proxy_listener,
-                                     request);
-
-       request->child_state = REQUEST_PROXIED;
-       request->when.tv_sec += home->ping_timeout;;
-
-       INSERT_EVENT(no_response_to_ping, request);
-
-       /*
-        *      Add +/- 2s of jitter, as suggested in RFC 3539
-        *      and in the Issues and Fixes draft.
-        */
-       home->when.tv_sec += home->ping_interval - 2;
-
-       jitter = lrad_rand();
-       jitter ^= (jitter >> 10);
-       jitter &= ((1 << 23) - 1); /* 22 bits of 1 */
-
-       tv_add(&home->when, jitter);
-
-
-       INSERT_EVENT(ping_home_server, home);
-}
-
-
-static void check_for_zombie_home_server(REQUEST *request)
-{
-       home_server *home;
-       struct timeval when;
-       char buffer[128];
-
-       home = request->home_server;
-
-       if (home->state != HOME_STATE_ZOMBIE) return;
-
-       when = home->zombie_period_start;
-       when.tv_sec += home->zombie_period;
-
-       if (timercmp(&now, &when, <)) {
-               return;
-       }
-
-       /*
-        *      It's been a zombie for too long, mark it as
-        *      dead.
-        */
-       DEBUG2("FAILURE: Marking home server %s port %d as dead.",
-              inet_ntop(request->proxy->dst_ipaddr.af,
-                        &request->proxy->dst_ipaddr.ipaddr,
-                        buffer, sizeof(buffer)),
-              request->proxy->dst_port);
-       home->state = HOME_STATE_IS_DEAD;
-       home->num_received_pings = 0;
-       home->when = request->when;
-
-       if (home->ping_check != HOME_PING_CHECK_NONE) {
-               rad_assert((home->ping_check == HOME_PING_CHECK_STATUS_SERVER) ||
-                          (home->ping_user_name != NULL));
-               home->when.tv_sec += home->ping_interval;
-
-               INSERT_EVENT(ping_home_server, home);
-       } else {
-               home->when.tv_sec += home->revive_interval;
-
-               INSERT_EVENT(revive_home_server, home);
-       }
-}
-
-
-static int setup_post_proxy_fail(REQUEST *request)
-{
-       DICT_VALUE *dval = NULL;
-       VALUE_PAIR *vp;
-
-       if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
-               dval = dict_valbyname(PW_POST_PROXY_TYPE, "Fail-Authentication");
-
-       } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
-               dval = dict_valbyname(PW_POST_PROXY_TYPE, "Fail-Accounting");
-
-       } else {
-               return 0;
-       }
-
-       if (!dval) dval = dict_valbyname(PW_POST_PROXY_TYPE, "Fail");
-
-       if (!dval) {
-               pairdelete(&request->config_items, PW_POST_PROXY_TYPE);
-               return 0;
-       }
-
-       vp = pairfind(request->config_items, PW_POST_PROXY_TYPE);
-       if (!vp) vp = radius_paircreate(request, &request->config_items,
-                                       PW_POST_PROXY_TYPE, PW_TYPE_INTEGER);
-       vp->vp_integer = dval->value;
-
-       rad_assert(request->proxy_reply == NULL);
-
-       return 1;
-}
-
-
-static int null_handler(REQUEST *request)
-{
-       return 0;
-}
-
-static void post_proxy_fail_handler(REQUEST *request)
-{
-       /*
-        *      Not set up to run Post-Proxy-Type = Fail.
-        *
-        *      Mark the request as still running, and figure out what
-        *      to do next.
-        */
-       if (!setup_post_proxy_fail(request)) {
-               request->child_state = REQUEST_RUNNING;
-               request_post_handler(request);
-               wait_a_bit(request);
-
-       } else {
-               /*
-                *      Re-queue the request.
-                */
-               request->child_state = REQUEST_QUEUED;
-
-               wait_a_bit(request);
-
-               /*
-                *      There is a post-proxy-type of fail.  We run
-                *      the request through the pre/post proxy
-                *      handlers, just like it was a real proxied
-                *      request.  However, we set the per-request
-                *      handler to NULL, as we don't want to do
-                *      anything else.
-                */
-               request->priority = 0;
-               rad_assert(request->proxy != NULL);
-               thread_pool_addrequest(request, null_handler);
-       }
-}
-
-
-/* maybe check this against wait_for_proxy_id_to_expire? */
-static void no_response_to_proxied_request(void *ctx)
-{
-       REQUEST *request = ctx;
-       home_server *home;
-       char buffer[128];
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-       rad_assert(request->child_state == REQUEST_PROXIED);
-
-       radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s port %d",
-              request->number,
-              inet_ntop(request->proxy->dst_ipaddr.af,
-                        &request->proxy->dst_ipaddr.ipaddr,
-                        buffer, sizeof(buffer)),
-              request->proxy->dst_port);
-
-       check_for_zombie_home_server(request);
-
-       home = request->home_server;
-
-       post_proxy_fail_handler(request);
-
-       /*
-        *      Don't touch request due to race conditions
-        */
-       if (home->state == HOME_STATE_IS_DEAD) {
-               rad_assert(home->ev != NULL); /* or it will never wake up */
-               return;
-       }
-
-       /*
-        *      Enable the zombie period when we notice that the home
-        *      server hasn't responded.  We also back-date the start
-        *      of the zombie period to when the proxied request was
-        *      sent.
-        */
-       if (home->state == HOME_STATE_ALIVE) {
-               DEBUG2("WARNING: Marking home server %s port %d as zombie (it looks like it is dead).",
-                      inet_ntop(home->ipaddr.af, &home->ipaddr.ipaddr,
-                                buffer, sizeof(buffer)),
-                      home->port);
-               home->state = HOME_STATE_ZOMBIE;
-               home->zombie_period_start = now;
-               home->zombie_period_start.tv_sec -= home->response_window;
-               return;
-       }
-}
-
-
-static void wait_a_bit(void *ctx)
-{
-       struct timeval when;
-       REQUEST *request = ctx;
-       lrad_event_callback_t callback = NULL;
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-
-       switch (request->child_state) {
-       case REQUEST_QUEUED:
-       case REQUEST_RUNNING:
-               when = request->received;
-               when.tv_sec += mainconfig.max_request_time;
-
-               if (timercmp(&now, &when, <)) {
-                       callback = wait_a_bit;
-               } else {
-                       /* FIXME: kill unresponsive children? */
-                       radlog(L_ERR, "WARNING: Unresponsive child (id %lu) for request %d, in module %s component %s",
-                              (unsigned long)request->child_pid, request->number,
-                              request->module ? request->module : "<server core>",
-                              request->component ? request->component : "<server core>");
-
-                       request->master_state = REQUEST_STOP_PROCESSING;
-
-                       request->delay = 500000;
-                       tv_add(&request->when, request->delay);
-                       callback = wait_for_child_to_die;
-               }
-               request->delay += request->delay >> 1;
-               break;
-
-       case REQUEST_REJECT_DELAY:
-       case REQUEST_CLEANUP_DELAY:
-               request->child_pid = NO_SUCH_CHILD_PID;
-               snmp_inc_counters(request);
-
-       case REQUEST_PROXIED:
-               rad_assert(request->next_callback != NULL);
-
-               request->when = request->next_when;
-               callback = request->next_callback;
-               request->next_callback = NULL;
-               break;
-
-               /*
-                *      Mark the request as no longer running,
-                *      and clean it up.
-                */
-       case REQUEST_DONE:
-               request->child_pid = NO_SUCH_CHILD_PID;
-               snmp_inc_counters(request);
-               cleanup_delay(request);
-               return;
-
-       default:
-               rad_panic("Internal sanity check failure");
-               return;
-       }
-
-       INSERT_EVENT(callback, request);
-}
-
-
-static int request_pre_handler(REQUEST *request)
-{
-       int rcode;
-
-       rad_assert(request->magic == REQUEST_MAGIC);
-       rad_assert(request->packet != NULL);
-       rad_assert(request->packet->dst_port != 0);
-
-       request->child_state = REQUEST_RUNNING;
-
-       /*
-        *      Don't decode the packet if it's an internal "fake"
-        *      request.  Instead, just return so that the caller can
-        *      process it.
-        */
-       if (request->packet->dst_port == 0) {
-               request->username = pairfind(request->packet->vps,
-                                            PW_USER_NAME);
-               request->password = pairfind(request->packet->vps,
-                                            PW_USER_PASSWORD);
-               return 1;
-       }
-
-       /*
-        *      Put the decoded packet into it's proper place.
-        */
-       if (request->proxy_reply != NULL) {
-               rcode = request->proxy_listener->decode(request->proxy_listener,
-                                                       request);
-       } else if (request->packet->vps == NULL) {
-               rcode = request->listener->decode(request->listener, request);
-
-       } else {
-               rcode = 0;
-       }
-
-       if (rcode < 0) {
-               radlog(L_ERR, "%s Dropping packet without response.", librad_errstr);
-               request->child_state = REQUEST_DONE;
-               return 0;
-       }
-
-       if (!request->proxy) {
-               request->username = pairfind(request->packet->vps,
-                                            PW_USER_NAME);
-
-       } else {
-               int post_proxy_type = 0;
-               VALUE_PAIR *vp;
-
-               /*
-                *      Delete any reply we had accumulated until now.
-                */
-               pairfree(&request->reply->vps);
-
-               /*
-                *      Run the packet through the post-proxy stage,
-                *      BEFORE playing games with the attributes.
-                */
-               vp = pairfind(request->config_items, PW_POST_PROXY_TYPE);
-               if (vp) {
-                       DEBUG2("  Found Post-Proxy-Type %s", vp->vp_strvalue);
-                       post_proxy_type = vp->vp_integer;
-               }
-               rcode = module_post_proxy(post_proxy_type, request);
-
-               /*
-                *      There may NOT be a proxy reply, as we may be
-                *      running Post-Proxy-Type = Fail.
-                */
-               if (request->proxy_reply) {
-                       /*
-                        *      Delete the Proxy-State Attributes from
-                        *      the reply.  These include Proxy-State
-                        *      attributes from us and remote server.
-                        */
-                       pairdelete(&request->proxy_reply->vps, PW_PROXY_STATE);
-
-                       /*
-                        *      Add the attributes left in the proxy
-                        *      reply to the reply list.
-                        */
-                       pairadd(&request->reply->vps, request->proxy_reply->vps);
-                       request->proxy_reply->vps = NULL;
-
-                       /*
-                        *      Free proxy request pairs.
-                        */
-                       pairfree(&request->proxy->vps);
-               }
-
-               switch (rcode) {
-                default:  /* Don't do anything */
-                       break;
-                case RLM_MODULE_FAIL:
-                       /* FIXME: debug print stuff */
-                       request->child_state = REQUEST_DONE;
-                       return 0;
-
-                case RLM_MODULE_HANDLED:
-                       /* FIXME: debug print stuff */
-                       request->child_state = REQUEST_DONE;
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-
-/*
- *     Return 1 if we did proxy it, or the proxy attempt failed
- *     completely.  Either way, the caller doesn't touch the request
- *     any more if we return 1.
- */
-static int successfully_proxied_request(REQUEST *request)
-{
-       int rcode;
-       int pre_proxy_type = 0;
-       VALUE_PAIR *realmpair;
-       VALUE_PAIR *strippedname;
-       VALUE_PAIR *vp;
-       char *realmname;
-       home_server *home;
-       struct timeval when;
-       REALM *realm = NULL;
-       home_pool_t *pool;
-       char buffer[128];
-
-       realmpair = pairfind(request->config_items, PW_PROXY_TO_REALM);
-       if (!realmpair || (realmpair->length == 0)) {
-               return 0;
-       }
-
-       realmname = (char *) realmpair->vp_strvalue;
-
-       realm = realm_find(realmname);
-       if (!realm) {
-               DEBUG2("ERROR: Cannot proxy to unknown realm %s", realmname);
-               return 0;
-       }
-
-       /*
-        *      Figure out which pool to use.
-        */
-       if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
-               pool = realm->auth_pool;
-
-       } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
-               pool = realm->acct_pool;
-
-       } else {
-               rad_panic("Internal sanity check failed");
-       }
-
-       if (!pool) {
-               DEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",
-                      realmname);
-               return 0;
-       }
-
-       home = home_server_ldb(realmname, pool, request);
-       if (!home) {
-               DEBUG2("ERROR: Failed to find live home server for realm %s",
-                      realmname);
-               return -1;
-       }
-       request->home_pool = pool;
-
-       /*
-        *      Remember that we sent the request to a Realm.
-        */
-       pairadd(&request->packet->vps,
-               pairmake("Realm", realmname, T_OP_EQ));
-
-       /*
-        *      We read the packet from a detail file, AND it came from
-        *      the server we're about to send it to.  Don't do that.
-        */
-       if ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
-           (request->listener->type == RAD_LISTEN_DETAIL) &&
-           (home->ipaddr.af == AF_INET) &&
-           (request->packet->src_ipaddr.af == AF_INET) &&
-           (home->ipaddr.ipaddr.ip4addr.s_addr == request->packet->src_ipaddr.ipaddr.ip4addr.s_addr)) {
-               DEBUG2("    rlm_realm: Packet came from realm %s, proxy cancelled", realmname);
-               return 0;
-       }
-
-       /*
-        *      Allocate the proxy packet, only if it wasn't already
-        *      allocated by a module.  This check is mainly to support
-        *      the proxying of EAP-TTLS and EAP-PEAP tunneled requests.
-        *
-        *      In those cases, the EAP module creates a "fake"
-        *      request, and recursively passes it through the
-        *      authentication stage of the server.  The module then
-        *      checks if the request was supposed to be proxied, and
-        *      if so, creates a proxy packet from the TUNNELED request,
-        *      and not from the EAP request outside of the tunnel.
-        *
-        *      The proxy then works like normal, except that the response
-        *      packet is "eaten" by the EAP module, and encapsulated into
-        *      an EAP packet.
-        */
-       if (!request->proxy) {
-               if ((request->proxy = rad_alloc(TRUE)) == NULL) {
-                       radlog(L_ERR|L_CONS, "no memory");
-                       exit(1);
-               }
-
-               /*
-                *      Copy the request, then look up name and
-                *      plain-text password in the copy.
-                *
-                *      Note that the User-Name attribute is the
-                *      *original* as sent over by the client.  The
-                *      Stripped-User-Name attribute is the one hacked
-                *      through the 'hints' file.
-                */
-               request->proxy->vps =  paircopy(request->packet->vps);
-       }
-
-       /*
-        *      Strip the name, if told to.
-        *
-        *      Doing it here catches the case of proxied tunneled
-        *      requests.
-        */
-       if (realm->striprealm == TRUE &&
-          (strippedname = pairfind(request->proxy->vps, PW_STRIPPED_USER_NAME)) != NULL) {
-               /*
-                *      If there's a Stripped-User-Name attribute in
-                *      the request, then use THAT as the User-Name
-                *      for the proxied request, instead of the
-                *      original name.
-                *
-                *      This is done by making a copy of the
-                *      Stripped-User-Name attribute, turning it into
-                *      a User-Name attribute, deleting the
-                *      Stripped-User-Name and User-Name attributes
-                *      from the vps list, and making the new
-                *      User-Name the head of the vps list.
-                */
-               vp = pairfind(request->proxy->vps, PW_USER_NAME);
-               if (!vp) {
-                       vp = paircreate(PW_USER_NAME, PW_TYPE_STRING);
-                       if (!vp) {
-                               radlog(L_ERR|L_CONS, "no memory");
-                               exit(1);
-                       }
-                       vp->next = request->proxy->vps;
-                       request->proxy->vps = vp;
-               }
-               memcpy(vp->vp_strvalue, strippedname->vp_strvalue,
-                      sizeof(vp->vp_strvalue));
-               vp->length = strippedname->length;
-
-               /*
-                *      Do NOT delete Stripped-User-Name.
-                */
-       }
-
-       /*
-        *      If there is no PW_CHAP_CHALLENGE attribute but
-        *      there is a PW_CHAP_PASSWORD we need to add it
-        *      since we can't use the request authenticator
-        *      anymore - we changed it.
-        */
-       if (pairfind(request->proxy->vps, PW_CHAP_PASSWORD) &&
-           pairfind(request->proxy->vps, PW_CHAP_CHALLENGE) == NULL) {
-               vp = paircreate(PW_CHAP_CHALLENGE, PW_TYPE_STRING);
-               if (!vp) {
-                       radlog(L_ERR|L_CONS, "no memory");
-                       exit(1);
-               }
-               vp->length = AUTH_VECTOR_LEN;
-               memcpy(vp->vp_strvalue, request->packet->vector, AUTH_VECTOR_LEN);
-               pairadd(&(request->proxy->vps), vp);
-       }
-
-       /*
-        *      The RFC's say we have to do this, but FreeRADIUS
-        *      doesn't need it.
-        */
-       vp = paircreate(PW_PROXY_STATE, PW_TYPE_STRING);
-       if (!vp) {
-               radlog(L_ERR|L_CONS, "no memory");
-               exit(1);
-       }
-       sprintf(vp->vp_strvalue, "%d", request->packet->id);
-       vp->length = strlen(vp->vp_strvalue);
-
-       pairadd(&request->proxy->vps, vp);
-
-       /*
-        *      Should be done BEFORE inserting into proxy hash, as
-        *      pre-proxy may use this information, or change it.
-        */
-       request->proxy->code = request->packet->code;
-       request->proxy->dst_ipaddr = home->ipaddr;
-       request->proxy->dst_port = home->port;
-       request->home_server = home;
-
-       /*
-        *      Call the pre-proxy routines.
-        */
-       vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE);
-       if (vp) {
-               DEBUG2("  Found Pre-Proxy-Type %s", vp->vp_strvalue);
-               pre_proxy_type = vp->vp_integer;
-       }
-       rcode = module_pre_proxy(pre_proxy_type, request);
-       switch (rcode) {
-       case RLM_MODULE_FAIL:
-       case RLM_MODULE_INVALID:
-       case RLM_MODULE_NOTFOUND:
-       case RLM_MODULE_USERLOCK:
-       default:
-               /* FIXME: debug print failed stuff */
-               return -1;
-
-       case RLM_MODULE_REJECT:
-       case RLM_MODULE_HANDLED:
-               return 0;
-
-       /*
-        *      Only proxy the packet if the pre-proxy code succeeded.
-        */
-       case RLM_MODULE_NOOP:
-       case RLM_MODULE_OK:
-       case RLM_MODULE_UPDATED:
-               break;
-       }
-
-       /*
-        *      If it's a fake request, don't send the proxy
-        *      packet.  The outer tunnel session will take
-        *      care of doing that.
-        */
-       if (request->packet->dst_port == 0) {
-               request->home_server = NULL;
-               return 1;
-       }
-
-       if (!insert_into_proxy_hash(request)) {
-               DEBUG("ERROR: Failed to proxy request %d", request->number);
-               return -1;
-       }
-
-       request->proxy_listener->encode(request->proxy_listener, request);
-
-       when = request->received;
-       when.tv_sec += mainconfig.max_request_time;
-
-       gettimeofday(&request->proxy_when, NULL);
-
-       request->next_when = request->proxy_when;
-       request->next_when.tv_sec += home->response_window;
-
-       rad_assert(home->response_window > 0);
-
-       if (timercmp(&when, &request->next_when, <)) {
-               request->next_when = when;
-       }
-       request->next_callback = no_response_to_proxied_request;
-
-       DEBUG2("Proxying request %d to realm %s, home server %s port %d",
-              request->number, realmname,
-              inet_ntop(request->proxy->dst_ipaddr.af,
-                        &request->proxy->dst_ipaddr.ipaddr,
-                        buffer, sizeof(buffer)),
-              request->proxy->dst_port);
-
-       /*
-        *      Note that we set proxied BEFORE sending the packet.
-        *
-        *      Once we send it, the request is tainted, as
-        *      another thread may have picked it up.  Don't
-        *      touch it!
-        */
-       request->num_proxied_requests = 1;
-       request->num_proxied_responses = 0;
-       request->child_pid = NO_SUCH_CHILD_PID;
-       request->child_state = REQUEST_PROXIED;
-       request->proxy_listener->send(request->proxy_listener,
-                                     request);
-       return 1;
-}
-
-
-static void request_post_handler(REQUEST *request)
-{
-       int child_state = -1;
-       int send_reply = TRUE;
-       struct timeval when;
-       VALUE_PAIR *vp;
-
-       if (request->master_state == REQUEST_STOP_PROCESSING) {
-               DEBUG2("Request %d was cancelled.", request->number);
-               request->child_pid = NO_SUCH_CHILD_PID;
-               request->child_state = REQUEST_DONE;
-               return;
-       }
-
-       if (request->child_state != REQUEST_RUNNING) {
-               rad_panic("Internal sanity check failed");
-       }
-
-       if ((request->reply->code == 0) &&
-           ((vp = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL) &&
-           (vp->vp_integer == PW_AUTHTYPE_REJECT)) {
-               request->reply->code = PW_AUTHENTICATION_REJECT;
-       }
-
-       if (mainconfig.proxy_requests &&
-           !request->proxy &&
-           (request->reply->code == 0) &&
-           (request->packet->code != PW_STATUS_SERVER)) {
-               int rcode = successfully_proxied_request(request);
-
-               if (rcode == 1) return;
-
-               /*
-                *      Failed proxying it (dead home servers, etc.)
-                *      Run it through Post-Proxy-Type = Fail, and
-                *      respond to the request.
-                *
-                *      Note that we're in a child thread here, so we
-                *      do NOT re-schedule the request.  Instead, we
-                *      do what we would have done, which is run the
-                *      pre-handler, a NULL request handler, and then
-                *      the post handler.
-                */
-               if ((rcode < 0) && setup_post_proxy_fail(request)) {
-                       request_pre_handler(request);
-               }
-
-               /*
-                *      Else we weren't supposed to proxy it.
-                */
-       }
-
-       /*
-        *      Fake requests don't get encoded or signed.  The caller
-        *      also requires the reply VP's, so we don't free them
-        *      here!
-        */
-       if (request->packet->dst_port == 0) {
-               /* FIXME: DEBUG going to the next request */
-               request->child_pid = NO_SUCH_CHILD_PID;
-               request->child_state = REQUEST_DONE;
-               return;
-       }
-
-       /*
-        *      Copy Proxy-State from the request to the reply.
-        */
-       vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
-       if (vp) pairadd(&request->reply->vps, vp);
-
-       /*
-        *      Access-Requests get delayed or cached.
-        */
-       if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
-               gettimeofday(&request->next_when, NULL);
-
-               if (request->reply->code == 0) {
-                       DEBUG2("There was no response configured: rejecting request %d",
-                              request->number);
-                       request->reply->code = PW_AUTHENTICATION_REJECT;
-               }
-
-               /*
-                *      Run rejected packets through
-                *
-                *      Post-Auth-Type = Reject
-                */
-               if (request->reply->code == PW_AUTHENTICATION_REJECT) {
-                       vp = pairmake("Post-Auth-Type", "Reject", T_OP_SET);
-                       if (vp) {
-                               pairdelete(&request->config_items, PW_POST_AUTH_TYPE);
-                               pairadd(&request->config_items, vp);
-                               rad_postauth(request);
-                       } /* else no Reject section defined */
-
-                       /*
-                        *      If configured, delay Access-Reject packets.
-                        *
-                        *      If mainconfig.reject_delay = 0, we discover
-                        *      that we have to send the packet now.
-                        */
-                       when = request->received;
-                       when.tv_sec += mainconfig.reject_delay;
-
-                       if (timercmp(&when, &request->next_when, >)) {
-                               DEBUG2("Delaying reject of request %d for %d seconds",
-                                      request->number,
-                                      mainconfig.reject_delay);
-                               request->next_when = when;
-                               request->next_callback = reject_delay;
-                               request->child_pid = NO_SUCH_CHILD_PID;
-                               request->child_state = REQUEST_REJECT_DELAY;
-                               return;
-                       }
-               }
-
-               request->next_when.tv_sec += mainconfig.cleanup_delay;
-               request->next_callback = cleanup_delay;
-               child_state = REQUEST_CLEANUP_DELAY;
-
-       } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
-               request->next_callback = NULL; /* just to be safe */
-               child_state = REQUEST_DONE;
-
-               /*
-                *      FIXME: Status-Server should probably not be
-                *      handled here...
-                */
-       } else if (request->packet->code == PW_STATUS_SERVER) {
-               request->next_callback = NULL;
-               child_state = REQUEST_DONE;
-               if (request->reply->code == 0) send_reply = FALSE;
-
-       } else {
-               rad_panic("Unknown packet type");
-       }
-
-       /*
-        *      Encode, sign, and send.  The accounting request
-        *      handler takes care of suppressing responses when
-        *      request->reply->code == 0.
-        */
-       if (send_reply) request->listener->send(request->listener, request);
-
-       /*
-        *      Clean up.  These are no longer needed.
-        */
-       pairfree(&request->config_items);
-
-       pairfree(&request->packet->vps);
-       request->username = NULL;
-       request->password = NULL;
-
-       pairfree(&request->reply->vps);
-
-       if (request->proxy) {
-               pairfree(&request->proxy->vps);
-
-               if (request->proxy_reply) {
-                       pairfree(&request->proxy_reply->vps);
-               }
-
-               /*
-                *      We're not tracking responses from the home
-                *      server, we can therefore free this memory in
-                *      the child thread.
-                */
-               if (!request->in_proxy_hash) {
-                       rad_free(&request->proxy);
-                       rad_free(&request->proxy_reply);
-                       request->home_server = NULL;
-               }
-       }
-
-       DEBUG2("Finished request %d state %d", request->number, child_state);
-
-       request->child_state = child_state;
-}
-
-
-static void received_retransmit(REQUEST *request, const RADCLIENT *client)
-{
-       char buffer[128];
-
-       RAD_SNMP_TYPE_INC(request->listener, total_dup_requests);
-       RAD_SNMP_CLIENT_INC(request->listener, client, dup_requests);
-
-       switch (request->child_state) {
-       case REQUEST_QUEUED:
-       case REQUEST_RUNNING:
-       discard:
-               radlog(L_ERR, "Discarding duplicate request from "
-                      "client %s port %d - ID: %d due to unfinished request %d",
-                      client->shortname,
-                      request->packet->src_port,request->packet->id,
-                      request->number);
-               break;
-
-       case REQUEST_PROXIED:
-               /*
-                *      We're not supposed to have duplicate
-                *      accounting packets.  The other states handle
-                *      duplicates fine (discard, or send duplicate
-                *      reply).  But we do NOT want to retransmit an
-                *      accounting request here, because that would
-                *      involve updating the Acct-Delay-Time, and
-                *      therefore changing the packet Id, etc.
-                *
-                *      Instead, we just discard the packet.  We may
-                *      eventually respond, or the client will send a
-                *      new accounting packet.
-                */
-               if (request->packet->code == PW_ACCOUNTING_REQUEST) {
-                       goto discard;
-               }
-
-               check_for_zombie_home_server(request);
-
-               /*
-                *      If we've just discovered that the home server is
-                *      dead, send the packet to another one.
-                */
-               if ((request->packet->dst_port != 0) &&
-                   (request->home_server->state == HOME_STATE_IS_DEAD)) {
-                       home_server *home;
-
-                       remove_from_proxy_hash(request);
-
-                       home = home_server_ldb(NULL, request->home_pool, request);
-                       if (!home) {
-                               DEBUG2("Failed to find live home server for request %d", request->number);
-                       no_home_servers:
-                               /*
-                                *      Do post-request processing,
-                                *      and any insertion of necessary
-                                *      events.
-                                */
-                               post_proxy_fail_handler(request);
-                               return;
-                       }
-
-                       request->proxy->code = request->packet->code;
-                       request->proxy->dst_ipaddr = home->ipaddr;
-                       request->proxy->dst_port = home->port;
-                       request->home_server = home;
-
-                       if (!insert_into_proxy_hash(request)) {
-                               DEBUG("ERROR: Failed to re-proxy request %d", request->number);
-                               goto no_home_servers;
-                       }
-
-                       /*
-                        *      Free the old packet, to force re-encoding
-                        */
-                       free(request->proxy->data);
-                       request->proxy->data = NULL;
-                       request->proxy->data_len = 0;
-
-                       DEBUG2("RETRY: Proxying request %d to different home server %s port %d",
-                              request->number,
-                              inet_ntop(request->proxy->dst_ipaddr.af,
-                                        &request->proxy->dst_ipaddr.ipaddr,
-                                        buffer, sizeof(buffer)),
-                              request->proxy->dst_port);
-
-                       /*
-                        *      Restart timers.  Note that we leave
-                        *      the old timeout in place, as that is a
-                        *      place-holder for when the request
-                        *      times out.
-                        */
-                       gettimeofday(&request->proxy_when, NULL);
-                       request->num_proxied_requests = 1;
-                       request->num_proxied_responses = 0;
-                       request->child_pid = NO_SUCH_CHILD_PID;
-                       request->child_state = REQUEST_PROXIED;
-                       request->proxy_listener->send(request->proxy_listener,
-                                                     request);
-                       return;
-               } /* else the home server is still alive */
-
-               DEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
-                      inet_ntop(request->proxy->dst_ipaddr.af,
-                                &request->proxy->dst_ipaddr.ipaddr,
-                                buffer, sizeof(buffer)),
-                      request->proxy->dst_port,
-                      request->proxy->id);
-               request->num_proxied_requests++;
-               request->proxy_listener->send(request->proxy_listener,
-                                             request);
-               break;
-
-       case REQUEST_REJECT_DELAY:
-               DEBUG2("Waiting to send Access-Reject "
-                      "to client %s port %d - ID: %d",
-                      client->shortname,
-                      request->packet->src_port, request->packet->id);
-               break;
-
-       case REQUEST_CLEANUP_DELAY:
-       case REQUEST_DONE:
-               DEBUG2("Sending duplicate reply "
-                      "to client %s port %d - ID: %d",
-                      client->shortname,
-                      request->packet->src_port, request->packet->id);
-               request->listener->send(request->listener, request);
-               break;
-       }
-}
-
-
-static void received_conflicting_request(REQUEST *request,
-                                        const RADCLIENT *client)
-{
-       radlog(L_ERR, "Received conflicting packet from "
-              "client %s port %d - ID: %d due to unfinished request %d.  Giving up on old request.",
-              client->shortname,
-              request->packet->src_port, request->packet->id,
-              request->number);
-
-       switch (request->child_state) {
-       case REQUEST_QUEUED:
-       case REQUEST_RUNNING:
-               request->master_state = REQUEST_STOP_PROCESSING;
-               request->delay += request->delay >> 1;
-
-               tv_add(&request->when, request->delay);
-
-               INSERT_EVENT(wait_for_child_to_die, request);
-               return;
-
-       default:
-               break;
-       }
-
-       remove_from_request_hash(request);
-
-       /*
-        *      The request stays in the event queue.  At some point,
-        *      the child will notice, and we can then delete it.
-        */
-}
-
-
-static int can_handle_new_request(RADIUS_PACKET *packet,
-                                 RADCLIENT *client)
-{
-       /*
-        *      Count the total number of requests, to see if
-        *      there are too many.  If so, return with an
-        *      error.
-        */
-       if (mainconfig.max_requests) {
-               int request_count = lrad_packet_list_num_elements(pl);
-
-               /*
-                *      This is a new request.  Let's see if
-                *      it makes us go over our configured
-                *      bounds.
-                */
-               if (request_count > mainconfig.max_requests) {
-                       radlog(L_ERR, "Dropping request (%d is too many): "
-                              "from client %s port %d - ID: %d", request_count,
-                              client->shortname,
-                              packet->src_port, packet->id);
-                       radlog(L_INFO, "WARNING: Please check the %s file.\n"
-                              "\tThe value for 'max_requests' is probably set too low.\n", mainconfig.radiusd_conf);
-                       return 0;
-               } /* else there were a small number of requests */
-       } /* else there was no configured limit for requests */
-
-       /*
-        *      FIXME: Add per-client checks.  If one client is sending
-        *      too many packets, start discarding them.
-        *
-        *      We increment the counters here, and decrement them
-        *      when the response is sent... somewhere in this file.
-        */
-
-       /*
-        *      FUTURE: Add checks for system load.  If the system is
-        *      busy, start dropping requests...
-        *
-        *      We can probably keep some statistics ourselves...  if
-        *      there are more requests coming in than we can handle,
-        *      start dropping some.
-        */
-
-       return 1;
-}
-
-
-int received_request(rad_listen_t *listener,
-                    RADIUS_PACKET *packet, REQUEST **prequest,
-                    RADCLIENT *client)
-{
-       RADIUS_PACKET **packet_p;
-       REQUEST *request = NULL;
-
-       packet_p = lrad_packet_list_find(pl, packet);
-       if (packet_p) {
-               request = lrad_packet2myptr(REQUEST, packet, packet_p);
-
-               if (memcmp(request->packet->vector, packet->vector,
-                          sizeof(packet->vector)) == 0) {
-                       received_retransmit(request, client);
-                       return 0;
-               }
-
-               /*
-                *      The new request is different from the old one,
-                *      but maybe the old is finished.  If so, delete
-                *      the old one.
-                */
-               switch (request->child_state) {
-               default:
-                       received_conflicting_request(request, client);
-                       request = NULL;
-                       break;
-
-               case REQUEST_REJECT_DELAY:
-               case REQUEST_CLEANUP_DELAY:
-                       request->child_state = REQUEST_DONE;
-               case REQUEST_DONE:
-                       cleanup_delay(request);
-                       request = NULL;
-                       break;
-               }
-
-
-       }
-
-       /*
-        *      We may want to quench the new request.
-        */
-       if (!can_handle_new_request(packet, client)) {
-               return 0;
-       }
-
-       /*
-        *      Create and initialize the new request.
-        */
-       request = request_alloc(); /* never fails */
-
-       if ((request->reply = rad_alloc(0)) == NULL) {
-               radlog(L_ERR, "No memory");
-               exit(1);
-       }
-
-       request->listener = listener;
-       request->client = client;
-       request->packet = packet;
-       request->packet->timestamp = request->timestamp;
-       request->number = request_num_counter++;
-       request->priority = listener->type;
-
-       /*
-        *      Remember the request in the list.
-        */
-       if (!lrad_packet_list_insert(pl, &request->packet)) {
-               radlog(L_ERR, "Failed to insert request %d in the list of live requests: discarding", request->number);
-               request_free(&request);
-               return 0;
-       }
-       request->in_request_hash = TRUE;
-
-       /*
-        *      The request passes many of our sanity checks.
-        *      From here on in, if anything goes wrong, we
-        *      send a reject message, instead of dropping the
-        *      packet.
-        */
-
-       /*
-        *      Build the reply template from the request.
-        */
-
-       request->reply->sockfd = request->packet->sockfd;
-       request->reply->dst_ipaddr = request->packet->src_ipaddr;
-       request->reply->src_ipaddr = request->packet->dst_ipaddr;
-       request->reply->dst_port = request->packet->src_port;
-       request->reply->src_port = request->packet->dst_port;
-       request->reply->id = request->packet->id;
-       request->reply->code = 0; /* UNKNOWN code */
-       memcpy(request->reply->vector, request->packet->vector,
-              sizeof(request->reply->vector));
-       request->reply->vps = NULL;
-       request->reply->data = NULL;
-       request->reply->data_len = 0;
-
-       request->master_state = REQUEST_ACTIVE;
-       request->child_state = REQUEST_QUEUED;
-       request->next_callback = NULL;
-
-       gettimeofday(&request->received, NULL);
-       request->timestamp = request->received.tv_sec;
-       request->when = request->received;
-       request->delay = USEC / 10;
-
-       tv_add(&request->when, request->delay);
-
-       INSERT_EVENT(wait_a_bit, request);
-
-       *prequest = request;
-       return 1;
-}
-
-
-REQUEST *received_proxy_response(RADIUS_PACKET *packet)
-{
-       char            buffer[128];
-       home_server     *home;
-       REQUEST         *request;
-
-       if (!home_server_find(&packet->src_ipaddr, packet->src_port)) {
-               radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
-                      inet_ntop(packet->src_ipaddr.af,
-                                &packet->src_ipaddr.ipaddr,
-                                buffer, sizeof(buffer)),
-                              packet->src_port);
-               rad_free(&packet);
-               return NULL;
-       }
-
-       /*
-        *      Also removes from the proxy hash if responses == requests
-        */
-       request = lookup_in_proxy_hash(packet);
-
-       if (!request) {
-               radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
-                      inet_ntop(packet->src_ipaddr.af,
-                                &packet->src_ipaddr.ipaddr,
-                                buffer, sizeof(buffer)),
-                      packet->src_port, packet->id);
-               rad_free(&packet);
-               return NULL;
-       }
-
-       home = request->home_server;
-
-       gettimeofday(&now, NULL);
-       home->state = HOME_STATE_ALIVE;
-
-       if (request->reply && request->reply->code != 0) {
-               DEBUG2("We already replied to this request.  Discarding response from home server.");
-               rad_free(&packet);
-               return NULL;
-       }
-
-       /*
-        *      We had previously received a reply, so we don't need
-        *      to do anything here.
-        */
-       if (request->proxy_reply) {
-               if (memcmp(request->proxy_reply->vector,
-                          packet->vector,
-                          sizeof(request->proxy_reply->vector)) == 0) {
-                       DEBUG2("Discarding duplicate reply from home server %s port %d  - ID: %d for request %d",
-                              inet_ntop(packet->src_ipaddr.af,
-                                        &packet->src_ipaddr.ipaddr,
-                                        buffer, sizeof(buffer)),
-                              packet->src_port, packet->id,
-                              request->number);
-               } else {
-                       /*
-                        *      ? The home server gave us a new proxy
-                        *      reply, which doesn't match the old
-                        *      one.  Delete it.
-                        */
-                       DEBUG2("Ignoring conflicting proxy reply");
-               }
-
-               /* assert that there's an event queued for request? */
-               rad_free(&packet);
-               return NULL;
-       }
-
-       switch (request->child_state) {
-       case REQUEST_QUEUED:
-       case REQUEST_RUNNING:
-               rad_panic("Internal sanity check failed for child state");
-               break;
-
-       case REQUEST_REJECT_DELAY:
-       case REQUEST_CLEANUP_DELAY:
-       case REQUEST_DONE:
-               radlog(L_ERR, "Reply from home server %s port %d  - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
-                      inet_ntop(packet->src_ipaddr.af,
-                                &packet->src_ipaddr.ipaddr,
-                                buffer, sizeof(buffer)),
-                      packet->src_port, packet->id,
-                      request->number);
-               /* assert that there's an event queued for request? */
-               rad_free(&packet);
-               return NULL;
-
-       case REQUEST_PROXIED:
-               break;
-       }
-
-       request->proxy_reply = packet;
-
-#if 0
-       /*
-        *      Perform RTT calculations, as per RFC 2988 (for TCP).
-        *      Note that we do so only if we sent one request, and
-        *      received one response.  If we sent two requests, we
-        *      have no idea if the response is for the first, or for
-        *      the second request/
-        */
-       if (request->num_proxied_requests == 1) {
-               int rtt;
-               home_server *home = request->home_server;
-
-               rtt = now.tv_sec - request->proxy_when.tv_sec;
-               rtt *= USEC;
-               rtt += now.tv_usec;
-               rtt -= request->proxy_when.tv_usec;
-
-               if (!home->has_rtt) {
-                       home->has_rtt = TRUE;
-
-                       home->srtt = rtt;
-                       home->rttvar = rtt / 2;
-
-               } else {
-                       home->rttvar -= home->rttvar >> 2;
-                       home->rttvar += (home->srtt - rtt);
-                       home->srtt -= home->srtt >> 3;
-                       home->srtt += rtt >> 3;
-               }
-
-               home->rto = home->srtt;
-               if (home->rttvar > (USEC / 4)) {
-                       home->rto += home->rttvar * 4;
-               } else {
-                       home->rto += USEC;
-               }
-       }
-#endif
-
-       /*
-        *      There's no incoming request, so it's a proxied packet
-        *      we originated.
-        */
-       if (!request->packet) {
-               received_response_to_ping(request);
-               return NULL;
-       }
-
-       request->child_state = REQUEST_QUEUED;
-       request->when = now;
-       request->delay = USEC / 10;
-       request->priority = RAD_LISTEN_PROXY;
-       tv_add(&request->when, request->delay);
-
-       /*
-        *      Wait a bit will take care of max_request_time
-        */
-       INSERT_EVENT(wait_a_bit, request);
-
-       return request;
-}
-
-
-/*
- *     Externally-visibly functions.
- */
-int radius_event_init(int spawn_flag)
-{
-       if (el) return 0;
-
-       time(&start_time);
-
-       el = lrad_event_list_create();
-       if (!el) return 0;
-
-       pl = lrad_packet_list_create(0);
-       if (!el) return 0;
-
-       request_num_counter = 0;
-
-       /*
-        *      Move all of the thread calls to this file?
-        *
-        *      It may be best for the mutexes to be in this file...
-        */
-       have_children = spawn_flag;
-
-       if (mainconfig.proxy_requests) {
-               int i;
-               rad_listen_t *listener;
-
-               /*
-                *      Create the tree for managing proxied requests and
-                *      responses.
-                */
-               proxy_list = lrad_packet_list_create(1);
-               if (!proxy_list) return 0;
-
-#ifdef HAVE_PTHREAD_H
-               if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
-                       radlog(L_ERR, "FATAL: Failed to initialize proxy mutex: %s",
-                              strerror(errno));
-                       exit(1);
-               }
-#endif
-
-               /*
-                *      Mark the Fd's as unused.
-                */
-               for (i = 0; i < 32; i++) proxy_fds[i] = -1;
-
-               i = -1;
-
-               for (listener = mainconfig.listen;
-                    listener != NULL;
-                    listener = listener->next) {
-                       if (listener->type == RAD_LISTEN_PROXY) {
-                               /*
-                                *      FIXME: This works only because we
-                                *      start off with one proxy socket.
-                                */
-                               rad_assert(proxy_fds[listener->fd & 0x1f] == -1);
-                               rad_assert(proxy_listeners[listener->fd & 0x1f] == NULL);
-
-                               proxy_fds[listener->fd & 0x1f] = listener->fd;
-                               proxy_listeners[listener->fd & 0x1f] = listener;
-                               if (!lrad_packet_list_socket_add(proxy_list, listener->fd)) {
-                                       rad_assert(0 == 1);
-                               }
-                               i = listener->fd;
-                       }
-               }
-
-               if (mainconfig.proxy_requests) rad_assert(i >= 0);
-       }
-
-       thread_pool_init(spawn_flag);
-
-       return 1;
-}
-
-
-static int request_hash_cb(void *ctx, void *data)
-{
-       ctx = ctx;              /* -Wunused */
-       REQUEST *request = lrad_packet2myptr(REQUEST, packet, data);
-
-       rad_assert(request->in_proxy_hash == FALSE);
-
-       lrad_event_delete(el, &request->ev);
-       remove_from_request_hash(request);
-       request_free(&request);
-
-       return 0;
-}
-
-
-static int proxy_hash_cb(void *ctx, void *data)
-{
-       ctx = ctx;              /* -Wunused */
-       REQUEST *request = lrad_packet2myptr(REQUEST, proxy, data);
-
-       lrad_packet_list_yank(proxy_list, request->proxy);
-       request->in_proxy_hash = FALSE;
-
-       if (!request->in_request_hash) {
-               lrad_event_delete(el, &request->ev);
-               request_free(&request);
-       }
-
-       return 0;
-}
-
-
-void radius_event_free(void)
-{
-       /*
-        *      FIXME: Stop all threads, or at least check that
-        *      they're all waiting on the semaphore, and the queues
-        *      are empty.
-        */
-
-       /*
-        *      There are requests in the proxy hash that aren't
-        *      referenced from anywhere else.  Remove them first.
-        */
-       if (proxy_list) {
-               PTHREAD_MUTEX_LOCK(&proxy_mutex);
-               lrad_packet_list_walk(proxy_list, NULL, proxy_hash_cb);
-               PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
-               lrad_packet_list_free(proxy_list);
-               proxy_list = NULL;
-       }
-
-       lrad_packet_list_walk(pl, NULL, request_hash_cb);
-
-       lrad_packet_list_free(pl);
-       pl = NULL;
-
-       lrad_event_list_free(el);
-}
-
-int radius_event_process(struct timeval **pptv)
-{
-       int rcode;
-       struct timeval when;
-
-       if (!el) return 0;
-
-       if (lrad_event_list_num_elements(el) == 0) {
-               *pptv = NULL;
-               return 1;
-       }
-
-       gettimeofday(&now, NULL);
-       when = now;
-
-       do {
-               rcode = lrad_event_run(el, &when);
-       } while (rcode == 1);
-
-       gettimeofday(&now, NULL);
-
-       if ((when.tv_sec == 0) && (when.tv_usec == 0)) {
-               if (lrad_event_list_num_elements(el) == 0) {
-                       *pptv = NULL;
-                       return 1;
-               }
-               rad_panic("Internal sanity check failed");
-
-       } else if (timercmp(&now, &when, >)) {
-               DEBUG3("Event in the past... compensating");
-               when.tv_sec = 0;
-               when.tv_usec = 1;
-
-       } else {
-               when.tv_sec -= now.tv_sec;
-               when.tv_usec -= now.tv_usec;
-               if (when.tv_usec < 0) {
-                       when.tv_sec--;
-                       when.tv_usec += USEC;
-               }
-       }
-       **pptv = when;
-
-       return 1;
-}
-
-void radius_handle_request(REQUEST *request, RAD_REQUEST_FUNP fun)
-{
-       if (!request_pre_handler(request)) {
-               DEBUG2("Going to the next request");
-               return;
-       }
-
-       rad_assert(fun != NULL);
-       rad_assert(request != NULL);
-
-       fun(request);
-
-       request_post_handler(request);
-       DEBUG2("Going to the next request");
-       return;
-}
index d3efd9c..64ab343 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000-2004,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000  Michael J. Hartwick <hartwick@hartwick.com>
  */
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
 
 #include <sys/file.h>
 
+#include <stdlib.h>
+#include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <unistd.h>
 #include <signal.h>
 
 #ifdef HAVE_SYS_WAIT_H
@@ -42,6 +43,98 @@ RCSID("$Id$")
 #      define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 #endif
 
+#include "radiusd.h"
+#include "rad_assert.h"
+
+/*
+ *     Copy a quoted string.
+ */
+static int rad_copy_string(char *to, const char *from)
+{
+       int length = 0;
+       char quote = *from;
+
+       do {
+               if (*from == '\\') {
+                       *(to++) = *(from++);
+                       length++;
+               }
+               *(to++) = *(from++);
+               length++;
+       } while (*from && (*from != quote));
+
+       if (*from != quote) return -1; /* not properly quoted */
+
+       *(to++) = quote;
+       length++;
+       *to = '\0';
+
+       return length;
+}
+
+
+/*
+ *     Copy a %{} string.
+ */
+static int rad_copy_variable(char *to, const char *from)
+{
+       int length = 0;
+       int sublen;
+
+       *(to++) = *(from++);
+       length++;
+
+       while (*from) {
+               switch (*from) {
+               case '"':
+               case '\'':
+                       sublen = rad_copy_string(to, from);
+                       if (sublen < 0) return sublen;
+                       from += sublen;
+                       to += sublen;
+                       break;
+
+               case '}':       /* end of variable expansion */
+                       *(to++) = *(from++);
+                       *to = '\0';
+                       length++;
+                       return length; /* proper end of variable */
+
+               case '\\':
+                       *(to++) = *(from++);
+                       *(to++) = *(from++);
+                       length += 2;
+                       break;
+
+               case '%':       /* start of variable expansion */
+                       if (from[1] == '{') {
+                               *(to++) = *(from++);
+                               length++;
+                               
+                               sublen = rad_copy_variable(to, from);
+                               if (sublen < 0) return sublen;
+                               from += sublen;
+                               to += sublen;
+                               length += sublen;
+                       } /* else FIXME: catch %%{ ?*/
+
+                       /* FALL-THROUGH */
+                       break;
+
+               default:
+                       *(to++) = *(from++);
+                       length++;
+                       break;
+               }
+       } /* loop over the input string */
+
+       /*
+        *      We ended the string before a trailing '}'
+        */
+
+       return -1;
+}
+
 #define MAX_ARGV (256)
 /*
  *     Execute a program on successful authentication.
@@ -53,8 +146,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                        int exec_wait,
                        char *user_msg, int msg_len,
                        VALUE_PAIR *input_pairs,
-                       VALUE_PAIR **output_pairs,
-                       int shell_escape)
+                       VALUE_PAIR **output_pairs)
 {
        VALUE_PAIR *vp;
        char mycmd[1024];
@@ -87,7 +179,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                return -1;
        }
 
-       strlcpy(mycmd, cmd, sizeof(mycmd));
+       strNcpy(mycmd, cmd, sizeof(mycmd));
 
        /*
         *      Split the string into argv's BEFORE doing radius_xlat...
@@ -176,8 +268,6 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                 */
                if (strchr(argv[i], '%') == NULL) continue;
 
-               if (!request) continue;
-
                sublen = radius_xlat(to, left - 1, argv[i], request, NULL);
                if (sublen <= 0) {
                        /*
@@ -203,7 +293,8 @@ int radius_exec_program(const char *cmd, REQUEST *request,
        argv[argc] = NULL;
 
        /*
-        *      Open a pipe for child/parent communication, if necessary.
+        *      Open a pipe for child/parent communication, if
+        *      necessary.
         */
        if (exec_wait) {
                if (pipe(pd) != 0) {
@@ -236,7 +327,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                /*
                 *      Child process.
                 *
-                *      We try to be fail-safe here. So if ANYTHING
+                *      We try to be fail-safe here.  So if ANYTHING
                 *      goes wrong, we exit with status 1.
                 */
 
@@ -314,18 +405,16 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                         *      variable...
                         */
                        snprintf(buffer, sizeof(buffer), "%s=", vp->name);
-                       if (shell_escape) {
-                               for (p = buffer; *p != '='; p++) {
-                                       if (*p == '-') {
-                                               *p = '_';
-                                       } else if (isalpha((int) *p)) {
-                                               *p = toupper(*p);
-                                       }
+                       for (p = buffer; *p != '='; p++) {
+                               if (*p == '-') {
+                                       *p = '_';
+                               } else if (isalpha((int) *p)) {
+                                       *p = toupper(*p);
                                }
                        }
 
                        n = strlen(buffer);
-                       vp_prints_value(buffer+n, sizeof(buffer) - n, vp, shell_escape);
+                       vp_prints_value(buffer+n, sizeof(buffer) - n, vp, 1);
 
                        envp[envlen++] = strdup(buffer);
 
@@ -335,7 +424,6 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                        if (envlen == (MAX_ENVP - 1)) break;
                }
                envp[envlen] = NULL;
-
                execve(argv[0], argv, envp);
                radlog(L_ERR, "Exec-Program: FAILED to execute %s: %s",
                       argv[0], strerror(errno));
@@ -352,7 +440,8 @@ int radius_exec_program(const char *cmd, REQUEST *request,
        }
 
        /*
-        *      We're not waiting, exit, and ignore any child's status.
+        *      We're not waiting, exit, and ignore any child's
+        *      status.
         */
        if (!exec_wait) {
                return 0;
@@ -422,7 +511,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
         *      Parse the output, if any.
         */
        if (done) {
-               n = T_OP_INVALID;
+               n = T_INVALID;
                if (output_pairs) {
                        /*
                         *      For backwards compatibility, first check
@@ -435,10 +524,10 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                        }
                }
 
-               if (n == T_OP_INVALID) {
-                       DEBUG("Exec-Program-Wait: plaintext: %s", answer);
+               if (n == T_INVALID) {
+                       radlog(L_DBG, "Exec-Program-Wait: plaintext: %s", answer);
                        if (user_msg) {
-                               strlcpy(user_msg, answer, msg_len);
+                               strNcpy(user_msg, answer, msg_len);
                        }
                } else {
                        /*
@@ -457,14 +546,14 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                        }
 
                        /*
-                        *      Replace any trailing comma by a NUL.
+                        *  Replace any trailing comma by a NUL.
                         */
                        if (answer[strlen(answer) - 1] == ',') {
                                answer[strlen(answer) - 1] = '\0';
                        }
 
                        radlog(L_DBG,"Exec-Program-Wait: value-pairs: %s", answer);
-                       if (userparse(answer, &vp) == T_OP_INVALID) {
+                       if (userparse(answer, &vp) == T_INVALID) {
                                radlog(L_ERR, "Exec-Program-Wait: %s: unparsable reply", cmd);
 
                        } else {
@@ -475,7 +564,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                                *output_pairs = vp;
                        }
                } /* else the answer was a set of VP's, not a text message */
-       } /* else we didn't read anything from the child */
+       } /* else we didn't read anything from the child. */
 
        /*
         *      Call rad_waitpid (should map to waitpid on non-threaded
index 2fb2429..c1512d4 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
 
 #include <sys/stat.h>
 
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
 #include <ctype.h>
 #include <fcntl.h>
 
+#include "radiusd.h"
+
+int maximum_proxies;
+
 /*
  *     Free a PAIR_LIST
  */
@@ -130,12 +140,9 @@ parse_again:
 
                        ptr = buffer;
                        token = getword(&ptr, entry, sizeof(entry));
+                       if (token == T_EOL) break;
 
-                       /*
-                        *      ?
-                        */
-                       if ((token != T_EOL) &&
-                           (token != T_BARE_WORD) &&
+                       if ((token != T_BARE_WORD) &&
                            (token != T_DOUBLE_QUOTED_STRING) &&
                            (token != T_SINGLE_QUOTED_STRING)) {
                                radlog(L_ERR, "%s[%d]: Unexpected text at start of entry",
@@ -166,7 +173,7 @@ parse_again:
                                 *      file.
                                 */
                                if (*s != '/') {
-                                       strlcpy(newfile, file,
+                                       strNcpy(newfile, file,
                                                sizeof(newfile));
                                        ptr = strrchr(newfile, '/');
                                        strcpy(ptr + 1, s);
@@ -202,7 +209,7 @@ parse_again:
                        reply_tmp = NULL;
                        old_lineno = lineno;
                        parsecode = userparse(ptr, &check_tmp);
-                       if (parsecode == T_OP_INVALID) {
+                       if (parsecode == T_INVALID) {
                                pairlist_free(&pl);
                                radlog(L_ERR|L_CONS,
                                "%s[%d]: Parse error (check) for entry %s: %s",
@@ -306,3 +313,355 @@ static void debug_pair_list(PAIR_LIST *pl)
        }
 }
 #endif
+
+#ifndef BUILDDBM /* HACK HACK */
+
+/*
+ *     Free a REALM list.
+ */
+void realm_free(REALM *cl)
+{
+       REALM *next;
+
+       while(cl) {
+               next = cl->next;
+               free(cl);
+               cl = next;
+       }
+}
+
+/*
+ *     Read the realms file.
+ */
+int read_realms_file(const char *file)
+{
+       FILE *fp;
+       char buffer[256];
+       char realm[256];
+       char hostnm[256];
+       char opts[256];
+       char *s, *p;
+       int lineno = 0;
+       REALM *c, **tail;
+       int got_realm = FALSE;
+
+       realm_free(mainconfig.realms);
+       mainconfig.realms = NULL;
+       tail = &mainconfig.realms;
+
+       if ((fp = fopen(file, "r")) == NULL) {
+               /* The realms file is not mandatory.  If it exists it will
+                  be used, however, since the new style config files are
+                  more robust and flexible they are more likely to get used.
+                  So this is a non-fatal error.  */
+               return 0;
+       }
+
+       while(fgets(buffer, 256, fp) != NULL) {
+               lineno++;
+               if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
+                       radlog(L_ERR, "%s[%d]: line too long", file, lineno);
+                       return -1;
+               }
+               if (buffer[0] == '#' || buffer[0] == '\n')
+                       continue;
+               p = buffer;
+               if (!getword(&p, realm, sizeof(realm)) ||
+                               !getword(&p, hostnm, sizeof(hostnm))) {
+                       radlog(L_ERR, "%s[%d]: syntax error", file, lineno);
+                       continue;
+               }
+
+               got_realm = TRUE;
+               c = rad_malloc(sizeof(REALM));
+               memset(c, 0, sizeof(REALM));
+
+               if ((s = strchr(hostnm, ':')) != NULL) {
+                       *s++ = 0;
+                       c->auth_port = atoi(s);
+                       c->acct_port = c->auth_port + 1;
+               } else {
+                       c->auth_port = PW_AUTH_UDP_PORT;
+                       c->acct_port = PW_ACCT_UDP_PORT;
+               }
+
+               if (strcmp(hostnm, "LOCAL") == 0) {
+                       /*
+                        *      Local realms don't have an IP address,
+                        *      secret, or port.
+                        */
+                       c->acct_ipaddr = c->ipaddr = htonl(INADDR_NONE);
+                       c->secret[0] = '\0';
+                       c->auth_port = 0;
+                       c->acct_port = 0;
+
+               } else {
+                       RADCLIENT *client;
+                       c->ipaddr = ip_getaddr(hostnm);
+                       c->acct_ipaddr = c->ipaddr;
+
+                       if (c->ipaddr == htonl(INADDR_NONE)) {
+                               radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
+                                      file, lineno, hostnm);
+                               free(c);
+                               return -1;
+                       }
+
+                       /*
+                        *      Find the remote server in the "clients" list.
+                        *      If we can't find it, there's a big problem...
+                        */
+                       client = client_find(c->ipaddr);
+                       if (client == NULL) {
+                               radlog(L_CONS|L_ERR, "%s[%d]: Cannot find 'clients' file entry of remote server %s for realm \"%s\"",
+                                      file, lineno, hostnm, realm);
+                               free(c);
+                               return -1;
+                       }
+                       memcpy(c->secret, client->secret, sizeof(c->secret));
+               }
+
+               /*
+                *      Double-check lengths to be sure they're sane
+                */
+               if (strlen(hostnm) >= sizeof(c->server)) {
+                       radlog(L_ERR, "%s[%d]: server name of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(hostnm),
+                              (int) sizeof(c->server) - 1);
+                       free(c);
+                       return -1;
+               }
+               if (strlen(realm) > sizeof(c->realm)) {
+                       radlog(L_ERR, "%s[%d]: realm of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(realm),
+                              (int) sizeof(c->realm) - 1);
+                       free(c);
+                       return -1;
+               }
+
+               /*
+                *      OK, they're sane, copy them over.
+                */
+               strcpy(c->realm, realm);
+               strcpy(c->server, hostnm);
+               c->striprealm = TRUE;
+               c->active = TRUE;
+               c->acct_active = TRUE;
+
+               while (getword(&p, opts, sizeof(opts))) {
+                       if (strcmp(opts, "nostrip") == 0)
+                               c->striprealm = FALSE;
+                       if (strstr(opts, "noacct") != NULL)
+                               c->acct_port = 0;
+                       if (strstr(opts, "trusted") != NULL)
+                               c->trusted = 1;
+                       if (strstr(opts, "notrealm") != NULL)
+                               c->notrealm = 1;
+                       if (strstr(opts, "notsuffix") != NULL)
+                               c->notrealm = 1;
+               }
+
+               c->next = NULL;
+               *tail = c;
+               tail = &c->next;
+       }
+       fclose(fp);
+
+       /*
+        *      Complain only if the realms file has content.
+        */
+       if (got_realm) {
+               radlog(L_INFO, "Using deprecated realms file.  Support for this will go away soon.");
+       }
+
+       return 0;
+}
+#endif /* BUILDDBM */
+
+/*
+ * Mark a host inactive
+ */
+void realm_disable(uint32_t ipaddr, int port)
+{
+       REALM *cl;
+       time_t now;
+
+       now = time(NULL);
+       for(cl = mainconfig.realms; cl; cl = cl->next) {
+               if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
+                       /*
+                        *      If we've received a reply (any reply)
+                        *      from the home server in the time spent
+                        *      re-sending this request, then don't mark
+                        *      the realm as dead.
+                        */
+                       if (cl->last_reply > (( now - mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count ))) {
+                               continue;
+                       }
+
+                       cl->active = FALSE;
+                       cl->wakeup = now + mainconfig.proxy_dead_time;
+                       radlog(L_PROXY, "marking authentication server %s:%d for realm %s dead",
+                               cl->server, port, cl->realm);
+               } else if ((ipaddr == cl->acct_ipaddr) && (port == cl->acct_port)) {
+                       if (cl->last_reply > (( now - mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count ))) {
+                               continue;
+                       }
+
+                       cl->acct_active = FALSE;
+                       cl->acct_wakeup = now + mainconfig.proxy_dead_time;
+                       radlog(L_PROXY, "marking accounting server %s:%d for realm %s dead",
+                               cl->acct_server, port, cl->realm);
+               }
+       }
+}
+
+/*
+ *     Find a realm in the REALM list.
+ */
+REALM *realm_find(const char *realm, int accounting)
+{
+       REALM *cl;
+       REALM *default_realm = NULL;
+       time_t now;
+       int dead_match = 0;
+
+       now = time(NULL);
+
+       /*
+        *      If we're passed a NULL realm pointer,
+        *      then look for a "NULL" realm string.
+        */
+       if (realm == NULL) {
+               realm = "NULL";
+       }
+
+       for (cl = mainconfig.realms; cl; cl = cl->next) {
+               /*
+                *      Wake up any sleeping realm.
+                */
+               if (cl->wakeup <= now) {
+                       cl->active = TRUE;
+               }
+               if (cl->acct_wakeup <= now) {
+                       cl->acct_active = TRUE;
+               }
+
+               /*
+                *      Asked for auth/acct, and the auth/acct server
+                *      is not active.  Skip it.
+                */
+               if ((!accounting && !cl->active) ||
+                   (accounting && !cl->acct_active)) {
+
+                       /*
+                        *      We've been asked to NOT fall through
+                        *      to the DEFAULT realm if there are
+                        *      exact matches for this realm which are
+                        *      dead.
+                        */
+                       if ((!mainconfig.proxy_fallback) &&
+                           (strcasecmp(cl->realm, realm) == 0)) {
+                               dead_match = 1;
+                       }
+                       continue;
+               }
+
+               /*
+                *      If it matches exactly, return it.
+                *
+                *      Note that we just want ONE live realm
+                *      here.  We don't care about round-robin, or
+                *      scatter techniques, as that's more properly
+                *      the responsibility of the proxying code.
+                */
+               if (strcasecmp(cl->realm, realm) == 0) {
+                       return cl;
+               }
+
+               /*
+                *      No default realm, try to set one.
+                */
+               if ((default_realm == NULL) &&
+                   (strcmp(cl->realm, "DEFAULT") == 0)) {
+                 default_realm = cl;
+               }
+       } /* loop over all realms */
+
+       /*
+        *      There WAS one or more matches which were marked dead,
+        *      AND there were NO live matches, AND we've been asked
+        *      to NOT fall through to the DEFAULT realm.  Therefore,
+        *      we return NULL, which means "no match found".
+        */
+       if (!mainconfig.proxy_fallback && dead_match) {
+               if (mainconfig.wake_all_if_all_dead) {
+                       REALM *rcl = NULL;
+                       for (cl = mainconfig.realms; cl; cl = cl->next) {
+                               if(strcasecmp(cl->realm,realm) == 0) {
+                                       if (!accounting && !cl->active) {
+                                               cl->active = TRUE;
+                                               rcl = cl;
+                                       }
+                                       else if (accounting &&
+                                                !cl->acct_active) {
+                                               cl->acct_active = TRUE;
+                                               rcl = cl;
+                                       }
+                               }
+                       }
+                       return rcl;
+               }
+               else {
+                       return NULL;
+               }
+       }
+
+       /*      If we didn't find the realm 'NULL' don't return the
+        *      DEFAULT entry.
+        */
+       if ((strcmp(realm, "NULL")) == 0) {
+         return NULL;
+       }
+
+       /*
+        *      Didn't find anything that matched exactly, return the
+        *      DEFAULT realm.  We also return the DEFAULT realm if
+        *      all matching realms were marked dead, and we were
+        *      asked to fall through to the DEFAULT realm in this
+        *      case.
+        */
+       return default_realm;
+}
+
+/*
+ *     Find a realm for a proxy reply by proxy's IP
+ *
+ *     Note that we don't do anything else.
+ */
+REALM *realm_findbyaddr(uint32_t ipaddr, int port)
+{
+       REALM *cl;
+
+       /*
+        *      Note that we do NOT check for inactive realms!
+        *
+        *      The purpose of this code is simply to find a matching
+        *      source IP/Port pair, for a home server which is allowed
+        *      to send us proxy replies.  If we get a reply, then it
+        *      doesn't matter if we think the realm is inactive.
+        */
+       for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
+               if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
+                       return cl;
+
+               } else if ((ipaddr == cl->acct_ipaddr) && (port == cl->acct_port)) {
+                       return cl;
+               }
+       }
+
+       return NULL;
+}
+
diff --git a/src/main/listen.c b/src/main/listen.c
deleted file mode 100644 (file)
index 377d117..0000000
+++ /dev/null
@@ -1,1927 +0,0 @@
-/*
- * listen.c    Handle socket stuff
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2005,2006  The FreeRADIUS server project
- * Copyright 2005  Alan DeKok <aland@ox.org>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/radius_snmp.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/rad_assert.h>
-
-#include <sys/resource.h>
-
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#include <fcntl.h>
-
-#define USEC (1000000)
-
-/*
- *     We'll use this below.
- */
-typedef int (*rad_listen_parse_t)(const char *, int, const CONF_SECTION *, rad_listen_t *);
-typedef void (*rad_listen_free_t)(rad_listen_t *);
-
-typedef struct rad_listen_master_t {
-       rad_listen_parse_t      parse;
-       rad_listen_free_t       free;
-       rad_listen_recv_t       recv;
-       rad_listen_send_t       send;
-       rad_listen_print_t      print;
-       rad_listen_encode_t     encode;
-       rad_listen_decode_t     decode;
-} rad_listen_master_t;
-
-typedef struct listen_socket_t {
-       /*
-        *      For normal sockets.
-        */
-       lrad_ipaddr_t   ipaddr;
-       int             port;
-       RADCLIENT_LIST  *clients;
-} listen_socket_t;
-
-typedef struct listen_detail_t {
-       const char      *filename;
-       VALUE_PAIR      *vps;
-       FILE            *fp;
-       int             state;
-       time_t          timestamp;
-       lrad_ipaddr_t   client_ip;
-       REQUEST         *request; /* can only be one at a time! */
-       int             load_factor; /* 1..100 */
-
-       int             has_rtt;
-       int             srtt;
-       int             rttvar;
-       int             delay_time;
-       struct timeval  last_packet;
-} listen_detail_t;
-
-
-/*
- *     Find a per-socket client.
- */
-static RADCLIENT *client_listener_find(const rad_listen_t *listener,
-                                      const lrad_ipaddr_t *ipaddr)
-{
-       const RADCLIENT_LIST *clients;
-
-       rad_assert(listener != NULL);
-       rad_assert(ipaddr != NULL);
-
-       rad_assert((listener->type == RAD_LISTEN_AUTH) ||
-                  (listener->type == RAD_LISTEN_ACCT));
-
-       clients = ((listen_socket_t *)listener->data)->clients;
-       if (!clients) clients = mainconfig.clients;
-
-       rad_assert(clients != NULL);
-
-       return client_find(clients, ipaddr);
-}
-
-static int listen_bind(rad_listen_t *this);
-
-/*
- *     Process and reply to a server-status request.
- *     Like rad_authenticate and rad_accounting this should
- *     live in it's own file but it's so small we don't bother.
- */
-static int rad_status_server(REQUEST *request)
-{
-       int rcode = RLM_MODULE_OK;
-       DICT_VALUE *dval;
-
-       switch (request->listener->type) {
-       case RAD_LISTEN_AUTH:
-               dval = dict_valbyname(PW_AUTZ_TYPE, "Status-Server");
-               if (dval) {
-                       rcode = module_authorize(dval->value, request);
-               } else {
-                       rcode = RLM_MODULE_OK;
-               }
-
-               switch (rcode) {
-               case RLM_MODULE_OK:
-               case RLM_MODULE_UPDATED:
-                       request->reply->code = PW_AUTHENTICATION_ACK;
-                       break;
-
-               case RLM_MODULE_FAIL:
-               case RLM_MODULE_HANDLED:
-                       request->reply->code = 0; /* don't reply */
-                       break;
-
-               default:
-               case RLM_MODULE_REJECT:
-                       request->reply->code = PW_AUTHENTICATION_REJECT;
-                       break;
-               }
-               break;
-
-       case RAD_LISTEN_ACCT:
-               dval = dict_valbyname(PW_ACCT_TYPE, "Status-Server");
-               if (dval) {
-                       rcode = module_accounting(dval->value, request);
-               } else {
-                       rcode = RLM_MODULE_OK;
-               }
-
-               switch (rcode) {
-               case RLM_MODULE_OK:
-               case RLM_MODULE_UPDATED:
-                       request->reply->code = PW_ACCOUNTING_RESPONSE;
-                       break;
-
-               default:
-                       request->reply->code = 0; /* don't reply */
-                       break;
-               }
-               break;
-
-       default:
-               return 0;
-       }
-
-       return 0;
-}
-
-
-static int socket_print(rad_listen_t *this, char *buffer, size_t bufsize)
-{
-       size_t len;
-       listen_socket_t *sock = this->data;
-
-       if ((sock->ipaddr.af == AF_INET) &&
-           (sock->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_ANY))) {
-               strcpy(buffer, "*");
-       } else {
-               ip_ntoh(&sock->ipaddr, buffer, bufsize);
-       }
-
-       len = strlen(buffer);
-
-       return len + snprintf(buffer + len, bufsize - len, " port %d",
-                             sock->port);
-}
-
-
-/*
- *     Parse an authentication or accounting socket.
- */
-static int common_socket_parse(const char *filename, int lineno,
-                            const CONF_SECTION *cs, rad_listen_t *this)
-{
-       int             rcode;
-       int             listen_port;
-       lrad_ipaddr_t   ipaddr;
-       listen_socket_t *sock = this->data;
-       const char      *section_name = NULL;
-       CONF_SECTION    *client_cs;
-
-       /*
-        *      Try IPv4 first
-        */
-       ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
-       rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
-                             &ipaddr.ipaddr.ip4addr, NULL);
-       if (rcode < 0) return -1;
-
-       if (rcode == 0) { /* successfully parsed IPv4 */
-               ipaddr.af = AF_INET;
-
-       } else {        /* maybe IPv6? */
-               rcode = cf_item_parse(cs, "ipv6addr", PW_TYPE_IPV6ADDR,
-                                     &ipaddr.ipaddr.ip6addr, NULL);
-               if (rcode < 0) return -1;
-
-               if (rcode == 1) {
-                       radlog(L_ERR, "%s[%d]: No address specified in listen section",
-                              filename, lineno);
-                       return -1;
-               }
-               ipaddr.af = AF_INET6;
-       }
-
-       rcode = cf_item_parse(cs, "port", PW_TYPE_INTEGER,
-                             &listen_port, "0");
-       if (rcode < 0) return -1;
-
-       sock->ipaddr = ipaddr;
-       sock->port = listen_port;
-
-       /*
-        *      And bind it to the port.
-        */
-       if (listen_bind(this) < 0) {
-               char buffer[128];
-               radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s port %d",
-                      filename, cf_section_lineno(cs),
-                      ip_ntoh(&sock->ipaddr, buffer, sizeof(buffer)),
-                      sock->port);
-               return -1;
-       }
-
-       /*
-        *      If we can bind to interfaces, do so,
-        *      else don't.
-        */
-       if (cf_pair_find(cs, "interface")) {
-#ifndef SO_BINDTODEVICE
-               radlog(L_CONS|L_ERR, "%s[%d]: System does not support binding to interfaces, delete this line from the configuration file.",
-                      filename, cf_section_lineno(cs));
-               return -1;
-#else
-               const char *value;
-               const CONF_PAIR *cp = cf_pair_find(cs, "interface");
-               struct ifreq ifreq;
-
-               rad_assert(cp != NULL);
-               value = cf_pair_value(cp);
-               rad_assert(value != NULL);
-
-               strcpy(ifreq.ifr_name, value);
-
-               if (setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
-                              (char *)&ifreq, sizeof(ifreq)) < 0) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: Failed binding to interface %s: %s",
-                              filename, cf_section_lineno(cs),
-                              value, strerror(errno));
-                       return -1;
-               } /* else it worked. */
-#endif
-       }
-
-       /*
-        *      Look for the name of a section that holds a list
-        *      of clients.
-        */
-       rcode = cf_item_parse(cs, "clients", PW_TYPE_STRING_PTR,
-                             &section_name, NULL);
-       if (rcode < 0) return -1; /* bad string */
-       if (rcode > 0) return 0; /* non-existent is OK. */
-
-       client_cs = cf_section_find(section_name);
-       free(section_name);
-       if (!client_cs) {
-               radlog(L_CONS|L_ERR, "%s[%d]: Failed to find client section %s",
-                      filename, cf_section_lineno(cs), section_name);
-               return -1;
-       }
-
-       sock->clients = clients_parse_section(filename, client_cs);
-       if (!sock->clients) {
-               return -1;
-       }
-
-       return 0;
-}
-
-/*
- *     Send an authentication response packet
- */
-static int auth_socket_send(rad_listen_t *listener, REQUEST *request)
-{
-       rad_assert(request->listener == listener);
-       rad_assert(listener->send == auth_socket_send);
-
-       return rad_send(request->reply, request->packet,
-                       request->client->secret);
-}
-
-
-/*
- *     Send an accounting response packet (or not)
- */
-static int acct_socket_send(rad_listen_t *listener, REQUEST *request)
-{
-       rad_assert(request->listener == listener);
-       rad_assert(listener->send == acct_socket_send);
-
-       /*
-        *      Accounting reject's are silently dropped.
-        *
-        *      We do it here to avoid polluting the rest of the
-        *      code with this knowledge
-        */
-       if (request->reply->code == 0) return 0;
-
-       return rad_send(request->reply, request->packet,
-                       request->client->secret);
-}
-
-
-/*
- *     Send a packet to a home server.
- *
- *     FIXME: have different code for proxy auth & acct!
- */
-static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
-{
-       listen_socket_t *sock = listener->data;
-
-       rad_assert(request->proxy_listener == listener);
-       rad_assert(listener->send == proxy_socket_send);
-
-       request->proxy->src_ipaddr = sock->ipaddr;
-       request->proxy->src_port = sock->port;
-
-       return rad_send(request->proxy, request->packet,
-                       request->home_server->secret);
-}
-
-
-/*
- *     Check if an incoming request is "ok"
- *
- *     It takes packets, not requests.  It sees if the packet looks
- *     OK.  If so, it does a number of sanity checks on it.
-  */
-static int auth_socket_recv(rad_listen_t *listener,
-                           RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
-{
-       ssize_t         rcode;
-       int             code, src_port;
-       RADIUS_PACKET   *packet;
-       RAD_REQUEST_FUNP fun = NULL;
-       char            buffer[128];
-       RADCLIENT       *client;
-       lrad_ipaddr_t   src_ipaddr;
-
-       rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
-       if (rcode < 0) return 0;
-
-       RAD_SNMP_TYPE_INC(listener, total_requests);
-
-       if (rcode < 20) {       /* AUTH_HDR_LEN */
-               RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
-               return 0;
-       }
-
-       if ((client = client_listener_find(listener,
-                                          &src_ipaddr)) == NULL) {
-               rad_recv_discard(listener->fd);
-               RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
-
-               /*
-                *      This is debugging rather than logging, so that
-                *      DoS attacks don't affect us.
-                */
-               DEBUG("Ignoring request from unknown client %s port %d",
-                     inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
-                               buffer, sizeof(buffer)), src_port);
-               return 0;
-       }
-
-       /*
-        *      Some sanity checks, based on the packet code.
-        */
-       switch(code) {
-       case PW_AUTHENTICATION_REQUEST:
-               RAD_SNMP_CLIENT_INC(listener, client, requests);
-               fun = rad_authenticate;
-               break;
-
-       case PW_STATUS_SERVER:
-               if (!mainconfig.status_server) {
-                       rad_recv_discard(listener->fd);
-                       RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
-                       RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
-                       DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
-                       return 0;
-               }
-               fun = rad_status_server;
-               break;
-
-       default:
-               rad_recv_discard(listener->fd);
-               RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
-               RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
-
-               DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",
-                     code, client->shortname, src_port);
-               return 0;
-               break;
-       } /* switch over packet types */
-
-       /*
-        *      Now that we've sanity checked everything, receive the
-        *      packet.
-        */
-       packet = rad_recv(listener->fd);
-       if (!packet) {
-               RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
-               radlog(L_ERR, "%s", librad_errstr);
-               return 0;
-       }
-
-       if (!received_request(listener, packet, prequest, client)) {
-               RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
-               RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
-               rad_free(&packet);
-               return 0;
-       }
-
-       *pfun = fun;
-       return 1;
-}
-
-
-/*
- *     Receive packets from an accounting socket
- */
-static int acct_socket_recv(rad_listen_t *listener,
-                           RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
-{
-       ssize_t         rcode;
-       int             code, src_port;
-       RADIUS_PACKET   *packet;
-       RAD_REQUEST_FUNP fun = NULL;
-       char            buffer[128];
-       RADCLIENT       *client;
-       lrad_ipaddr_t   src_ipaddr;
-
-       rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
-       if (rcode < 0) return 0;
-
-       RAD_SNMP_TYPE_INC(listener, total_requests);
-
-       if (rcode < 20) {       /* AUTH_HDR_LEN */
-               RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
-               return 0;
-       }
-
-       if ((client = client_listener_find(listener,
-                                          &src_ipaddr)) == NULL) {
-               rad_recv_discard(listener->fd);
-               RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
-
-               /*
-                *      This is debugging rather than logging, so that
-                *      DoS attacks don't affect us.
-                */
-               DEBUG("Ignoring request from unknown client %s port %d",
-                     inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,
-                               buffer, sizeof(buffer)), src_port);
-               return 0;
-       }
-
-       /*
-        *      Some sanity checks, based on the packet code.
-        */
-       switch(code) {
-       case PW_ACCOUNTING_REQUEST:
-               RAD_SNMP_CLIENT_INC(listener, client, requests);
-               fun = rad_accounting;
-               break;
-
-       case PW_STATUS_SERVER:
-               if (!mainconfig.status_server) {
-                       rad_recv_discard(listener->fd);
-                       RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
-                       RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
-
-                       DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
-                       return 0;
-               }
-               fun = rad_status_server;
-               break;
-
-       default:
-               rad_recv_discard(listener->fd);
-               RAD_SNMP_TYPE_INC(listener, total_unknown_types);
-               RAD_SNMP_CLIENT_INC(listener, client, unknown_types);
-
-               DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",
-                     code, client->shortname, src_port);
-               return 0;
-       } /* switch over packet types */
-
-       /*
-        *      Now that we've sanity checked everything, receive the
-        *      packet.
-        */
-       packet = rad_recv(listener->fd);
-       if (!packet) {
-               RAD_SNMP_TYPE_INC(listener, total_malformed_requests);
-               radlog(L_ERR, "%s", librad_errstr);
-               return 0;
-       }
-
-       /*
-        *      There can be no duplicate accounting packets.
-        */
-       if (!received_request(listener, packet, prequest, client)) {
-               RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
-               RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);
-               rad_free(&packet);
-               return 0;
-       }
-
-       *pfun = fun;
-       return 1;
-}
-
-
-/*
- *     Recieve packets from a proxy socket.
- */
-static int proxy_socket_recv(rad_listen_t *listener,
-                             RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
-{
-       REQUEST         *request;
-       RADIUS_PACKET   *packet;
-       RAD_REQUEST_FUNP fun = NULL;
-       char            buffer[128];
-
-       packet = rad_recv(listener->fd);
-       if (!packet) {
-               radlog(L_ERR, "%s", librad_errstr);
-               return 0;
-       }
-
-       /*
-        *      FIXME: Client MIB updates?
-        */
-       switch(packet->code) {
-       case PW_AUTHENTICATION_ACK:
-       case PW_ACCESS_CHALLENGE:
-       case PW_AUTHENTICATION_REJECT:
-               fun = rad_authenticate;
-               break;
-
-       case PW_ACCOUNTING_RESPONSE:
-               fun = rad_accounting;
-               break;
-
-       default:
-               /*
-                *      FIXME: Update MIB for packet types?
-                */
-               radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
-                      "from home server %s port %d - ID %d : IGNORED",
-                      packet->code,
-                      ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
-                      packet->src_port, packet->id);
-               rad_free(&packet);
-               return 0;
-       }
-
-       request = received_proxy_response(packet);
-       if (!request) {
-               return 0;
-       }
-
-       rad_assert(fun != NULL);
-       *pfun = fun;
-       *prequest = request;
-
-       return 1;
-}
-
-
-static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
-{
-       if (!request->reply->code) return 0;
-
-       rad_encode(request->reply, request->packet,
-                  request->client->secret);
-       rad_sign(request->reply, request->packet,
-                request->client->secret);
-
-       return 0;
-}
-
-
-static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
-{
-       if (rad_verify(request->packet, NULL,
-                      request->client->secret) < 0) {
-               return -1;
-       }
-
-       return rad_decode(request->packet, NULL,
-                         request->client->secret);
-}
-
-static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
-{
-       rad_encode(request->proxy, NULL, request->home_server->secret);
-       rad_sign(request->proxy, NULL, request->home_server->secret);
-
-       return 0;
-}
-
-
-static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
-{
-       if (rad_verify(request->proxy_reply, request->proxy,
-                      request->home_server->secret) < 0) {
-               return -1;
-       }
-
-       return rad_decode(request->proxy_reply, request->proxy,
-                          request->home_server->secret);
-}
-
-
-#define STATE_UNOPENED (0)
-#define STATE_UNLOCKED (1)
-#define STATE_HEADER   (2)
-#define STATE_READING  (3)
-#define STATE_DONE     (4)
-#define STATE_WAITING  (5)
-
-/*
- *     If we're limiting outstanding packets, then mark the response
- *     as being sent.
- */
-static int detail_send(rad_listen_t *listener, REQUEST *request)
-{
-       int rtt;
-       struct timeval now;
-       listen_detail_t *data = listener->data;
-
-       rad_assert(request->listener == listener);
-       rad_assert(listener->send == detail_send);
-
-       /*
-        *      This request timed out.  We should probably re-send it
-        *      again... forever.
-        */
-       if (request->reply->code == 0) {
-               /*
-                *      FIXME: do something sane!
-                */
-       }
-
-       /*
-        *      We call gettimeofday a lot.  But here it should be OK,
-        *      because there's nothing else to do.
-        */
-       gettimeofday(&now, NULL);
-
-       /*
-        *      If we haven't sent a packet in the last second, reset
-        *      the RTT.
-        */
-       now.tv_sec -= 1;
-       if (timercmp(&data->last_packet, &now, <)) {
-               data->has_rtt = FALSE;
-       }
-       now.tv_sec += 1;
-
-       /*
-        *      Only one detail packet may be outstanding at a time,
-        *      so it's safe to update some entries in the detail
-        *      structure.
-        *
-        *      We keep smoothed round trip time (SRTT), but not round
-        *      trip timeout (RTO).  We use SRTT to calculate a rough
-        *      load factor.
-        */
-       rtt = now.tv_sec - request->received.tv_sec;
-       rtt *= USEC;
-       rtt += now.tv_usec;
-       rtt -= request->received.tv_usec;
-
-       /*
-        *      If we're proxying, the RTT is our processing time,
-        *      plus the network delay there and back, plus the time
-        *      on the other end to process the packet.  Ideally, we
-        *      should remove the network delays from the RTT, but we
-        *      don't know what they are.
-        *
-        *      So, to be safe, we over-estimate the total cost of
-        *      processing the packet.
-        */
-       if (!data->has_rtt) {
-               data->has_rtt = TRUE;
-               data->srtt = rtt;
-               data->rttvar = rtt / 2;
-
-       } else {
-               data->rttvar -= data->rttvar >> 2;
-               data->rttvar += (data->srtt - rtt);
-               data->srtt -= data->srtt >> 3;
-               data->srtt += rtt >> 3;
-       }
-
-       /*
-        *      Calculate the time we wait before sending the next
-        *      packet.
-        *
-        *      rtt / (rtt + delay) = load_factor / 100
-        */
-       data->delay_time = (data->srtt * (100 - data->load_factor)) / (data->load_factor);
-
-       /*
-        *      FIXME: Push this delay to the event handler!
-        */
-       DEBUG2("RTT %d\tdelay %d", data->srtt, data->delay_time);
-
-       usleep(data->delay_time);
-
-       data->last_packet = now;
-
-       /*
-        *      FIXME: Cache the LAST offset in the file where we
-        *      successfully read a packet, and got a response.  Then
-        *      when we re-open the file (say after a restart), we
-        *      start reading from that offset, rather than from the
-        *      beginning of the file again.
-        *
-        *      OR, put the offset into a comment in the first line of
-        *      "detail.work" ?
-        */
-       data->request = NULL;
-
-       /*
-        *      Code in threads.c will take care performing self
-        *      signalling that we can read from the detail file.
-        *
-        *      Even though this request is now done, there may be
-        *      auth/acct requests pending that mean we shouldn't read
-        *      the detail file.
-        */
-
-       return 0;
-}
-
-
-/*
- *     Open the detail file..
- *
- *     FIXME: create it, if it's not already there, so that the main
- *     server select() will wake us up if there's anything to read.
- */
-static int detail_open(rad_listen_t *this)
-{
-       struct stat st;
-       char buffer[2048];
-       listen_detail_t *data = this->data;
-
-       rad_assert(data->state == STATE_UNOPENED);
-       snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
-
-       /*
-        *      Open detail.work first, so we don't lose
-        *      accounting packets.  It's probably better to
-        *      duplicate them than to lose them.
-        *
-        *      Note that we're not writing to the file, but
-        *      we've got to open it for writing in order to
-        *      establish the lock, to prevent rlm_detail from
-        *      writing to it.
-        */
-       this->fd = open(buffer, O_RDWR);
-       if (this->fd < 0) {
-               /*
-                *      Try reading the detail file.  If it
-                *      doesn't exist, we can't do anything.
-                *
-                *      Doing the stat will tell us if the file
-                *      exists, even if we don't have permissions
-                *      to read it.
-                */
-               if (stat(data->filename, &st) < 0) {
-                       return 0;
-               }
-
-               /*
-                *      Open it BEFORE we rename it, just to
-                *      be safe...
-                */
-               this->fd = open(data->filename, O_RDWR);
-               if (this->fd < 0) {
-                       radlog(L_ERR, "Failed to open %s: %s",
-                              data->filename, strerror(errno));
-                       return 0;
-               }
-
-               /*
-                *      Rename detail to detail.work
-                */
-               if (rename(data->filename, buffer) < 0) {
-                       close(this->fd);
-                       this->fd = -1;
-                       return 0;
-               }
-       } /* else detail.work existed, and we opened it */
-
-       rad_assert(data->vps == NULL);
-
-       rad_assert(data->fp == NULL);
-       data->fp = fdopen(this->fd, "r");
-       if (!data->fp) {
-               radlog(L_ERR, "Failed to re-open %s: %s",
-                      data->filename, strerror(errno));
-               return 0;
-       }
-
-       data->state = STATE_UNLOCKED;
-
-       data->client_ip.af = AF_UNSPEC;
-       data->timestamp = 0;
-
-       return 1;
-}
-
-/*
- *     FIXME: this should be dynamically allocated.
- */
-static const RADCLIENT detail_client = {
-       {               /* ipaddr */
-               AF_INET,
-               {{ INADDR_NONE }}
-       },
-       32,
-       "<detail-file>",
-       "secret",
-       "UNKNOWN-CLIENT",
-       "other",
-       "",
-       "",
-       -1
-#ifdef WITH_SNMP
-       , NULL, NULL
-#endif
-};
-
-/*
- *     FIXME: add a configuration "exit when done" so that the detail
- *     file reader can be used as a one-off tool to update stuff.
- */
-
-static int detail_recv(rad_listen_t *listener,
-                      RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
-{
-       int             free_slot = -1;
-       char            key[256], value[1024];
-       VALUE_PAIR      *vp, **tail;
-       RADIUS_PACKET   *packet;
-       char            buffer[2048];
-       listen_detail_t *data = listener->data;
-       REQUEST         *old_request;
-
-       if (data->state == STATE_UNOPENED) {
-               rad_assert(listener->fd < 0);
-
-               /*
-                *      FIXME: If the file doesn't exist, then return
-                *      "sleep for 1s", to avoid busy looping.
-                */
-               if (!detail_open(listener)) return 0;
-       }
-       rad_assert(listener->fd >= 0);
-
-       /*
-        *      Try to lock fd.  If we can't, return.  If we can,
-        *      continue.  This means that the server doesn't block
-        *      while waiting for the lock to open...
-        */
-       if (data->state == STATE_UNLOCKED) {
-               /*
-                *      Note that we do NOT block waiting for the
-                *      lock.  We've re-named the file above, so we've
-                *      already guaranteed that any *new* detail
-                *      writer will not be opening this file.  The
-                *      only purpose of the lock is to catch a race
-                *      condition where the execution "ping-pongs"
-                *      between radiusd & radrelay.
-                */
-               if (rad_lockfd_nonblock(listener->fd, 0) < 0) {
-                       return 0;
-               }
-               /*
-                *      Look for the header
-                */
-               data->state = STATE_HEADER;
-       }
-
-
-       /*
-        *      Catch an out of memory condition which will most likely
-        *      never be met.
-        */
-       if (data->state == STATE_DONE) goto alloc_packet;
-
-       /*
-        *      We still have an outstanding packet.  Don't read any
-        *      more.
-        */
-       old_request = data->request; /* threading issues */
-       if (old_request && old_request->reply->code == 0) {
-               /*
-                *      FIXME: return "don't do anything until the
-                *      request is done, AND we receive another signal
-                *      saying it's OK to read the detail file.
-                */
-               return 0;
-       }
-
-       /*
-        *      We read the last packet, and returned it for
-        *      processing.  We later come back here to shut
-        *      everything down, and unlink the file.
-        */
-       if (feof(data->fp)) {
-               if (data->state == STATE_READING) {
-                       data->state = STATE_DONE;
-                       goto alloc_packet;
-               }
-
-               /*
-                *      If there's a pending request, don't delete the
-                *      file.
-                */
-               if (data->request) {
-                       data->state = STATE_WAITING;
-                       return 0;
-               }
-
-       cleanup:
-               rad_assert(data->vps == NULL);
-
-               snprintf(buffer, sizeof(buffer), "%s.work", data->filename);
-               unlink(buffer);
-               fclose(data->fp); /* closes listener->fd */
-               data->fp = NULL;
-               listener->fd = -1;
-               data->state = STATE_UNOPENED;
-
-               /*
-                *      Try to open "detail" again.  If we're on a
-                *      busy RADIUS server, odds are that it will
-                *      now exist.
-                */
-               detail_open(listener);
-               return 0;
-       }
-
-       tail = &data->vps;
-
-       /*
-        *      Fill the buffer...
-        */
-       while (fgets(buffer, sizeof(buffer), data->fp)) {
-               /*
-                *      No CR, die.
-                */
-               if (!strchr(buffer, '\n')) {
-                       pairfree(&data->vps);
-                       goto cleanup;
-               }
-
-               /*
-                *      We've read a header, possibly packet contents,
-                *      and are now at the end of the packet.
-                */
-               if ((data->state == STATE_READING) &&
-                   (buffer[0] == '\n')) {
-                       data->state = STATE_DONE;
-                       break;
-               }
-
-               /*
-                *      Look for date/time header, and read VP's if
-                *      found.  If not, keep reading lines until we
-                *      find one.
-                */
-               if (data->state == STATE_HEADER) {
-                       int y;
-
-                       if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {
-                               data->state = STATE_READING;
-                       }
-                       continue;
-               }
-
-               /*
-                *      We have a full "attribute = value" line.
-                *      If it doesn't look reasonable, skip it.
-                */
-               if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {
-                       continue;
-               }
-
-               /*
-                *      Skip non-protocol attributes.
-                */
-               if (!strcasecmp(key, "Request-Authenticator")) continue;
-
-               /*
-                *      Set the original client IP address, based on
-                *      what's in the detail file.
-                *
-                *      Hmm... we don't set the server IP address.
-                *      or port.  Oh well.
-                */
-               if (!strcasecmp(key, "Client-IP-Address")) {
-                       data->client_ip.af = AF_INET;
-                       ip_hton(value, AF_INET, &data->client_ip);
-                       continue;
-               }
-
-               /*
-                *      The original time at which we received the
-                *      packet.  We need this to properly calculate
-                *      Acct-Delay-Time.
-                */
-               if (!strcasecmp(key, "Timestamp")) {
-                       data->timestamp = atoi(value);
-                       continue;
-               }
-
-               /*
-                *      Read one VP.
-                *
-                *      FIXME: do we want to check for non-protocol
-                *      attributes like radsqlrelay does?
-                */
-               vp = NULL;
-               if ((userparse(buffer, &vp) > 0) &&
-                   (vp != NULL)) {
-                       *tail = vp;
-                       tail = &(vp->next);
-               }
-       }
-
-       /*
-        *      We got to EOF,  If we're in STATE_HEADER, it's OK.
-        *      Otherwise it's a problem.  In any case, nuke the file
-        *      and start over from scratch,
-        */
-       if (feof(data->fp)) {
-               /*
-                *      Send the packet.
-                */
-               if (data->state == STATE_READING) goto alloc_packet;
-               pairfree(&data->vps);
-               goto cleanup;
-       }
-
-       /*
-        *      If we're not done, then there's a problem.  The checks
-        *      above for EOF
-        */
-       rad_assert(data->state == STATE_DONE);
-
-       /*
-        *      The packet we read was empty, re-set the state to look
-        *      for a header, and don't return anything.
-        */
-       if (!data->vps) {
-               data->state = STATE_HEADER;
-               return 0;
-       }
-
-       /*
-        *      Allocate the packet.  If we fail, it's a serious
-        *      problem.
-        */
- alloc_packet:
-       rad_assert(data->request == NULL);
-
-       packet = rad_alloc(1);
-       if (!packet) {
-               return 0;       /* maybe memory will magically free up... */
-       }
-
-       memset(packet, 0, sizeof(*packet));
-       packet->sockfd = -1;
-       packet->src_ipaddr.af = AF_INET;
-       packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
-       packet->code = PW_ACCOUNTING_REQUEST;
-       packet->timestamp = time(NULL);
-
-       /*
-        *      Remember where it came from, so that we don't
-        *      proxy it to the place it came from...
-        */
-       if (data->client_ip.af != AF_UNSPEC) {
-               packet->src_ipaddr = data->client_ip;
-       }
-
-       vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);
-       if (vp) {
-               packet->src_ipaddr.af = AF_INET;
-               packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
-       } else {
-               vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);
-               if (vp) {
-                       packet->src_ipaddr.af = AF_INET6;
-                       memcpy(&packet->src_ipaddr.ipaddr.ip6addr,
-                              &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
-               }
-       }
-
-       vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);
-       if (vp) {
-               packet->dst_ipaddr.af = AF_INET;
-               packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
-       } else {
-               vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);
-               if (vp) {
-                       packet->dst_ipaddr.af = AF_INET6;
-                       memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,
-                              &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
-               }
-       }
-
-       /*
-        *      We've got to give SOME value for Id & ports, so that
-        *      the packets can be added to the request queue.
-        *      However, we don't want to keep track of used/unused
-        *      id's and ports, as that's a lot of work.  This hack
-        *      ensures that (if we have real random numbers), that
-        *      there will be a collision on every 2^(16+15+15+24 - 1)
-        *      packets, on average.  That means we can read 2^37
-        *      packets before having a collision, which means it's
-        *      effectively impossible.
-        */
-       packet->id = lrad_rand() & 0xffff;
-       packet->src_port = 1024 + (lrad_rand() & 0x7fff);
-       packet->dst_port = 1024 + (lrad_rand() & 0x7fff);
-
-       packet->dst_ipaddr.af = AF_INET;
-       packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (lrad_rand() & 0xffffff));
-
-       packet->vps = data->vps;
-
-       /*
-        *      Re-set the state.
-        */
-       data->vps = NULL;
-       data->state = STATE_HEADER;
-
-       /*
-        *      Look for Acct-Delay-Time, and update
-        *      based on Acct-Delay-Time += (time(NULL) - timestamp)
-        */
-       vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);
-       if (!vp) {
-               vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
-               rad_assert(vp != NULL);
-               pairadd(&packet->vps, vp);
-       }
-       if (data->timestamp != 0) {
-               vp->vp_integer += time(NULL) - data->timestamp;
-       }
-
-       *pfun = rad_accounting;
-
-       if (debug_flag) {
-               printf("detail_recv: Read packet from %s\n", data->filename);
-               for (vp = packet->vps; vp; vp = vp->next) {
-                       putchar('\t');
-                       vp_print(stdout, vp);
-                       putchar('\n');
-               }
-       }
-
-       /*
-        *      FIXME: many of these checks may not be necessary when
-        *      reading from the detail file.
-        */
-       if (!received_request(listener, packet, prequest, &detail_client)) {
-               rad_free(&packet);
-               return 0;
-       }
-
-       return 1;
-}
-
-
-/*
- *     Free detail-specific stuff.
- */
-static void detail_free(rad_listen_t *this)
-{
-       listen_detail_t *data = this->data;
-
-       free(data->filename);
-       pairfree(&data->vps);
-
-       if (data->fp != NULL) fclose(data->fp);
-}
-
-
-static int detail_print(rad_listen_t *this, char *buffer, size_t bufsize)
-{
-       return snprintf(buffer, bufsize, "%s",
-                       ((listen_detail_t *)(this->data))->filename);
-}
-
-static int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
-{
-       /*
-        *      We never encode responses "sent to" the detail file.
-        */
-       return 0;
-}
-
-static int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request)
-{
-       /*
-        *      We never decode responses read from the detail file.
-        */
-       return 0;
-}
-
-
-static const CONF_PARSER detail_config[] = {
-       { "filename",   PW_TYPE_STRING_PTR,
-         offsetof(listen_detail_t, filename), NULL,  NULL },
-       { "load_factor",   PW_TYPE_INTEGER,
-         offsetof(listen_detail_t, load_factor), NULL, Stringify(10)},
-
-       { NULL, -1, 0, NULL, NULL }             /* end the list */
-};
-
-
-/*
- *     Parse a detail section.
- */
-static int detail_parse(const char *filename, int lineno,
-                       const CONF_SECTION *cs, rad_listen_t *this)
-{
-       int             rcode;
-       listen_detail_t *data;
-
-       data = this->data;
-
-       rcode = cf_section_parse(cs, data, detail_config);
-       if (rcode < 0) {
-               radlog(L_ERR, "%s[%d]: Failed parsing listen section",
-                      filename, lineno);
-               return -1;
-       }
-
-       if (!data->filename) {
-               radlog(L_ERR, "%s[%d]: No detail file specified in listen section",
-                      filename, lineno);
-               return -1;
-       }
-
-       if ((data->load_factor < 1) || (data->load_factor > 100)) {
-               radlog(L_ERR, "%s[%d]: Load factor must be between 1 and 100",
-                      filename, lineno);
-               return -1;
-       }
-
-       data->vps = NULL;
-       data->fp = NULL;
-       data->state = STATE_UNOPENED;
-       detail_open(this);
-
-       return 0;
-}
-
-
-#ifdef WITH_SNMP
-static int radius_snmp_recv(rad_listen_t *listener,
-                           UNUSED RAD_REQUEST_FUNP *pfun,
-                           UNUSED REQUEST **prequest)
-{
-       if (!mainconfig.do_snmp) return 0;
-
-       if ((rad_snmp.smux_fd >= 0) &&
-           (rad_snmp.smux_event == SMUX_READ)) {
-               smux_read();
-       }
-
-       /*
-        *  If we've got to re-connect, then do so now,
-        *  before calling select again.
-        */
-       if (rad_snmp.smux_event == SMUX_CONNECT) {
-               smux_connect();
-       }
-
-       /*
-        *      Reset this every time, as the smux connect may have
-        *      opened a new socket.
-        */
-       listener->fd = rad_snmp.smux_fd;
-
-       return 0;
-}
-
-
-static int radius_snmp_print(rad_listen_t *this, char *buffer, size_t bufsize)
-{
-       return snprintf(buffer, bufsize, "SMUX with OID .1.3.6.1.4.1.11344.1.1.1");
-}
-
-#endif
-
-static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {
-       { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_NONE */
-
-       /* proxying */
-       { NULL, NULL,
-         proxy_socket_recv, proxy_socket_send,
-         socket_print, proxy_socket_encode, proxy_socket_decode },
-
-       /* authentication */
-       { common_socket_parse, NULL,
-         auth_socket_recv, auth_socket_send,
-         socket_print, client_socket_encode, client_socket_decode },
-
-       /* accounting */
-       { common_socket_parse, NULL,
-         acct_socket_recv, acct_socket_send,
-         socket_print, client_socket_encode, client_socket_decode},
-
-       /* detail */
-       { detail_parse, detail_free,
-         detail_recv, detail_send,
-         detail_print, detail_encode, detail_decode },
-
-       { NULL, NULL, NULL, NULL, NULL, NULL, NULL},    /* RAD_LISTEN_SNMP */
-};
-
-
-
-/*
- *     Binds a listener to a socket.
- */
-static int listen_bind(rad_listen_t *this)
-{
-       rad_listen_t    **last;
-       listen_socket_t *sock = this->data;
-
-       /*
-        *      If the port is zero, then it means the appropriate
-        *      thing from /etc/services.
-        */
-       if (sock->port == 0) {
-               struct servent  *svp;
-
-               switch (this->type) {
-               case RAD_LISTEN_AUTH:
-                       svp = getservbyname ("radius", "udp");
-                       if (svp != NULL) {
-                               sock->port = ntohs(svp->s_port);
-                       } else {
-                               sock->port = PW_AUTH_UDP_PORT;
-                       }
-                       break;
-
-               case RAD_LISTEN_ACCT:
-                       svp = getservbyname ("radacct", "udp");
-                       if (svp != NULL) {
-                               sock->port = ntohs(svp->s_port);
-                       } else {
-                               sock->port = PW_ACCT_UDP_PORT;
-                       }
-                       break;
-
-               default:
-                       radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
-                       return -1;
-               }
-       }
-
-       /*
-        *      Find it in the old list, AFTER updating the port.  If
-        *      it's there, use that, rather than creating a new
-        *      socket.  This allows HUP's to re-use the old sockets,
-        *      which means that packets waiting in the socket queue
-        *      don't get lost.
-        */
-       for (last = &mainconfig.listen;
-            *last != NULL;
-            last = &((*last)->next)) {
-               listen_socket_t *other;
-
-               if (this->type != (*last)->type) continue;
-
-               if ((this->type == RAD_LISTEN_DETAIL) ||
-                   (this->type == RAD_LISTEN_SNMP)) continue;
-
-               other = (listen_socket_t *)((*last)->data);
-
-               if ((sock->port == other->port) &&
-                   (sock->ipaddr.af == other->ipaddr.af) &&
-                   (lrad_ipaddr_cmp(&sock->ipaddr, &other->ipaddr) == 0)) {
-                       this->fd = (*last)->fd;
-                       (*last)->fd = -1;
-                       return 0;
-               }
-       }
-
-       this->fd = lrad_socket(&sock->ipaddr, sock->port);
-       if (this->fd < 0) {
-               radlog(L_ERR|L_CONS, "ERROR: Failed to open socket: %s",
-                      librad_errstr);
-               return -1;
-       }
-
-#if 0
-#ifdef O_NONBLOCK
-       if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0)  {
-               radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
-               return -1;
-       }
-
-       flags |= O_NONBLOCK;
-       if( fcntl(this->fd, F_SETFL, flags) < 0) {
-               radlog(L_ERR, "Failure in fcntl: %s)\n", strerror(errno));
-               return -1;
-       }
-#endif
-#endif
-
-       return 0;
-}
-
-
-/*
- *     Allocate & initialize a new listener.
- */
-static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
-{
-       rad_listen_t *this;
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->type = type;
-       this->recv = master_listen[this->type].recv;
-       this->send = master_listen[this->type].send;
-       this->print = master_listen[this->type].print;
-       this->encode = master_listen[this->type].encode;
-       this->decode = master_listen[this->type].decode;
-
-       switch (type) {
-       case RAD_LISTEN_AUTH:
-       case RAD_LISTEN_ACCT:
-       case RAD_LISTEN_PROXY:
-               this->data = rad_malloc(sizeof(listen_socket_t));
-               memset(this->data, 0, sizeof(listen_socket_t));
-               break;
-
-       case RAD_LISTEN_DETAIL:
-               this->data = rad_malloc(sizeof(listen_detail_t));
-               memset(this->data, 0, sizeof(listen_detail_t));
-
-       default:
-               break;
-       }
-
-       return this;
-}
-
-
-/*
- *     Externally visible function for creating a new proxy LISTENER.
- *
- *     For now, don't take ipaddr or port.
- *
- *     Not thread-safe, but all calls to it are protected by the
- *     proxy mutex in request_list.c
- */
-rad_listen_t *proxy_new_listener()
-{
-       int last_proxy_port, port;
-       rad_listen_t *this, *tmp, **last;
-       listen_socket_t *sock, *old;
-
-       this = listen_alloc(RAD_LISTEN_PROXY);
-
-       /*
-        *      Find an existing proxy socket to copy.
-        *
-        *      FIXME: Make it per-realm, or per-home server!
-        */
-       last_proxy_port = 0;
-       old = NULL;
-       last = &mainconfig.listen;
-       for (tmp = mainconfig.listen; tmp != NULL; tmp = tmp->next) {
-               if (tmp->type == RAD_LISTEN_PROXY) {
-                       sock = tmp->data;
-                       if (sock->port > last_proxy_port) {
-                               last_proxy_port = sock->port + 1;
-                       }
-                       if (!old) old = sock;
-               }
-
-               last = &(tmp->next);
-       }
-
-       if (!old) return NULL;  /* This is a serious error. */
-
-       /*
-        *      FIXME: find a new IP address to listen on?
-        *
-        *      This could likely be done in the "home server"
-        *      configuration, to have per-home-server source IP's.
-        */
-       sock = this->data;
-       memcpy(&sock->ipaddr, &old->ipaddr, sizeof(sock->ipaddr));
-
-       /*
-        *      Keep going until we find an unused port.
-        */
-       for (port = last_proxy_port; port < 64000; port++) {
-               sock->port = port;
-               if (listen_bind(this) == 0) {
-                       /*
-                        *      Add the new listener to the list of
-                        *      listeners.
-                        */
-                       *last = this;
-                       return this;
-               }
-       }
-
-       return NULL;
-}
-
-
-static const LRAD_NAME_NUMBER listen_compare[] = {
-       { "auth",       RAD_LISTEN_AUTH },
-       { "acct",       RAD_LISTEN_ACCT },
-       { "detail",     RAD_LISTEN_DETAIL },
-       { NULL, 0 },
-};
-
-
-/*
- *     Generate a list of listeners.  Takes an input list of
- *     listeners, too, so we don't close sockets with waiting packets.
- */
-int listen_init(const char *filename, rad_listen_t **head)
-{
-       int             rcode;
-       CONF_SECTION    *cs;
-       rad_listen_t    **last;
-       rad_listen_t    *this;
-       lrad_ipaddr_t   server_ipaddr;
-       int             auth_port = 0;
-
-       /*
-        *      We shouldn't be called with a pre-existing list.
-        */
-       rad_assert(head && (*head == NULL));
-
-       last = head;
-       server_ipaddr.af = AF_UNSPEC;
-
-       /*
-        *      If the port is specified on the command-line,
-        *      it over-rides the configuration file.
-        */
-       if (mainconfig.port >= 0) {
-               auth_port = mainconfig.port;
-       } else {
-               rcode = cf_item_parse(mainconfig.config, "port",
-                                     PW_TYPE_INTEGER, &auth_port,
-                                     Stringify(PW_AUTH_UDP_PORT));
-               if (rcode < 0) return -1; /* error parsing it */
-
-               if (rcode == 0)
-                       radlog(L_INFO, "WARNING: The directive 'port' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
-       }
-
-       /*
-        *      If the IP address was configured on the command-line,
-        *      use that as the "bind_address"
-        */
-       if (mainconfig.myip.af != AF_UNSPEC) {
-               memcpy(&server_ipaddr, &mainconfig.myip,
-                      sizeof(server_ipaddr));
-               goto bind_it;
-       }
-
-       /*
-        *      Else look for bind_address and/or listen sections.
-        */
-       server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
-       rcode = cf_item_parse(mainconfig.config, "bind_address",
-                             PW_TYPE_IPADDR,
-                             &server_ipaddr.ipaddr.ip4addr, NULL);
-       if (rcode < 0) return -1; /* error parsing it */
-
-       if (rcode == 0) { /* successfully parsed IPv4 */
-               listen_socket_t *sock;
-               server_ipaddr.af = AF_INET;
-
-               radlog(L_INFO, "WARNING: The directive 'bind_adress' is deprecated, and will be removed in future versions of FreeRADIUS. Please edit the configuration files to use the directive 'listen'.");
-
-       bind_it:
-               this = listen_alloc(RAD_LISTEN_AUTH);
-               sock = this->data;
-
-               sock->ipaddr = server_ipaddr;
-               sock->port = auth_port;
-
-               if (listen_bind(this) < 0) {
-                       listen_free(&this);
-                       listen_free(head);
-                       radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", sock->port);
-                       return -1;
-               }
-               auth_port = sock->port; /* may have been updated in listen_bind */
-               *last = this;
-               last = &(this->next);
-
-               /*
-                *      Open Accounting Socket.
-                *
-                *      If we haven't already gotten acct_port from
-                *      /etc/services, then make it auth_port + 1.
-                */
-               this = listen_alloc(RAD_LISTEN_ACCT);
-               sock = this->data;
-
-               /*
-                *      Create the accounting socket.
-                *
-                *      The accounting port is always the
-                *      authentication port + 1
-                */
-               sock->ipaddr = server_ipaddr;
-               sock->port = auth_port + 1;
-
-               if (listen_bind(this) < 0) {
-                       listen_free(&this);
-                       listen_free(head);
-                       radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", sock->port);
-                       return -1;
-               }
-
-               *last = this;
-               last = &(this->next);
-
-       } else if (mainconfig.port > 0) { /* no bind address, but a port */
-               radlog(L_CONS|L_ERR, "The command-line says \"-p %d\", but there is no associated IP address to use",
-                      mainconfig.port);
-               return -1;
-       }
-
-       /*
-        *      They specified an IP on the command-line, ignore
-        *      all listen sections.
-        */
-       if (mainconfig.myip.af != AF_UNSPEC) goto do_proxy;
-
-       /*
-        *      Walk through the "listen" sections, if they exist.
-        */
-       for (cs = cf_subsection_find_next(mainconfig.config, NULL, "listen");
-            cs != NULL;
-            cs = cf_subsection_find_next(mainconfig.config, cs, "listen")) {
-               int             type;
-               char            *listen_type, *identity;
-               int             lineno = cf_section_lineno(cs);
-
-               listen_type = identity = NULL;
-
-               DEBUG2(" listen {");
-
-               rcode = cf_item_parse(cs, "type", PW_TYPE_STRING_PTR,
-                                     &listen_type, "");
-               if (rcode < 0) return -1;
-               if (rcode == 1) {
-                       listen_free(head);
-                       free(listen_type);
-                       radlog(L_ERR, "%s[%d]: No type specified in listen section",
-                              filename, lineno);
-                       return -1;
-               }
-
-               /*
-                *      See if there's an identity.
-                */
-               rcode = cf_item_parse(cs, "identity", PW_TYPE_STRING_PTR,
-                                     &identity, NULL);
-               if (rcode < 0) {
-                       listen_free(head);
-                       free(identity);
-                       return -1;
-               }
-
-               type = lrad_str2int(listen_compare, listen_type,
-                                   RAD_LISTEN_NONE);
-               free(listen_type);
-               if (type == RAD_LISTEN_NONE) {
-                       listen_free(head);
-                       radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
-                              filename, lineno);
-                       return -1;
-               }
-
-               /*
-                *      Set up cross-type data.
-                */
-               this = listen_alloc(type);
-               this->identity = identity;
-               this->fd = -1;
-
-               /*
-                *      Call per-type parser.
-                */
-               if (master_listen[type].parse(filename, lineno,
-                                             cs, this) < 0) {
-                       listen_free(&this);
-                       listen_free(head);
-                       return -1;
-               }
-
-               DEBUG2(" }");
-
-               *last = this;
-               last = &(this->next);
-       }
-
-       /*
-        *      If we're proxying requests, open the proxy FD.
-        *      Otherwise, don't do anything.
-        */
- do_proxy:
-       if (mainconfig.proxy_requests == TRUE) {
-               int             port = -1;
-               listen_socket_t *sock = NULL;
-
-               /*
-                *      No sockets to receive packets, therefore
-                *      proxying is pointless.
-                */
-               if (!*head) return -1;
-
-               /*
-                *      If we previously had proxy sockets, copy them
-                *      to the new config.
-                */
-               if (mainconfig.listen != NULL) {
-                       rad_listen_t *old, *next, **tail;
-
-                       tail = &mainconfig.listen;
-                       for (old = mainconfig.listen;
-                            old != NULL;
-                            old = next) {
-                               next = old->next;
-
-                               if (old->type != RAD_LISTEN_PROXY) {
-                                       tail = &((*tail)->next);
-                                       continue;
-                               }
-
-                               *last = old;
-                               *tail = next;
-                               old->next = NULL;
-                               last = &(old->next);
-                       }
-
-                       goto do_snmp;
-               }
-
-               /*
-                *      Find the first authentication port,
-                *      and use it
-                */
-               for (this = *head; this != NULL; this = this->next) {
-                       if (this->type == RAD_LISTEN_AUTH) {
-                               sock = this->data;
-                               if (server_ipaddr.af == AF_UNSPEC) {
-                                       server_ipaddr = sock->ipaddr;
-                               }
-                               port = sock->port + 2; /* skip acct port */
-                               break;
-                       }
-               }
-
-               if (port < 0) port = 1024 + (lrad_rand() & 0x1ff);
-
-               /*
-                *      Address is still unspecified, use IPv4.
-                */
-               if (server_ipaddr.af == AF_UNSPEC) {
-                       server_ipaddr.af = AF_INET;
-                       server_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_ANY);
-               }
-
-               this = listen_alloc(RAD_LISTEN_PROXY);
-               sock = this->data;
-
-               /*
-                *      Create the first proxy socket.
-                */
-               sock->ipaddr = server_ipaddr;
-
-               /*
-                *      Try to find a proxy port (value doesn't matter)
-                */
-               for (sock->port = port;
-                    sock->port < 64000;
-                    sock->port++) {
-                       if (listen_bind(this) == 0) {
-                               *last = this;
-                               last = &(this->next); /* just in case */
-                               break;
-                       }
-               }
-
-               if (sock->port >= 64000) {
-                       listen_free(head);
-                       listen_free(&this);
-                       radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
-                       return -1;
-               }
-       }
-
- do_snmp:
-#ifdef WITH_SNMP
-       if (mainconfig.do_snmp) {
-               radius_snmp_init();
-
-               /*
-                *      Forget about the old one.
-                */
-               for (this = mainconfig.listen;
-                    this != NULL;
-                    this = this->next) {
-                       if (this->type != RAD_LISTEN_SNMP) continue;
-                       this->fd = -1;
-               }
-
-               this = rad_malloc(sizeof(*this));
-               memset(this, 0, sizeof(*this));
-
-               this->type = RAD_LISTEN_SNMP;
-               this->fd = rad_snmp.smux_fd;
-
-               this->recv = radius_snmp_recv;
-               this->print = radius_snmp_print;
-
-               *last = this;
-               last = &(this->next);
-       }
-#endif
-
- done:
-       return 0;
-}
-
-/*
- *     Free a linked list of listeners;
- */
-void listen_free(rad_listen_t **head)
-{
-       rad_listen_t *this;
-
-       if (!head || !*head) return;
-
-       this = *head;
-       while (this) {
-               rad_listen_t *next = this->next;
-
-               free(this->identity);
-
-               /*
-                *      Other code may have eaten the FD.
-                */
-               if (this->fd >= 0) close(this->fd);
-
-               if (master_listen[this->type].free) {
-                       master_listen[this->type].free(this);
-               }
-               free(this->data);
-               free(this);
-
-               this = next;
-       }
-
-       *head = NULL;
-}
index 128c099..eb50a2e 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2001  Chad Miller <cmiller@surfsouth.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include "radiusd.h"
 
 #ifdef HAVE_SYSLOG_H
 #      include <syslog.h>
-/* keep track of whether we've run openlog() */
-static int openlog_run = 0;
 #endif
 
  /*
  * Logging facility names
  */
-static const LRAD_NAME_NUMBER levels[] = {
+static LRAD_NAME_NUMBER levels[] = {
        { ": Debug: ",          L_DBG   },
        { ": Auth: ",           L_AUTH  },
        { ": Proxy: ",          L_PROXY },
        { ": Info: ",           L_INFO  },
-       { ": Acct: ",           L_ACCT  },
        { ": Error: ",          L_ERR   },
        { NULL, 0 }
 };
@@ -53,11 +59,10 @@ static const LRAD_NAME_NUMBER levels[] = {
  */
 int vradlog(int lvl, const char *fmt, va_list ap)
 {
-       int fd = mainconfig.radlog_fd;
-       FILE *fp = NULL;
+       FILE *msgfd = NULL;
        unsigned char *p;
        char buffer[8192];
-       int len, print_timestamp = 0;
+       int len;
 
        /*
         *      NOT debugging, and trying to log debug messages.
@@ -72,73 +77,51 @@ int vradlog(int lvl, const char *fmt, va_list ap)
         *      If we don't want any messages, then
         *      throw them away.
         */
-       if (mainconfig.radlog_dest == RADLOG_NULL) {
+       if (radlog_dest == RADLOG_NULL) {
                return 0;
        }
 
-       /*
-        *      Don't print timestamps to syslog, it does that for us.
-        *      Don't print timestamps for low levels of debugging.
-        *
-        *      Print timestamps for non-debugging, and for high levels
-        *      of debugging.
-        */
-       if ((mainconfig.radlog_dest != RADLOG_SYSLOG) &&
-           (debug_flag != 1) && (debug_flag != 2)) {
-               print_timestamp = 1;
-       }
+       if (debug_flag
+           || (radlog_dest == RADLOG_STDOUT)
+           || (radlog_dir == NULL)) {
+               msgfd = stdout;
 
-       *buffer = '\0';
-       len = 0;
-       if (fd != -1) {
-               /*
-                *      Use it, rather than anything else.
-                */
+       } else if (radlog_dest == RADLOG_STDERR) {
+               msgfd = stderr;
 
-#ifdef HAVE_SYSLOG_H
-       } else if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
+       } else if (radlog_dest != RADLOG_SYSLOG) {
                /*
-                *      Open run openlog() on the first log message
+                *      No log file set.  It must go to stdout.
                 */
-               if(!openlog_run) {
-                       openlog(progname, LOG_PID, mainconfig.syslog_facility);
-                       openlog_run = 1;
-               }
-#endif
+               if (!mainconfig.log_file) {
+                       msgfd = stdout;
 
-       } else if (!mainconfig.log_file) {
-               /*
-                *      Errors go to stderr, in the hope that they will
-                *      be printed somewhere.
-                */
-               if (lvl & L_ERR) {
-                       fd = STDERR_FILENO;
-                       print_timestamp = 0;
-                       snprintf(buffer, sizeof(buffer), "%s: ", progname);
-                       len = strlen(buffer);
-               } else {
                        /*
-                        *      No log file set.  Discard it.
+                        *      Else try to open the file.
                         */
-                       return 0;
+               } else if ((msgfd = fopen(mainconfig.log_file, "a")) == NULL) {
+                        fprintf(stderr, "%s: Couldn't open %s for logging: %s\n",
+                                progname, mainconfig.log_file, strerror(errno));
+
+                        fprintf(stderr, "  (");
+                        vfprintf(stderr, fmt, ap);  /* the message that caused the log */
+                        fprintf(stderr, ")\n");
+                        return -1;
                }
-
-       } else if ((fp = fopen(mainconfig.log_file, "a")) == NULL) {
-               fprintf(stderr, "%s: Couldn't open %s for logging: %s\n",
-                       progname, mainconfig.log_file, strerror(errno));
-
-               fprintf(stderr, "  (");
-               vfprintf(stderr, fmt, ap);  /* the message that caused the log */
-               fprintf(stderr, ")\n");
-               return -1;
        }
 
-       if (print_timestamp) {
+#ifdef HAVE_SYSLOG_H
+       if (radlog_dest == RADLOG_SYSLOG) {
+               *buffer = '\0';
+               len = 0;
+       } else
+#endif
+       {
                const char *s;
                time_t timeval;
 
                timeval = time(NULL);
-               CTIME_R(&timeval, buffer + len, sizeof(buffer) - len - 1);
+               CTIME_R(&timeval, buffer, 8192);
 
                s = lrad_int2str(levels, (lvl & ~L_CONS), ": ");
 
@@ -146,7 +129,14 @@ int vradlog(int lvl, const char *fmt, va_list ap)
                len = strlen(buffer);
        }
 
-       vsnprintf(buffer + len, sizeof(buffer) - len - 1, fmt, ap);
+#ifdef HAVE_VSNPRINTF
+       vsnprintf(buffer + len, sizeof(buffer) - len -1, fmt, ap);
+#else
+       vsprintf(buffer + len, fmt, ap);
+       if (strlen(buffer) >= sizeof(buffer) - 1)
+               /* What can we do? */
+               _exit(42);
+#endif
 
        /*
         *      Filter out characters not in Latin-1.
@@ -154,14 +144,41 @@ int vradlog(int lvl, const char *fmt, va_list ap)
        for (p = (unsigned char *)buffer; *p != '\0'; p++) {
                if (*p == '\r' || *p == '\n')
                        *p = ' ';
-               else if (*p == '\t') continue;
                else if (*p < 32 || (*p >= 128 && *p <= 160))
                        *p = '?';
        }
        strcat(buffer, "\n");
 
+       /*
+        *   If we're debugging, for small values of debug, then
+        *   we don't do timestamps.
+        */
+       if ((debug_flag == 1) || (debug_flag == 2)) {
+               p = buffer + len;
+
+       } else {
+               /*
+                *  No debugging, or lots of debugging.  Print
+                *  the time stamps.
+                */
+               p = buffer;
+       }
+
+#ifdef HAVE_SYSLOG_H
+       if (radlog_dest != RADLOG_SYSLOG)
+#endif
+       {
+               fputs(p, msgfd);
+               if (msgfd == stdout) {
+                       fflush(stdout);
+               } else if (msgfd == stderr) {
+                       fflush(stderr);
+               } else {
+                       fclose(msgfd);
+               }
+       }
 #ifdef HAVE_SYSLOG_H
-       if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
+       else {                  /* it was syslog */
                switch(lvl & ~L_CONS) {
                        case L_DBG:
                                lvl = LOG_DEBUG;
@@ -172,9 +189,6 @@ int vradlog(int lvl, const char *fmt, va_list ap)
                        case L_PROXY:
                                lvl = LOG_NOTICE;
                                break;
-                       case L_ACCT:
-                               lvl = LOG_NOTICE;
-                               break;
                        case L_INFO:
                                lvl = LOG_INFO;
                                break;
@@ -182,16 +196,9 @@ int vradlog(int lvl, const char *fmt, va_list ap)
                                lvl = LOG_ERR;
                                break;
                }
-               syslog(lvl, "%s", buffer);
-       } else
-#endif
-       if (fp != NULL) {
-               fputs(buffer, fp);
-               fflush(fp);
-               fclose(fp);
-       } else if (fd >= 0) {
-               write(fd, buffer, strlen(buffer));
+               syslog(lvl, "%s", buffer + len); /* don't print timestamp */
        }
+#endif
 
        return 0;
 }
index b366807..9c9a184 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006-2007  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/rad_assert.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include <sys/stat.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
 #endif
 
-#ifdef HAVE_PWD_H
-#include <pwd.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
 #endif
 
-#ifdef HAVE_GRP_H
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "conffile.h"
+#include "token.h"
+
+#include <sys/resource.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/stat.h>
 #include <grp.h>
-#endif
+#include <pwd.h>
 
-#ifdef HAVE_SYS_PRTCL_H
+#ifdef HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
 #endif
 
-#ifdef HAVE_SYSLOG_H
-#      include <syslog.h>
+#ifdef WITH_UDPFROMTO
+#include "udpfromto.h"
 #endif
 
+
 struct main_config_t mainconfig;
 
 /*
- *     Temporary local variables for parsing the configuration
- *     file.
+ *  Local variables for stuff.
  */
 static uid_t server_uid;
 static gid_t server_gid;
@@ -64,106 +71,36 @@ static gid_t server_gid;
  */
 static const char *localstatedir = NULL;
 static const char *prefix = NULL;
-static char *syslog_facility = NULL;
-static const LRAD_NAME_NUMBER str2fac[] = {
-#ifdef LOG_KERN
-       { "kern", LOG_KERN },
-#endif
-#ifdef LOG_USER
-       { "user", LOG_USER },
-#endif
-#ifdef LOG_MAIL
-       { "mail", LOG_MAIL },
-#endif
-#ifdef LOG_DAEMON
-       { "daemon", LOG_DAEMON },
-#endif
-#ifdef LOG_AUTH
-       { "auth", LOG_AUTH },
-#endif
-#ifdef LOG_LPR
-       { "lpr", LOG_LPR },
-#endif
-#ifdef LOG_NEWS
-       { "news", LOG_NEWS },
-#endif
-#ifdef LOG_UUCP
-       { "uucp", LOG_UUCP },
-#endif
-#ifdef LOG_CRON
-       { "cron", LOG_CRON },
-#endif
-#ifdef LOG_AUTHPRIV
-       { "authpriv", LOG_AUTHPRIV },
-#endif
-#ifdef LOG_FTP
-       { "ftp", LOG_FTP },
-#endif
-#ifdef LOG_LOCAL0
-       { "local0", LOG_LOCAL0 },
-#endif
-#ifdef LOG_LOCAL1
-       { "local1", LOG_LOCAL1 },
-#endif
-#ifdef LOG_LOCAL2
-       { "local2", LOG_LOCAL2 },
-#endif
-#ifdef LOG_LOCAL3
-       { "local3", LOG_LOCAL3 },
-#endif
-#ifdef LOG_LOCAL4
-       { "local4", LOG_LOCAL4 },
-#endif
-#ifdef LOG_LOCAL5
-       { "local5", LOG_LOCAL5 },
-#endif
-#ifdef LOG_LOCAL6
-       { "local6", LOG_LOCAL6 },
-#endif
-#ifdef LOG_LOCAL7
-       { "local7", LOG_LOCAL7 },
-#endif
-       { NULL, -1 }
-};
+static int auth_port = 0;
 
 /*
  *  Map the proxy server configuration parameters to variables.
  */
-static const CONF_PARSER proxy_config[] = {
+static CONF_PARSER proxy_config[] = {
        { "retry_delay",  PW_TYPE_INTEGER, 0, &mainconfig.proxy_retry_delay, Stringify(RETRY_DELAY) },
        { "retry_count",  PW_TYPE_INTEGER, 0, &mainconfig.proxy_retry_count, Stringify(RETRY_COUNT) },
+       { "synchronous",  PW_TYPE_BOOLEAN, 0, &mainconfig.proxy_synchronous, "no" },
        { "default_fallback", PW_TYPE_BOOLEAN, 0, &mainconfig.proxy_fallback, "no" },
        { "dead_time",    PW_TYPE_INTEGER, 0, &mainconfig.proxy_dead_time, Stringify(DEAD_TIME) },
+        { "post_proxy_authorize", PW_TYPE_BOOLEAN, 0, &mainconfig.post_proxy_authorize, "yes" },
        { "wake_all_if_all_dead", PW_TYPE_BOOLEAN, 0, &mainconfig.wake_all_if_all_dead, "no" },
-       { "proxy_fail_type", PW_TYPE_STRING_PTR, 0, &mainconfig.proxy_fail_type, NULL},
        { NULL, -1, 0, NULL, NULL }
 };
 
-
 /*
  *  Security configuration for the server.
  */
-static const CONF_PARSER security_config[] = {
+static CONF_PARSER security_config[] = {
        { "max_attributes",  PW_TYPE_INTEGER, 0, &librad_max_attributes, Stringify(0) },
        { "reject_delay",  PW_TYPE_INTEGER, 0, &mainconfig.reject_delay, Stringify(0) },
        { "status_server", PW_TYPE_BOOLEAN, 0, &mainconfig.status_server, "no"},
        { NULL, -1, 0, NULL, NULL }
 };
 
-
-/*
- *  syslog configuration for the server.
- */
-static const CONF_PARSER log_config[] = {
-       { "syslog_facility",  PW_TYPE_STRING_PTR, 0, &syslog_facility, Stringify(0) },
-       { NULL, -1, 0, NULL, NULL }
-};
-
-
 /*
  *  A mapping of configuration file names to internal variables
  */
-static const CONF_PARSER server_config[] = {
+static CONF_PARSER server_config[] = {
        /*
         *      FIXME: 'prefix' is the ONLY one which should be
         *      configured at compile time.  Hard-coding it here is
@@ -183,32 +120,31 @@ static const CONF_PARSER server_config[] = {
        { "max_request_time", PW_TYPE_INTEGER, 0, &mainconfig.max_request_time, Stringify(MAX_REQUEST_TIME) },
        { "cleanup_delay", PW_TYPE_INTEGER, 0, &mainconfig.cleanup_delay, Stringify(CLEANUP_DELAY) },
        { "max_requests", PW_TYPE_INTEGER, 0, &mainconfig.max_requests, Stringify(MAX_REQUESTS) },
-#ifdef DELETE_BLOCKED_REQUESTS
        { "delete_blocked_requests", PW_TYPE_INTEGER, 0, &mainconfig.kill_unresponsive_children, Stringify(FALSE) },
-#endif
+       { "port", PW_TYPE_INTEGER, 0, &auth_port, Stringify(PW_AUTH_UDP_PORT) },
        { "allow_core_dumps", PW_TYPE_BOOLEAN, 0, &mainconfig.allow_core_dumps, "no" },
        { "log_stripped_names", PW_TYPE_BOOLEAN, 0, &log_stripped_names,"no" },
-
        { "log_file", PW_TYPE_STRING_PTR, -1, &mainconfig.log_file, "${logdir}/radius.log" },
        { "log_auth", PW_TYPE_BOOLEAN, -1, &mainconfig.log_auth, "no" },
        { "log_auth_badpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_badpass, "no" },
        { "log_auth_goodpass", PW_TYPE_BOOLEAN, 0, &mainconfig.log_auth_goodpass, "no" },
        { "pidfile", PW_TYPE_STRING_PTR, 0, &mainconfig.pid_file, "${run_dir}/radiusd.pid"},
+       { "bind_address", PW_TYPE_IPADDR, 0, &mainconfig.myip, "*" },
        { "user", PW_TYPE_STRING_PTR, 0, &mainconfig.uid_name, NULL},
        { "group", PW_TYPE_STRING_PTR, 0, &mainconfig.gid_name, NULL},
+       { "usercollide", PW_TYPE_BOOLEAN, 0, &mainconfig.do_usercollide,  "no" },
+       { "lower_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_user, "no" },
+       { "lower_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_lower_pass, "no" },
+       { "nospace_user", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_user, "no" },
+       { "nospace_pass", PW_TYPE_STRING_PTR, 0, &mainconfig.do_nospace_pass, "no" },
        { "checkrad", PW_TYPE_STRING_PTR, 0, &mainconfig.checkrad, "${sbindir}/checkrad" },
-
-       { "debug_level", PW_TYPE_INTEGER, 0, &mainconfig.debug_level, "0"},
-
        { "proxy_requests", PW_TYPE_BOOLEAN, 0, &mainconfig.proxy_requests, "yes" },
-       { "log", PW_TYPE_SUBSECTION, 0, NULL,  (const void *) log_config},
-       { "proxy", PW_TYPE_SUBSECTION, 0, NULL, (const void *) proxy_config },
-       { "security", PW_TYPE_SUBSECTION, 0, NULL, (const void *) security_config },
+       { "proxy", PW_TYPE_SUBSECTION, 0, proxy_config, NULL },
+       { "security", PW_TYPE_SUBSECTION, 0, security_config, NULL },
+       { "debug_level", PW_TYPE_INTEGER, 0, &mainconfig.debug_level, "0"},
        { NULL, -1, 0, NULL, NULL }
 };
 
-
-#define MAX_ARGV (256)
 /*
  *     Xlat for %{config:section.subsection.attribute}
  */
@@ -219,12 +155,9 @@ static int xlat_config(void *instance, REQUEST *request,
 {
        CONF_SECTION *cs;
        CONF_PAIR *cp;
-       int i, argc, left;
-       const char *from, *value;
-       char *to;
-       char myfmt[1024];
-       char argv_buf[1024];
-       char *argv[MAX_ARGV];
+       char buffer[1024];
+       char *p, *value;
+       const char *start = fmt;
 
        request = request;      /* -Wunused */
        instance = instance;    /* -Wunused */
@@ -232,176 +165,44 @@ static int xlat_config(void *instance, REQUEST *request,
        cp = NULL;
        cs = NULL;
 
-       /*
-        *      Split the string into argv's BEFORE doing radius_xlat...
-        *      Copied from exec.c
-        */
-       from = fmt;
-       to = myfmt;
-       argc = 0;
-       while (*from) {
-               int flag, length;
-
-               flag = 0;
-               argv[argc] = to;
-               argc++;
-
-               if (argc >= (MAX_ARGV - 1)) break;
-
+       while (cp == NULL) {
                /*
-                *      Copy the argv over to our buffer.
+                *      Find the next section.
                 */
-               while (*from) {
-                       if (to >= myfmt + sizeof(myfmt) - 1) {
-                               return 0; /* no error msg */
-                       }
-
-                       switch (*from) {
-                       case '%':
-                               if (from[1] == '{') {
-                                       *(to++) = *(from++);
-
-                                       length = rad_copy_variable(to, from);
-                                       if (length < 0) {
-                                               return -1;
-                                       }
-                                       from += length;
-                                       to += length;
-                               } else { /* FIXME: catch %%{ ? */
-                                       *(to++) = *(from++);
-                               }
-                               break;
-
-                       case '[':
-                               if (flag != 0) {
-                                       radlog(L_ERR, "config: Unexpected nested '[' in \"%s\"", fmt);
-                                       return 0;
-                               }
-                               flag++;
-                               *(to++) = *(from++);
-                               break;
-
-                       case ']':
-                               if (flag == 0) {
-                                       radlog(L_ERR, "config: Unbalanced ']' in \"%s\"", fmt);
-                                       return 0;
-                               }
-                               if (from[1] != '.') {
-                                       radlog(L_ERR, "config: Unexpected text after ']' in \"%s\"", fmt);
-                                       return 0;
-                               }
-
-                               flag--;
-                               *(to++) = *(from++);
-                               break;
-
-                       case '.':
-                               if (flag == 0) break;
-                               /* FALL-THROUGH */
-
-                       default:
-                               *(to++) = *(from++);
-                               break;
-                       }
-
-                       if ((*from == '.') && (flag == 0)) {
-                               from++;
-                               break;
-                       }
-               } /* end of string, or found a period */
-
-               if (flag != 0) {
-                       radlog(L_ERR, "config: Unbalanced '[' in \"%s\"", fmt);
-                       return 0;
+               for (p = buffer; (*fmt != 0) && (*fmt != '.'); p++, fmt++) {
+                       *p = *fmt;
                }
-
-               *(to++) = '\0'; /* terminate the string. */
-       }
-
-       /*
-        *      Expand each string, as appropriate
-        */
-       to = argv_buf;
-       left = sizeof(argv_buf);
-       for (i = 0; i < argc; i++) {
-               int sublen;
+               *p = '\0';
 
                /*
-                *      Don't touch argv's which won't be translated.
+                *  The character is a '.', find a section (as the user
+                *  has given us a subsection to find)
                 */
-               if (strchr(argv[i], '%') == NULL) continue;
-
-               sublen = radius_xlat(to, left - 1, argv[i], request, NULL);
-               if (sublen <= 0) {
-                       /*
-                        *      Fail to be backwards compatible.
-                        *
-                        *      It's yucky, but it won't break anything,
-                        *      and it won't cause security problems.
-                        */
-                       sublen = 0;
-               }
-
-               argv[i] = to;
-               to += sublen;
-               *(to++) = '\0';
-               left -= sublen;
-               left--;
+               if (*fmt == '.') {
+                       CONF_SECTION *next;
 
-               if (left <= 0) {
-                       return 0;
-               }
-       }
-       argv[argc] = NULL;
+                       fmt++;  /* skip the period */
 
-       cs = cf_section_find(NULL); /* get top-level section */
+                       if (cs == NULL) {
+                         next = cf_section_find(buffer);
+                       } else {
+                         next = cf_subsection_find_next(cs, NULL, buffer);
+                       }
+                       if (next == NULL) {
+                               radlog(L_ERR, "config: No such section %s in format string %s", buffer, start);
+                               return 0;
+                       }
+                       cs = next;
 
-       /*
-        *      Root through section & subsection references.
-        *      The last entry of argv MUST be the CONF_PAIR.
-        */
-       for (i = 0; i < argc - 1; i++) {
-               char *name2 = NULL;
-               CONF_SECTION *subcs;
+               } else {        /* no period, must be a conf-part */
+                       cp = cf_pair_find(cs, buffer);
 
-               /*
-                *      FIXME: What about RADIUS attributes containing '['?
-                */
-               name2 = strchr(argv[i], '[');
-               if (name2) {
-                       char *p = strchr(name2, ']');
-                       rad_assert(p != NULL);
-                       rad_assert(p[1] =='\0');
-                       *p = '\0';
-                       *name2 = '\0';
-                       name2++;
-               }
-
-               if (name2) {
-                       subcs = cf_section_sub_find_name2(cs, argv[i],
-                                                         name2);
-                       if (!subcs) {
-                         radlog(L_ERR, "config: section \"%s %s {}\" not found while dereferencing \"%s\"", argv[i], name2, fmt);
-                         return 0;
-                       }
-               } else {
-                       subcs = cf_section_sub_find(cs, argv[i]);
-                       if (!subcs) {
-                         radlog(L_ERR, "config: section \"%s {}\" not found while dereferencing \"%s\"", argv[i], fmt);
-                         return 0;
+                       if (cp == NULL) {
+                               radlog(L_ERR, "config: No such section %s in format string %s", buffer, start);
+                               return 0;
                        }
                }
-               cs = subcs;
-       } /* until argc - 1 */
-
-       /*
-        *      This can now have embedded periods in it.
-        */
-       cp = cf_pair_find(cs, argv[argc - 1]);
-       if (!cp) {
-               radlog(L_ERR, "config: item \"%s\" not found while dereferencing \"%s\"", argv[argc], fmt);
-               return 0;
-       }
+       } /* until cp is non-NULL */
 
        /*
         *  Ensure that we only copy what's necessary.
@@ -441,7 +242,7 @@ static int r_mkdir(const char *part)
                return(1);
 
        if (mkdir(part, 0770) != 0) {
-               radlog(L_ERR, "mkdir(%s) error: %s\n", part, strerror(errno));
+               fprintf(stderr, "mkdir(%s) error: %s\n", part, strerror(errno));
                return(1);
        }
 
@@ -453,11 +254,9 @@ static int r_mkdir(const char *part)
  */
 static int radlogdir_iswritable(const char *effectiveuser)
 {
-#ifdef HAVE_GETPWNAM
        struct passwd *pwent;
-#endif
 
-       if (!radlog_dir || radlog_dir[0] != '/')
+       if (radlog_dir[0] != '/')
                return(0);
 
        if (r_mkdir(radlog_dir) != 0)
@@ -476,7 +275,6 @@ static int radlogdir_iswritable(const char *effectiveuser)
                return 1;
        }
 
-#ifdef HAVE_GETPWNAM
        pwent = getpwnam(effectiveuser);
 
        if (pwent == NULL) /* uh oh! */
@@ -484,7 +282,6 @@ static int radlogdir_iswritable(const char *effectiveuser)
 
        if (chown(radlog_dir, pwent->pw_uid, -1) != 0)
                return(1);
-#endif
 
        return(0);
 }
@@ -495,11 +292,6 @@ static int radlogdir_iswritable(const char *effectiveuser)
  */
 static int switch_users(void)
 {
-#ifdef HAVE_SYS_RESOURCE_H
-       struct rlimit core_limits;
-#endif
-
-#ifdef HAVE_GRP_H
        /*  Set GID.  */
        if (mainconfig.gid_name != NULL) {
                struct group *gr;
@@ -522,9 +314,7 @@ static int switch_users(void)
        } else {
                server_gid = getgid();
        }
-#endif
 
-#ifdef HAVE_PWD_H
        /*  Set UID.  */
        if (mainconfig.uid_name != NULL) {
                struct passwd *pw;
@@ -552,279 +342,980 @@ static int switch_users(void)
                        exit(1);
                }
        }
-#endif
+       return(0);
+}
 
-#ifdef HAVE_SYS_RESOURCE_H
-       /*  Get the current maximum for core files.  */
-       if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
-               radlog(L_ERR|L_CONS, "Failed to get current core limit:  %s", strerror(errno));
-               exit(1);
-       }
-#endif
 
-       if (mainconfig.allow_core_dumps) {
-#ifdef HAVE_SYS_PRTCL_H
-#ifdef PR_SET_DUMPABLE
-               if (prctl(PR_SET_DUMPABLE, 1) < 0) {
-                       radlog(L_ERR|L_CONS,"Cannot enable core dumps: prctl(PR_SET_DUMPABLE) failed: '%s'",
-                              strerror(errno));
+/*
+ * Create the linked list of realms from the new configuration type
+ * This way we don't have to change to much in the other source-files
+ */
+static int generate_realms(const char *filename)
+{
+       CONF_SECTION *cs;
+       REALM *my_realms = NULL;
+       REALM *c, **tail;
+       char *s, *t, *authhost, *accthost;
+       char *name2;
+
+       tail = &my_realms;
+       for (cs = cf_subsection_find_next(mainconfig.config, NULL, "realm");
+            cs != NULL;
+            cs = cf_subsection_find_next(mainconfig.config, cs, "realm")) {
+               name2 = cf_section_name2(cs);
+               if (!name2) {
+                       radlog(L_CONS|L_ERR, "%s[%d]: Missing realm name",
+                              filename, cf_section_lineno(cs));
+                       return -1;
                }
-#endif
-#endif
+               /*
+                * We've found a realm, allocate space for it
+                */
+               c = rad_malloc(sizeof(REALM));
+               memset(c, 0, sizeof(REALM));
 
-#ifdef HAVE_SYS_RESOURCE_H
-               if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
-                       radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
-                                       strerror(errno));
-                       exit(1);
+               c->secret[0] = '\0';
+
+               /*
+                *      No authhost means LOCAL.
+                */
+               if ((authhost = cf_section_value_find(cs, "authhost")) == NULL) {
+                       c->ipaddr = htonl(INADDR_NONE);
+                       c->auth_port = 0;
+               } else {
+                       if ((s = strchr(authhost, ':')) != NULL) {
+                               *s++ = 0;
+                               c->auth_port = atoi(s);
+                       } else {
+                               c->auth_port = PW_AUTH_UDP_PORT;
+                       }
+                       if (strcmp(authhost, "LOCAL") == 0) {
+                               /*
+                                *      Local realms don't have an IP address,
+                                *      secret, or port.
+                                */
+                               c->ipaddr = htonl(INADDR_NONE);
+                               c->auth_port = 0;
+                       } else {
+                               c->ipaddr = ip_getaddr(authhost);
+                               if (c->ipaddr == htonl(INADDR_NONE)) {
+                                       free(c);
+                                       radlog(L_ERR, "%s[%d]: Host %s not found",
+                                              filename, cf_section_lineno(cs),
+                                              authhost);
+                                       return -1;
+                               }
+                       }
 
                        /*
-                        *  If we're running as a daemon, and core
-                        *  dumps are enabled, log that information.
+                        * Double check length, just to be sure!
                         */
-               } else if ((core_limits.rlim_cur != 0) && !debug_flag)
-                       radlog(L_INFO|L_CONS, "Core dumps are enabled.");
-#endif
+                       if (strlen(authhost) >= sizeof(c->server)) {
+                               free(c);
+                               radlog(L_ERR, "%s[%d]: Server name of length %d is greater than allowed: %d",
+                                      filename, cf_section_lineno(cs),
+                                      (int) strlen(authhost),
+                                      (int) sizeof(c->server) - 1);
+                               return -1;
+                       }
+               }
 
-       } else if (!debug_flag) {
-#ifdef HAVE_SYS_RESOURCE_H
                /*
-                *  Not debugging.  Set the core size to zero, to
-                *  prevent security breaches.  i.e. People
-                *  reading passwords from the 'core' file.
+                *      No accthost means LOCAL
                 */
-               struct rlimit limits;
-
-               limits.rlim_cur = 0;
-               limits.rlim_max = core_limits.rlim_max;
+               if ((accthost = cf_section_value_find(cs, "accthost")) == NULL) {
+                       c->acct_ipaddr = htonl(INADDR_NONE);
+                       c->acct_port = 0;
+               } else {
+                       if ((s = strchr(accthost, ':')) != NULL) {
+                               *s++ = 0;
+                               c->acct_port = atoi(s);
+                       } else {
+                               c->acct_port = PW_ACCT_UDP_PORT;
+                       }
+                       if (strcmp(accthost, "LOCAL") == 0) {
+                               /*
+                                *      Local realms don't have an IP address,
+                                *      secret, or port.
+                                */
+                               c->acct_ipaddr = htonl(INADDR_NONE);
+                               c->acct_port = 0;
+                       } else {
+                               c->acct_ipaddr = ip_getaddr(accthost);
+                               if (c->acct_ipaddr == htonl(INADDR_NONE)) {
+                                       free(c);
+                                       radlog(L_ERR, "%s[%d]: Host %s not found",
+                                              filename, cf_section_lineno(cs),
+                                              accthost);
+                                       return -1;
+                               }
+                       }
 
-               if (setrlimit(RLIMIT_CORE, &limits) < 0) {
-                       radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
-                                       strerror(errno));
-                       exit(1);
+                       if (strlen(accthost) >= sizeof(c->acct_server)) {
+                               free(c);
+                               radlog(L_ERR, "%s[%d]: Server name of length %d is greater than allowed: %d",
+                                      filename, cf_section_lineno(cs),
+                                      (int) strlen(accthost),
+                                      (int) sizeof(c->acct_server) - 1);
+                               return -1;
+                       }
                }
-#endif
-       }
 
-#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
-       /*
-        *      We've probably written to the log file already as
-        *      root.root, so if we have switched users, we've got to
-        *      update the ownership of the file.
-        */
-       if ((debug_flag == 0) &&
-           (mainconfig.radlog_dest == RADLOG_FILES) &&
-           (mainconfig.log_file != NULL)) {
-               chown(mainconfig.log_file, server_uid, server_gid);
-       }
-#endif
-       return(0);
-}
+               if (strlen(name2) >= sizeof(c->realm)) {
+                       free(c);
+                       radlog(L_ERR, "%s[%d]: Realm name of length %d is greater than allowed %d",
+                              filename, cf_section_lineno(cs),
+                              (int) strlen(name2),
+                              (int) sizeof(c->server) - 1);
+                       return -1;
+               }
 
+               strcpy(c->realm, name2);
+                if (authhost) strcpy(c->server, authhost);
+               if (accthost) strcpy(c->acct_server, accthost);
 
-static const LRAD_NAME_NUMBER str2dest[] = {
-       { "null", RADLOG_NULL },
-       { "files", RADLOG_FILES },
-       { "syslog", RADLOG_SYSLOG },
-       { "stdout", RADLOG_STDOUT },
-       { "stderr", RADLOG_STDERR },
-       { NULL, RADLOG_NUM_DEST }
-};
+               /*
+                *      If one or the other of authentication/accounting
+                *      servers is set to LOCALHOST, then don't require
+                *      a shared secret.
+                */
+               if ((c->ipaddr != htonl(INADDR_NONE)) ||
+                   (c->acct_ipaddr != htonl(INADDR_NONE))) {
+                       if ((s = cf_section_value_find(cs, "secret")) == NULL ) {
+                               free(c);
+                               radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s",
+                                      filename, cf_section_lineno(cs), name2);
+                               return -1;
+                       }
 
+                       if (strlen(s) >= sizeof(c->secret)) {
+                               free(c);
+                               radlog(L_ERR, "%s[%d]: Secret of length %u is greater than the allowed maximum of %u.",
+                                      filename, cf_section_lineno(cs),
+                                      strlen(s), sizeof(c->secret) - 1);
+                               return -1;
+                       }
+                       strNcpy((char *)c->secret, s, sizeof(c->secret));
+               }
 
-/*
- *     Read config files.
- *
- *     This function can ONLY be called from the main server process.
- */
-int read_mainconfig(int reload)
-{
-       static int old_debug_level = -1;
-       char buffer[1024];
-       CONF_SECTION *cs, *templates;
-       rad_listen_t *listener;
-       struct stat statbuf;
+               c->striprealm = 1;
+
+               if ((cf_section_value_find(cs, "nostrip")) != NULL)
+                       c->striprealm = 0;
+               if ((cf_section_value_find(cs, "noacct")) != NULL)
+                       c->acct_port = 0;
+               if ((cf_section_value_find(cs, "trusted")) != NULL)
+                       c->trusted = 1;
+               if ((cf_section_value_find(cs, "notrealm")) != NULL)
+                       c->notrealm = 1;
+               if ((cf_section_value_find(cs, "notsuffix")) != NULL)
+                       c->notrealm = 1;
+               if ((t = cf_section_value_find(cs,"ldflag")) != NULL) {
+                       static const LRAD_NAME_NUMBER ldflags[] = {
+                               { "fail_over",   0 },
+                               { "round_robin", 1 },
+                               { NULL, 0 }
+                       };
 
-       if (stat(radius_dir, &statbuf) < 0) {
-               radlog(L_ERR|L_CONS, "Errors reading %s: %s",
-                      radius_dir, strerror(errno));
-               return -1;
-       }
+                       c->ldflag = lrad_str2int(ldflags, t, -1);
+                       if (c->ldflag == -1) {
+                               free(c);
+                               radlog(L_ERR, "%s[%d]: Unknown value \"%s\" for ldflag",
+                                      filename, cf_section_lineno(cs),
+                                      t);
+                               return -1;
+                       }
 
-#ifdef S_IWOTH
-       if ((statbuf.st_mode & S_IWOTH) != 0) {
-               radlog(L_ERR|L_CONS, "Configuration directory %s is globally writable.  Refusing to start due to insecure configuration.",
-                      radius_dir);
-         return -1;
-       }
-#endif
+               } else {
+                       c->ldflag = 0; /* non, make it fail-over */
+               }
+               c->active = TRUE;
+               c->acct_active = TRUE;
 
-#ifdef S_IROTH
-       if (0 && (statbuf.st_mode & S_IROTH) != 0) {
-               radlog(L_ERR|L_CONS, "Configuration directory %s is globally readable.  Refusing to start due to insecure configuration.",
-                      radius_dir);
-               return -1;
+               c->next = NULL;
+               *tail = c;
+               tail = &c->next;
        }
-#endif
 
-       /* Read the configuration file */
-       snprintf(buffer, sizeof(buffer), "%.200s/%.50s",
-                radius_dir, mainconfig.radiusd_conf);
-       if ((cs = cf_file_read(buffer)) == NULL) {
-               radlog(L_ERR|L_CONS, "Errors reading %s", buffer);
-               return -1;
-       }
+       /*
+        *      And make these realms preferred over the ones
+        *      in the 'realms' file.
+        */
+       *tail = mainconfig.realms;
+       mainconfig.realms = my_realms;
 
        /*
-        *      Add templates to each kind of subsection.
+        *  Ensure that all of the flags agree for the realms.
+        *
+        *      Yeah, it's O(N^2), but it's only once, and the
+        *      maximum number of realms is small.
         */
-       templates = cf_section_sub_find(cs, "templates");
-       if (templates) {
-               CONF_SECTION *ts, *mycs;
+       for(c = mainconfig.realms; c != NULL; c = c->next) {
+               REALM *this;
+
+               /*
+                *      Check that we cannot load balance to LOCAL
+                *      realms, as that doesn't make any sense.
+                */
+               if ((c->ldflag == 1) &&
+                   ((c->ipaddr == htonl(INADDR_NONE)) ||
+                    (c->acct_ipaddr == htonl(INADDR_NONE)))) {
+                       radlog(L_ERR | L_CONS, "ERROR: Realm %s cannot be load balanced to LOCAL",
+                              c->realm);
+                       exit(1);
+               }
 
                /*
-                *      Loop over the templates, adding them to the
-                *      sections in the main configuration file.
+                *      Compare this realm to all others, to ensure
+                *      that the configuration is consistent.
                 */
-               for (ts = cf_subsection_find_next(templates, NULL, NULL);
-                    ts != NULL;
-                    ts = cf_subsection_find_next(templates, ts, NULL)) {
-                       const char *name1 = cf_section_name1(ts);
+               for (this = c->next; this != NULL; this = this->next) {
+                       if (strcasecmp(c->realm, this->realm) != 0) {
+                               continue;
+                       }
 
                        /*
-                        *      Loop over sections in the main config
-                        *      file, adding templats.
+                        *      Same realm: Different load balancing
+                        *      flag: die.
                         */
-                       for (mycs = cf_subsection_find_next(cs, NULL, name1);
-                            mycs != NULL;
-                            mycs = cf_subsection_find_next(cs, mycs, name1)) {
-                               const char *value;
-
-                               value = cf_section_value_find(mycs, "template");
-                               if (value) {
-                                       CONF_SECTION *tts;
-
-                                       tts = cf_section_sub_find_name2(templates,
-                                                                       name1,
-                                                                       value);
-                                       if (!tts) {
-                                               radlog(L_ERR|L_CONS, "%s[%d]: Section refers to non-existent template \"%s\"", buffer, cf_section_lineno(mycs), value);
-                                               return -1;
-                                       }
-                                       cf_section_template(mycs, tts);
-                               } else {
-                                       cf_section_template(mycs, ts);
-                               }
+                       if (c->ldflag != this->ldflag) {
+                               radlog(L_ERR | L_CONS, "ERROR: Inconsistent value in realm %s for load balancing 'ldflag' attribute",
+                                      c->realm);
+                               exit(1);
                        }
                }
        }
 
-       /*
-        *      Debug flag 1 MAY go to files.
-        *      Debug flag 2 ALWAYS goes to stdout
-        *
-        *      Parse the log_destination before printing anything else.
-        *      All messages before this MUST be errors, which log.c
-        *      will print to stderr, since log_file is NULL, too.
-        */
-       if (debug_flag < 2) {
-               int rcode;
-               char *radlog_dest = NULL;
-
-               rcode = cf_item_parse(cs, "log_destination",
-                                     PW_TYPE_STRING_PTR, &radlog_dest,
-                                     "files");
-               if (rcode < 0) return -1;
-
-               mainconfig.radlog_dest = lrad_str2int(str2dest, radlog_dest, RADLOG_NUM_DEST);
-               if (mainconfig.radlog_dest == RADLOG_NUM_DEST) {
-                       fprintf(stderr, "radiusd: Error: Unknown log_destination %s\n",
-                               radlog_dest);
-                       free(radlog_dest);
-                       cf_section_free(&cs);
-                       return -1;
-               }
+       return 0;
+}
 
-               if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
-                       static const CONF_PARSER syslog_config[] = {
-                               { "log", PW_TYPE_SUBSECTION, 0, NULL,  (const void *) log_config},
-                               { NULL, -1, 0, NULL, NULL }
-                       };
-                       cf_section_parse(cs, NULL, syslog_config);
 
-                       /*
-                        *      Make sure syslog_facility isn't NULL before using it
-                        */
-                       if (!syslog_facility) {
-                               fprintf(stderr, "radiusd: Error: Unknown syslog chosen but no facility spedified\n");
-                               free(radlog_dest);
-                               cf_section_free(&cs);
-                               return -1;
-                       }
-                       mainconfig.syslog_facility = lrad_str2int(str2fac, syslog_facility, -1);
-                       if (mainconfig.syslog_facility < 0) {
-                               fprintf(stderr, "radiusd: Error: Unknown syslog_facility %s\n",
-                                       syslog_facility);
-                               free(radlog_dest);
-                               free(syslog_facility);
-                               cf_section_free(&cs);
-                               return -1;
-                       }
+/*
+ *     Create the linked list of realms from the new configuration
+ *     type.  This way we don't have to change too much in the other
+ *     source-files.
+ */
+static RADCLIENT *generate_clients(const char *filename, CONF_SECTION *section)
+{
+       CONF_SECTION    *cs;
+       RADCLIENT       *list, *c;
+       char            *hostnm, *secret, *shortnm, *netmask;
+       char            *nastype, *login, *password;
+       char            *name2;
+
+       list = NULL;
+       for (cs = cf_subsection_find_next(section, NULL, "client");
+            cs != NULL;
+            cs = cf_subsection_find_next(section, cs, "client")) {
+
+               name2 = cf_section_name2(cs);
+               if (!name2) {
+                       radlog(L_CONS|L_ERR, "%s[%d]: Missing client name",
+                              filename, cf_section_lineno(cs));
+                       clients_free(list);
+                       return NULL;
                }
+               /*
+                * Check the lengths, we don't want any core dumps
+                */
+               hostnm = name2;
 
-               if (mainconfig.radlog_dest == RADLOG_FILES) {
-                       static const CONF_PARSER file_config[] = {
-                               { "log_file", PW_TYPE_STRING_PTR, -1, &mainconfig.log_file, "${logdir}/radius.log" },
-                               { NULL, -1, 0, NULL, NULL }
-                       };
+               if((secret = cf_section_value_find(cs, "secret")) == NULL) {
+                       radlog(L_ERR, "%s[%d]: Missing secret for client: %s",
+                               filename, cf_section_lineno(cs), name2);
+                       clients_free(list);
+                       return NULL;
+               }
 
-                       cf_section_parse(cs, NULL, file_config);
+               if((shortnm = cf_section_value_find(cs, "shortname")) == NULL) {
+                       radlog(L_ERR, "%s[%d]: Missing shortname for client: %s",
+                               filename, cf_section_lineno(cs), name2);
+                       clients_free(list);
+                       return NULL;
                }
 
-               free(radlog_dest);
-       } else {
-               mainconfig.radlog_dest = RADLOG_STDOUT;
-               mainconfig.radlog_fd = STDOUT_FILENO;
-       }
+               netmask = strchr(hostnm, '/');
 
-       if (!reload) {
-               radlog(L_INFO, "Starting - reading configuration files ...");
-       } else {
-               radlog(L_INFO, "Reloading - reading configuration files...");
-       }
+               if (strlen(secret) >= sizeof(c->secret)) {
+                       radlog(L_ERR, "%s[%d]: Secret of length %u is greater than the allowed maximum of %u.",
+                               filename, cf_section_lineno(cs),
+                               strlen(secret), sizeof(c->secret) - 1);
+                       clients_free(list);
+                       return NULL;
+               }
 
-       /* Initialize the dictionary */
-       DEBUG2("read_config_files:  reading dictionary");
-       if (dict_init(radius_dir, RADIUS_DICTIONARY) != 0) {
-               radlog(L_ERR|L_CONS, "Errors reading dictionary: %s",
-                               librad_errstr);
+               if (strlen(shortnm) > sizeof(c->shortname)) {
+                       radlog(L_ERR, "%s[%d]: Client short name of length %u is greater than the allowed maximum of %u.",
+                                       filename, cf_section_lineno(cs),
+                              strlen(shortnm), sizeof(c->shortname) - 1);
+                       clients_free(list);
+                       return NULL;
+               }
+
+               if((nastype = cf_section_value_find(cs, "nastype")) != NULL) {
+                       if(strlen(nastype) >= sizeof(c->nastype)) {
+                              radlog(L_ERR, "%s[%d]: nastype of length %u longer than the allowed maximum of %u",
+                                     filename, cf_section_lineno(cs),
+                                     strlen(nastype), sizeof(c->nastype) - 1);
+                              clients_free(list);
+                              return NULL;
+                       }
+               }
+
+               if((login = cf_section_value_find(cs, "login")) != NULL) {
+                       if(strlen(login) >= sizeof(c->login)) {
+                              radlog(L_ERR, "%s[%d]: login of length %u longer than the allowed maximum of %u",
+                                     filename, cf_section_lineno(cs),
+                                     strlen(login), sizeof(c->login) - 1);
+                              clients_free(list);
+                              return NULL;
+                       }
+               }
+
+               if((password = cf_section_value_find(cs, "password")) != NULL) {
+                       if(strlen(password) >= sizeof(c->password)) {
+                              radlog(L_ERR, "%s[%d]: password of length %u longer than the allowed maximum of %u",
+                                     filename, cf_section_lineno(cs),
+                                     strlen(password), sizeof(c->password) - 1);
+                              clients_free(list);
+                              return NULL;
+                       }
+               }
+
+               /*
+                * The size is fine.. Let's create the buffer
+                */
+               c = rad_malloc(sizeof(RADCLIENT));
+               memset(c, 0, sizeof(RADCLIENT));
+
+               /*
+                *      Look for netmasks.
+                */
+               c->netmask = ~0;
+               if (netmask) {
+                       int mask_length;
+
+                       mask_length = atoi(netmask + 1);
+                       if ((mask_length < 0) || (mask_length > 32)) {
+                               radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.",
+                                               filename, cf_section_lineno(cs), netmask + 1);
+                               clients_free(list);
+                               free(c);
+                               return NULL;
+                       }
+
+                       if (mask_length == 0) {
+                               c->netmask = 0;
+                       } else {
+                               c->netmask = ~0 << (32 - mask_length);
+                       }
+
+                       *netmask = '\0';
+                       c->netmask = htonl(c->netmask);
+               }
+
+               c->ipaddr = ip_getaddr(hostnm);
+               if (c->ipaddr == INADDR_NONE) {
+                       radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
+                                       filename, cf_section_lineno(cs), hostnm);
+                       clients_free(list);
+                       free(c);
+                       return NULL;
+               }
+
+               /*
+                *      Update the client name again...
+                */
+               if (netmask) {
+                       *netmask = '/';
+                       c->ipaddr &= c->netmask;
+                       strcpy(c->longname, hostnm);
+               } else {
+                       ip_hostname(c->longname, sizeof(c->longname),
+                                       c->ipaddr);
+               }
+
+               strcpy((char *)c->secret, secret);
+               strcpy(c->shortname, shortnm);
+               if(nastype != NULL)
+                       strcpy(c->nastype, nastype);
+               if(login != NULL)
+                       strcpy(c->login, login);
+               if(password != NULL)
+                       strcpy(c->password, password);
+
+               c->next = list;
+               list = c;
+       }
+
+       return list;
+}
+
+
+/*
+ *     Code for handling listening on multiple ports.
+ */
+static rad_listen_t listen_inst;
+static const char *listen_type = NULL;
+
+static const CONF_PARSER listen_config[] = {
+       { "ipaddr", PW_TYPE_IPADDR,
+         offsetof(rad_listen_t,ipaddr), NULL, "0.0.0.0" },
+
+       { "port", PW_TYPE_INTEGER,
+         offsetof(rad_listen_t,port), NULL, "0" },
+
+       { "type", PW_TYPE_STRING_PTR,
+         0, &listen_type, "" },
+
+       { NULL, -1, 0, NULL, NULL }             /* end the list */
+};
+
+static const LRAD_NAME_NUMBER listen_compare[] = {
+       { "auth",       RAD_LISTEN_AUTH },
+       { "acct",       RAD_LISTEN_ACCT },
+       { NULL, 0 },
+};
+
+
+/*
+ *     Free a linked list of listeners;
+ */
+static void listen_free(rad_listen_t *list)
+{
+       while (list) {
+               rad_listen_t *next = list->next;
+               
+               /*
+                *      The code below may have eaten the FD.
+                */
+               if (list->fd >= 0) close(list->fd);
+               free(list);
+               
+               list = next;
+       }
+}
+
+/*
+ *     Binds a listener to a socket.
+ */
+static int listen_bind(rad_listen_t *this)
+{
+       struct sockaddr salocal;
+       struct sockaddr_in *sa;
+
+       rad_listen_t    **last;
+
+       /*
+        *      If the port is zero, then it means the appropriate
+        *      thing from /etc/services.
+        */
+       if (this->port == 0) {
+               struct servent  *svp;
+
+               switch (this->type) {
+               case RAD_LISTEN_AUTH:
+                       svp = getservbyname ("radius", "udp");
+                       if (svp != NULL) {
+                               this->port = ntohs(svp->s_port);
+                       } else {
+                               this->port = PW_AUTH_UDP_PORT;
+                       }
+                       break;
+
+               case RAD_LISTEN_ACCT:
+                       svp = getservbyname ("radacct", "udp");
+                       if (svp != NULL) {
+                               this->port = ntohs(svp->s_port);
+                       } else {
+                               this->port = PW_ACCT_UDP_PORT;
+                       }
+                       break;
+
+               default:
+                       radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind.");
+                       return -1;
+               }
+       }
+
+       /*
+        *      Find it in the old list, AFTER updating the port.  If
+        *      it's there, use that, rather than creating a new
+        *      socket.  This allows HUP's to re-use the old sockets,
+        *      which means that packets waiting in the socket queue
+        *      don't get lost.  */
+       for (last = &mainconfig.listen;
+            *last != NULL;
+            last = &((*last)->next)) {
+               if ((this->ipaddr == (*last)->ipaddr) &&
+                   (this->type == (*last)->type) &&
+                   (this->port == (*last)->port)) {
+                       this->fd = (*last)->fd;
+                       (*last)->fd = -1;
+                       return 0;
+               }
+       }
+
+       /*
+        *      Create the socket.
+        */
+       this->fd = socket(AF_INET, SOCK_DGRAM, 0);
+       if (this->fd < 0) {
                return -1;
        }
+       
 
+#ifdef WITH_UDPFROMTO
        /*
-        *      This allows us to figure out where, relative to
-        *      radiusd.conf, the other configuration files exist.
+        *      Initialize udpfromto for all sockets.
         */
-       cf_section_parse(cs, NULL, server_config);
+       if (udpfromto_init(this->fd) != 0) {
+               radlog(L_ERR|L_CONS, "ERROR: udpfromto init failed.");
+       }
+#endif
+
+       sa = (struct sockaddr_in *) &salocal;
+       memset ((char *) sa, '\0', sizeof(salocal));
+       sa->sin_family = AF_INET;
+       sa->sin_addr.s_addr = this->ipaddr;
+       sa->sin_port = htons(this->port);
+       
+       if (bind(this->fd, &salocal, sizeof(*sa)) < 0) {
+               close(this->fd);
+               this->fd = -1;
+               return -1;
+       }
+
+       return 0;
+}
+
+
+static int last_proxy_port = 0;
+
+/*
+ *     Externally visible function for creating a new proxy LISTENER.
+ *
+ *     For now, don't take ipaddr or port.
+ */
+int proxy_new_listener(void)
+{
+       int port;
+       rad_listen_t *this;
+
+       this = rad_malloc(sizeof(*this));
+
+       memset(this, 0, sizeof(*this));
+
+       this->ipaddr = mainconfig.myip;
+       this->type = RAD_LISTEN_PROXY;
 
-#if 0
        /*
-        *      Merge the old with the new.
+        *      Proxying was not previously defined: die.
         */
-       if (reload) {
-               CONF_SECTION *newcs;
-
-               newcs = cf_section_sub_find(cs, "modules");
-               oldcs = cf_section_sub_find(mainconfig.config, "modules");
-               if (newcs && oldcs) {
-                       if (!cf_section_migrate(newcs, oldcs)) {
-                               radlog(L_ERR|L_CONS, "Fatal error migrating configuration data");
-                               return -1;
+       if (last_proxy_port == 0) {
+               free(this);
+               return -1;
+       }
+
+       /*
+        *      Keep going until we find an unused port.
+        */
+       for (port = last_proxy_port + 1; port < 64000; port++) {
+               this->port = port;
+               if (listen_bind(this) == 0) {
+                       rad_listen_t **last;
+
+                       last_proxy_port = port;
+
+                       /*
+                        *      Add the new listener to the list of
+                        *      listeners.
+                        */
+                       for (last = &mainconfig.listen;
+                            *last != NULL;
+                            last = &((*last)->next)) {
+                               /* do nothing */
+                       }
+
+                       *last = this;
+                       return this->fd;
+               }
+       }
+
+       free(this);
+       return -1;
+}
+
+
+/*
+ *     Generate a list of listeners.  Takes an input list of
+ *     listeners, too, so we don't close sockets with waiting packets.
+ */
+static int listen_init(const char *filename, rad_listen_t **head)
+{
+       CONF_SECTION    *cs;
+       rad_listen_t    **last;
+       char            buffer[32];
+       rad_listen_t    *this;
+
+       /*
+        *      Add to the end of the list.
+        */
+       for (last = head; *last != NULL; last = &((*last)->next)) {
+               /* do nothing */
+       }
+
+       /*
+        *      Find the first one (if any).
+        */
+       for (cs = cf_subsection_find_next(mainconfig.config,
+                                         NULL, "listen");
+            cs != NULL;
+            cs = cf_subsection_find_next(mainconfig.config,
+                                         cs, "listen")) {
+               memset(&listen_inst, 0, sizeof(listen_inst));
+               
+               /*
+                *      Fix errors for later.
+                */
+               if (cf_section_parse(cs, &listen_inst, listen_config) < 0) {
+                       radlog(L_CONS|L_ERR, "%s[%d]: Error parsing listen section.",
+                              filename, cf_section_lineno(cs));
+                       return -1;
+               }
+
+               if (listen_type) {
+                       listen_inst.type = lrad_str2int(listen_compare,
+                                                       listen_type, 0);
+               }
+               if (listen_inst.type == RAD_LISTEN_NONE) {
+                       radlog(L_CONS|L_ERR, "%s[%d]: Invalid type in listen section.",
+                              filename, cf_section_lineno(cs));
+                       return -1;
+               }
+
+               this = rad_malloc(sizeof(*this));
+               memcpy(this, &listen_inst, sizeof(*this));
+               
+               /*
+                *      And bind it to the port.
+                */
+               if (listen_bind(this) < 0) {
+                       radlog(L_CONS|L_ERR, "%s[%d]: Error binding to port for %s:%d",
+                              filename, cf_section_lineno(cs),
+                              ip_ntoa(buffer, this->ipaddr), this->port);
+                       free(this);
+                       return -1;
+               }
+
+               *last = this;
+               last = &(this->next);           
+       }
+
+       /*
+        *      If we're proxying requests, open the proxy FD.
+        *      Otherwise, don't do anything.
+        */
+       if (mainconfig.proxy_requests == TRUE) {
+               int             port = -1;
+               rad_listen_t    *auth;
+               int             num_realms = 0;
+               int             localhost = 0;
+               int             otherhost = 0;
+               REALM           *realm;
+               uint32_t        proxy_ip;
+               uint32_t        ipaddr;
+
+               /*
+                *      If there are no realms configured, don't
+                *      open the proxy port.
+                */
+               for (realm = mainconfig.realms;
+                    realm != NULL;
+                    realm = realm->next) {
+                       /*
+                        *      Ignore LOCAL realms.
+                        */
+                       if ((realm->ipaddr == htonl(INADDR_NONE)) &&
+                           (realm->acct_ipaddr == htonl(INADDR_NONE))) {
+                               continue;
+                       }
+                       num_realms++;
+
+                       /*
+                        *      Loopback addresses
+                        */
+                       if (realm->ipaddr == htonl(INADDR_LOOPBACK)) {
+                               localhost = 1;
+                       } else {
+                               otherhost = 1;
+                       }
+                       if (realm->acct_ipaddr == htonl(INADDR_LOOPBACK)) {
+                               localhost = 1;
+                       } else {
+                               otherhost = 1;
+                       }
+               }
+
+               /*
+                *      No external realms.  Don't open another port.
+                */
+               if (num_realms == 0) {
+                       return 0;
+               }
+
+               /*
+                *      All of the realms are localhost, don't open
+                *      an external port.
+                */
+               if (localhost && !otherhost) {
+                       proxy_ip = htonl(INADDR_LOOPBACK);
+               } else {
+                       /*
+                        *      Multiple external realms, listen
+                        *      on any address that will send packets.
+                        */
+                       proxy_ip = htonl(INADDR_NONE);
+               }
+
+               /*
+                *      Find the first authentication port,
+                *      and use it
+                */
+               ipaddr = htonl(INADDR_NONE);
+               for (auth = *head; auth != NULL; auth = auth->next) {
+                       /*
+                        *      Listening on ANY, use that.
+                        */
+                       if (ipaddr != htonl(INADDR_ANY)) {
+                               /*
+                                *      Not set.  Pick the first one.
+                                *      Or, ANY, pick that.
+                                */
+                               if ((ipaddr == htonl(INADDR_NONE)) ||
+                                   (auth->ipaddr == htonl(INADDR_ANY))) {
+                                       ipaddr = auth->ipaddr;
+
+                                       /*
+                                        *      Else listening on multiple
+                                        *      IP's, use ANY for proxying.
+                                        */
+                               } else if (ipaddr != auth->ipaddr) {
+                                       ipaddr = htonl(INADDR_ANY);
+                               }
+                       }
+                       if (auth->type == RAD_LISTEN_AUTH) {
+                               port = auth->port + 2;
+                               break;
+                       }
+               }
+
+               /*
+                *      Not found, pick an accounting port.
+                */
+               if (port < 0) for (auth = *head; auth != NULL; auth = auth->next) {
+                       if (auth->type == RAD_LISTEN_ACCT) {
+                               port = auth->port + 1;
+                               break;
+                       }
+               }
+
+               /*
+                *      Still no port.  Don't do anything.
+                */
+               if (port < 0) {
+                       return 0;
+               }
+
+               this = rad_malloc(sizeof(*this));
+               memset(this, 0, sizeof(*this));
+
+               /*
+                *      More checks to do the right thing.
+                */
+               if (proxy_ip == htonl(INADDR_NONE)) {
+                       proxy_ip = ipaddr;
+               }
+               
+               /*
+                *      Create the proxy socket.
+                */
+               this->ipaddr = proxy_ip;
+               this->type = RAD_LISTEN_PROXY;
+
+               /*
+                *      Try to find a proxy port (value doesn't matter)
+                */
+               for (this->port = port;
+                    this->port < 64000;
+                    this->port++) {
+                       if (listen_bind(this) == 0) {
+                               last_proxy_port = this->port;
+                               *last = this;
+                               return 0;
                        }
                }
+
+               radlog(L_ERR|L_CONS, "Failed to open socket for proxying");
+               free(this);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*
+ *     Hack the OLD way of listening on a socket.
+ */
+static int old_listen_init(rad_listen_t **head)
+{
+       CONF_PAIR       *cp;
+       rad_listen_t    *this, **last;
+
+       /*
+        *      No "bind_address": all listen directives
+        *      are in the "listen" clauses.
+        */
+       cp = cf_pair_find(mainconfig.config, "bind_address");
+       if (!cp) return 0;
+       
+       last = head;
+
+       this = rad_malloc(sizeof(*this));
+       memset(this, 0, sizeof(*this));
+
+       /*
+        *      Create the authentication socket.
+        */
+               this->ipaddr = mainconfig.myip;
+       this->type = RAD_LISTEN_AUTH;
+       this->port = auth_port;
+
+       if (listen_bind(this) < 0) {
+               radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the authentication port %d", this->port);
+               free(this);
+               return -1;
        }
+       auth_port = this->port; /* may have been updated in listen_bind */
+       *last = this;
+       last = &(this->next);
+
+       /*
+        *  Open Accounting Socket.
+        *
+        *  If we haven't already gotten acct_port from /etc/services,
+        *  then make it auth_port + 1.
+        */
+       this = rad_malloc(sizeof(*this));
+       memset(this, 0, sizeof(*this));
+
+       /*
+        *      Create the accounting socket.
+        *
+        *      The accounting port is always the authentication port + 1
+        */
+               this->ipaddr = mainconfig.myip;
+       this->type = RAD_LISTEN_ACCT;
+       this->port = auth_port + 1;
+
+       if (listen_bind(this) < 0) {
+               radlog(L_CONS|L_ERR, "There appears to be another RADIUS server running on the accounting port %d", this->port);
+               free(this);
+               return -1;
+       }
+       *last = this;
+
+       return 0;
+}
+
+
+#ifndef RADIUS_CONFIG
+#define RADIUS_CONFIG "radiusd.conf"
 #endif
 
+CONF_SECTION *read_radius_conf_file(void)
+{
+       char buffer[256];
+       CONF_SECTION *cs;
+       struct stat statbuf;
+
+       if (stat(radius_dir, &statbuf) < 0) {
+               radlog(L_ERR|L_CONS, "Errors reading %s: %s",
+                      radius_dir, strerror(errno));
+               return NULL;
+       }
+
+       if ((statbuf.st_mode & S_IWOTH) != 0) {
+               radlog(L_ERR|L_CONS, "Configuration directory %s is globally writable.  Refusing to start due to insecure configuration.",
+                      radius_dir);
+         return NULL;
+       }
+
+
+       if (0 && (statbuf.st_mode & S_IROTH) != 0) {
+               radlog(L_ERR|L_CONS, "Configuration directory %s is globally readable.  Refusing to start due to insecure configuration.",
+                      radius_dir);
+               return NULL;
+       }
+
+       /* Lets go look for the new configuration files */
+       snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
+       if ((cs = conf_read(NULL, 0, buffer, NULL)) == NULL) {
+               return NULL;
+       }
+
+       /*
+        *      This allows us to figure out where, relative to
+        *      radiusd.conf, the other configuration files exist.
+        */
+       cf_section_parse(cs, NULL, server_config);
+
+       /* Initialize the dictionary */
+       DEBUG2("read_config_files:  reading dictionary");
+       if (dict_init(radius_dir, RADIUS_DICTIONARY) != 0) {
+               radlog(L_ERR|L_CONS, "Errors reading dictionary: %s",
+                               librad_errstr);
+               cf_section_free(&cs);
+               return NULL;
+       }
+
+       return cs;
+}
+
+
+/*
+ *     Read config files.
+ *
+ *     This function can ONLY be called from the main server process.
+ */
+int read_mainconfig(int reload)
+{
+       struct rlimit core_limits;
+       static int old_debug_level = -1;
+       char buffer[1024];
+       CONF_SECTION *cs, *oldcs;
+       rad_listen_t *listener;
+       RADCLIENT *c, *tail;
+
+       if (!reload) {
+               radlog(L_INFO, "Starting - reading configuration files ...");
+       } else {
+               radlog(L_INFO, "Reloading configuration files.");
+       }
+
+       /* First read radiusd.conf */
+       DEBUG2("reread_config:  reading radiusd.conf");
+       if ((cs = read_radius_conf_file()) == NULL) {
+               if (debug_flag ||
+                   (radlog_dir == NULL)) {
+                       radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
+               } else {
+                       radlog(L_ERR|L_CONS, "Errors reading %s/radiusd.conf: For more information, please read the tail end of %s", radius_dir, mainconfig.log_file);
+               }
+               return -1;
+       }
+
        /*
         *      Free the old configuration items, and replace them
         *      with the new ones.
@@ -832,37 +1323,76 @@ int read_mainconfig(int reload)
         *      Note that where possible, we do atomic switch-overs,
         *      to ensure that the pointers are always valid.
         */
-       cf_section_free(&mainconfig.config);
+       oldcs = mainconfig.config;
        mainconfig.config = cs;
+       cf_section_free(&oldcs);
 
-       snprintf(buffer, sizeof(buffer), "%.200s/%.50s",
-                radius_dir, mainconfig.radiusd_conf);
-       if (!realms_init(buffer)) {
+       /* old-style naslist file */
+       snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_NASLIST);
+       DEBUG2("read_config_files:  reading naslist");
+       if (read_naslist_file(buffer) < 0) {
+               radlog(L_ERR|L_CONS, "Errors reading naslist");
+               return -1;
+       }
+       /* old-style clients file */
+       snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CLIENTS);
+       DEBUG2("read_config_files:  reading clients");
+       if (read_clients_file(buffer) < 0) {
+               radlog(L_ERR|L_CONS, "Errors reading clients");
                return -1;
        }
 
        /*
-        *  Register the %{config:section.subsection} xlat function.
+        *      Add to that, the *new* list of clients.
         */
-       xlat_register("config", xlat_config, NULL);
+       snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
+       c = generate_clients(buffer, mainconfig.config);
+       if (!c) {
+               return -1;
+       }
 
        /*
-        *      Reload: change debug flag if it's changed in the
-        *      configuration file.
+        *      The new list of clients takes precedence over the old one.
         */
-       if (reload) {
-               if (mainconfig.debug_level != old_debug_level) {
-                       debug_flag = mainconfig.debug_level;
-               }
+       for (tail = c; tail->next != NULL; tail = tail->next) {
+         /* do nothing */
+       }
+       tail->next = mainconfig.clients;
+       mainconfig.clients = c;
+       
+       /* old-style realms file */
+       snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_REALMS);
+       DEBUG2("read_config_files:  reading realms");
+       if (read_realms_file(buffer) < 0) {
+               radlog(L_ERR|L_CONS, "Errors reading realms");
+               return -1;
+       }
 
-       } else if (debug_flag == 0) {
+       /*
+        *      If there isn't any realms it isn't fatal..
+        */
+       snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
+       if (generate_realms(buffer) < 0) {
+               return -1;
+       }
 
-               /*
-                *      Starting the server, WITHOUT "-x" on the
-                *      command-line: use whatever's in the config
-                *      file.
-                */
-               debug_flag = mainconfig.debug_level;
+       /*
+        *  Register the %{config:section.subsection} xlat function.
+        */
+       xlat_register("config", xlat_config, NULL);
+
+       /*
+        *      Set the libraries debugging flag to whatever the main
+        *      flag is.  Note that on a SIGHUP, to turn the debugging
+        *      off, we do other magic.
+        *
+        *      Increase the debug level, if the configuration file
+        *      says to, OR, if we're decreasing the debug from what it
+        *      was before, allow that, too.
+        */
+       if ((mainconfig.debug_level > debug_flag) ||
+           (mainconfig.debug_level <= old_debug_level)) {
+         debug_flag = mainconfig.debug_level;
        }
        librad_debug = debug_flag;
        old_debug_level = mainconfig.debug_level;
@@ -872,6 +1402,43 @@ int read_mainconfig(int reload)
         *  changes.
         */
 
+       /*  Get the current maximum for core files.  */
+       if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
+               radlog(L_ERR|L_CONS, "Failed to get current core limit:  %s", strerror(errno));
+               exit(1);
+       }
+
+       if (mainconfig.allow_core_dumps) {
+               if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
+                       radlog(L_ERR|L_CONS, "Cannot update core dump limit: %s",
+                                       strerror(errno));
+                       exit(1);
+
+                       /*
+                        *  If we're running as a daemon, and core
+                        *  dumps are enabled, log that information.
+                        */
+               } else if ((core_limits.rlim_cur != 0) && !debug_flag)
+                       radlog(L_INFO|L_CONS, "Core dumps are enabled.");
+
+       } else if (!debug_flag) {
+               /*
+                *  Not debugging.  Set the core size to zero, to
+                *  prevent security breaches.  i.e. People
+                *  reading passwords from the 'core' file.
+                */
+               struct rlimit limits;
+
+               limits.rlim_cur = 0;
+               limits.rlim_max = core_limits.rlim_max;
+
+               if (setrlimit(RLIMIT_CORE, &limits) < 0) {
+                       radlog(L_ERR|L_CONS, "Cannot disable core dumps: %s",
+                                       strerror(errno));
+                       exit(1);
+               }
+       }
+
        /*
         *      The first time around, ensure that we can write to the
         *      log directory.
@@ -883,12 +1450,19 @@ int read_mainconfig(int reload)
                 */
                radlogdir_iswritable(mainconfig.uid_name);
        }
-
-       /*
-        *      We should really switch users earlier in the process.
-        */
        switch_users();
 
+#ifdef HAVE_SYS_PRCTL_H
+#ifdef HAVE_PR_SET_DUMPABLE
+       if (mainconfig.allow_core_dumps) {
+               if (prctl(PR_SET_DUMPABLE, 1) < 0) {
+                       radlog(L_ERR|L_CONS,"Cannot enable core dumps: prctl(PR_SET_DUMPABLE) failed: '%s'",
+                              strerror(errno));
+               }
+       }
+#endif
+#endif
+
        /*
         *      Sanity check the configuration for internal
         *      consistency.
@@ -896,18 +1470,19 @@ int read_mainconfig(int reload)
        if (mainconfig.reject_delay > mainconfig.cleanup_delay) {
                mainconfig.reject_delay = mainconfig.cleanup_delay;
        }
-       if (mainconfig.reject_delay < 0) mainconfig.reject_delay = 0;
 
        /*
         *      Initialize the old "bind_address" and "port", first.
         */
        listener = NULL;
+       if (old_listen_init(&listener) < 0) {
+               exit(1);
+       }
 
        /*
         *      Read the list of listeners.
         */
-       snprintf(buffer, sizeof(buffer), "%.200s/%.50s",
-                radius_dir, mainconfig.radiusd_conf);
+       snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", radius_dir);
        if (listen_init(buffer, &listener) < 0) {
                exit(1);
        }
@@ -917,62 +1492,14 @@ int read_mainconfig(int reload)
                exit(1);
        }
 
-       listen_free(&mainconfig.listen);
+       listen_free(mainconfig.listen);
        mainconfig.listen = listener;
 
-       /*
-        *      Walk through the listeners.  If we're listening on acct
-        *      or auth, read in the clients files, else ignore them.
-        */
-       for (listener = mainconfig.listen;
-            listener != NULL;
-            listener = listener->next) {
-               if ((listener->type == RAD_LISTEN_AUTH) ||
-                   (listener->type == RAD_LISTEN_ACCT)) {
-                       break;
-               }
-       }
-
-       if (listener != NULL) {
-               RADCLIENT_LIST *clients;
-
-               /*
-                *      Create the new clients first, and add them
-                *      to the CONF_SECTION, where they're automagically
-                *      freed if anything goes wrong.
-                */
-               snprintf(buffer, sizeof(buffer), "%.200s/%.50s",
-                        radius_dir, mainconfig.radiusd_conf);
-               clients = clients_parse_section(buffer, mainconfig.config);
-               if (!clients) {
-                       return -1;
-               }
-
-               /*
-                *      The old clients are already NULL, because they
-                *      are in a configuration section, and the client
-                *      "free" function was added by clients parse
-                *      section, above.
-                *
-                *      Note that because we require at least one
-                *      client in the main configuration file, any
-                *      clients added by SQL will be inserted into
-                *      that, and automatically freed.
-                */
-               mainconfig.clients = clients;
-       }
-
-       /*  Reload the modules.  */
-       DEBUG2("radiusd:  entering modules setup");
-       if (setup_modules(reload) < 0) {
-               radlog(L_ERR|L_CONS, "Errors setting up modules");
-               return -1;
-       }
        return 0;
 }
 
 /*
- *     Free the configuration.  Called only when the server is exiting.
+ *     Free the configuration.
  */
 int free_mainconfig(void)
 {
@@ -981,9 +1508,13 @@ int free_mainconfig(void)
         *      structures.
         */
        cf_section_free(&mainconfig.config);
-       free(mainconfig.radiusd_conf);
-       realms_free();
-       listen_free(&mainconfig.listen);
+       realm_free(mainconfig.realms);
+       clients_free(mainconfig.clients);
+       read_naslist_file(NULL);
+
+       rl_free();
+       listen_free(mainconfig.listen);
+       paircompare_builtin_free();
        xlat_free();
        dict_free();
        lt_dlexit();
index 9231e7f..7179143 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modpriv.h>
-#include <freeradius-devel/modcall.h>
-#include <freeradius-devel/rad_assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "conffile.h"
+#include "modpriv.h"
+#include "modules.h"
+#include "modcall.h"
 
 /* mutually-recursive static functions need a prototype up front */
-static modcallable *do_compile_modgroup(modcallable *,
-                                       int, CONF_SECTION *, const char *,
-                                       int, int);
+static modcallable *do_compile_modgroup(int, CONF_SECTION *, const char *,
+               int, int);
 
 /* Actions may be a positive integer (the highest one returned in the group
  * will be returned), or the keyword "return", represented here by
  * MOD_ACTION_RETURN, to cause an immediate return.
  * There's also the keyword "reject", represented here by MOD_ACTION_REJECT
  * to cause an immediate reject. */
-#define MOD_ACTION_RETURN  (-1)
-#define MOD_ACTION_REJECT  (-2)
+#define MOD_ACTION_RETURN (-1)
+#define MOD_ACTION_REJECT (-2)
 
 /* Here are our basic types: modcallable, modgroup, and modsingle. For an
  * explanation of what they are all about, see ../../doc/README.failover */
 struct modcallable {
-       modcallable *parent;
        struct modcallable *next;
        const char *name;
-       int lineno;
        int actions[RLM_MODULE_NUMCODES];
-       enum { MOD_SINGLE, MOD_GROUP, MOD_LOAD_BALANCE, MOD_REDUNDANT_LOAD_BALANCE, MOD_IF, MOD_ELSE, MOD_ELSIF } type;
+       enum { MOD_SINGLE, MOD_GROUP, MOD_LOAD_BALANCE, MOD_REDUNDANT_LOAD_BALANCE  } type;
 };
 
 #define GROUPTYPE_SIMPLE       0
@@ -58,8 +57,8 @@ struct modcallable {
 #define GROUPTYPE_COUNT                3
 
 typedef struct {
-       modcallable mc;         /* self */
-       int grouptype;  /* after mc */
+       modcallable mc;
+       int grouptype;
        modcallable *children;
 } modgroup;
 
@@ -68,6 +67,7 @@ typedef struct {
        module_instance_t *modinst;
 } modsingle;
 
+
 static const LRAD_NAME_NUMBER grouptype_table[] = {
        { "", GROUPTYPE_SIMPLE },
        { "redundant ", GROUPTYPE_REDUNDANT },
@@ -84,11 +84,8 @@ static modsingle *mod_callabletosingle(modcallable *p)
 }
 static modgroup *mod_callabletogroup(modcallable *p)
 {
-       rad_assert((p->type==MOD_GROUP) || /* this is getting silly... */
+       rad_assert((p->type==MOD_GROUP) ||
                   (p->type==MOD_LOAD_BALANCE) ||
-                  (p->type==MOD_IF) ||
-                  (p->type==MOD_ELSE) ||
-                  (p->type==MOD_ELSIF) ||
                   (p->type==MOD_REDUNDANT_LOAD_BALANCE));
        return (modgroup *)p;
 }
@@ -117,7 +114,6 @@ static void add_child(modgroup *g, modcallable *c)
 
        rad_assert(c->next == NULL);
        *last = c;
-       c->parent = mod_grouptocallable(g);
 }
 
 /* Here's where we recognize all of our keywords: first the rcodes, then the
@@ -142,7 +138,15 @@ static const LRAD_NAME_NUMBER rcode_table[] = {
 static int compile_action(modcallable *c, const char *attr, const char *value,
                          const char *filename, int lineno)
 {
-       int action;
+       int rcode, action;
+
+       rcode = lrad_str2int(rcode_table, attr, -1);
+       if (rcode < 0) {
+               radlog(L_ERR|L_CONS,
+                      "%s[%d] Unknown module rcode '%s'.\n",
+                      filename, lineno, attr);
+               return 0;
+       }
 
        if (!strcasecmp(value, "return"))
                action = MOD_ACTION_RETURN;
@@ -152,7 +156,7 @@ static int compile_action(modcallable *c, const char *attr, const char *value,
 
        else if (strspn(value, "0123456789")==strlen(value)) {
                action = atoi(value);
-
+               
                /*
                 *      Don't allow priority zero, for future use.
                 */
@@ -164,31 +168,26 @@ static int compile_action(modcallable *c, const char *attr, const char *value,
                return 0;
        }
 
-       if (strcasecmp(attr, "default") != 0) {
-               int rcode;
-
-               rcode = lrad_str2int(rcode_table, attr, -1);
-               if (rcode < 0) {
-                       radlog(L_ERR|L_CONS,
-                              "%s[%d] Unknown module rcode '%s'.\n",
-                              filename, lineno, attr);
-                       return 0;
-               }
-               c->actions[rcode] = action;
-
-       } else {                /* set all unset values to the default */
-               int i;
-
-               for (i = 0; i < RLM_MODULE_NUMCODES; i++) {
-                       if (!c->actions[i]) c->actions[i] = action;
-               }
-       }
+       c->actions[rcode] = action;
 
        return 1;
 }
 
+#if 0
+static const char *action2str(int action)
+{
+       static char buf[32];
+       if(action==MOD_ACTION_RETURN)
+               return "return";
+       if(action==MOD_ACTION_REJECT)
+               return "reject";
+       snprintf(buf, sizeof buf, "%d", action);
+       return buf;
+}
+#endif
+
 /* Some short names for debugging output */
-static const char * const comp2str[] = {
+static const char *comp2str[] = {
        "authenticate",
        "authorize",
        "preacct",
@@ -234,16 +233,8 @@ static int call_modsingle(int component, modsingle *sp, REQUEST *request,
               comp2str[component], sp->modinst->name,
               sp->modinst->entry->name, request->number);
        safe_lock(sp->modinst);
-
-       /*
-        *      For logging unresponsive children.
-        */
-       request->module = sp->modinst->name;
-
        myresult = sp->modinst->entry->module->methods[component](
                        sp->modinst->insthandle, request);
-
-       request->module = "<server-core>";
        safe_unlock(sp->modinst);
        DEBUG3("  modsingle[%s]: returned from %s (%s) for request %d",
               comp2str[component], sp->modinst->name,
@@ -253,377 +244,342 @@ static int call_modsingle(int component, modsingle *sp, REQUEST *request,
 }
 
 
-static int default_component_results[RLM_COMPONENT_COUNT] = {
-       RLM_MODULE_REJECT,      /* AUTH */
-       RLM_MODULE_NOTFOUND,    /* AUTZ */
-       RLM_MODULE_NOOP,        /* PREACCT */
-       RLM_MODULE_NOOP,        /* ACCT */
-       RLM_MODULE_FAIL,        /* SESS */
-       RLM_MODULE_NOOP,        /* PRE_PROXY */
-       RLM_MODULE_NOOP,        /* POST_PROXY */
-       RLM_MODULE_NOOP         /* POST_AUTH */
-};
-
-static const char *group_name[] = {
-       "",
-       "group",
-       "load-balance group",
-       "redundant-load-balance group",
-       "if",
-       "else",
-       "elsif"
-};
-
-static const char *modcall_spaces = "++++++++++++++++++++++++++++++++";
-
-#define MODCALL_STACK_MAX (32)
-
 /*
- *     Don't call the modules recursively.  Instead, do them
- *     iteratively, and manage the call stack ourselves.
+ *     Helper function for call_modgroup, and call_modredundantloadbalance
+ *
+ *     Returns 0 for "stop", and "1" for continue.
  */
-typedef struct modcall_stack {
-       int pointer;
+static int call_one(int component, modcallable *p, REQUEST *request,
+                   int *priority, int *result)
+{
+       int r;
 
-       int priority[MODCALL_STACK_MAX];
-       int result[MODCALL_STACK_MAX];
-       modcallable *children[MODCALL_STACK_MAX];
-       modcallable *start[MODCALL_STACK_MAX];
-} modcall_stack;
+#ifdef RAD_REQUEST_OPTION_STOP_NOW
+       /*
+        *      A module has taken too long to process the request,
+        *      and we've been told to stop processing it.
+        */
+       if (request->options & RAD_REQUEST_OPTION_STOP_NOW) {
+               *result = RLM_MODULE_FAIL;
+               return 0;
+       }
+#endif
+       
+       /* Call this child by recursing into modcall */
+       r = modcall(component, p, request);
+       
+#if 0
+       DEBUG2("%s: action for %s is %s",
+              comp2str[component], lrad_int2str(rcode_table, r, "??"),
+              action2str(p->actions[r]));
+#endif
+       
+       /*
+        *      Find an action to go with the child's result. If it is
+        *      "return", break out of the loop so the rest of the
+        *      children in the list will be skipped.
+        */
+       if (p->actions[r] == MOD_ACTION_RETURN) {
+               *result = r;
+               return 0;
+       }
+       
+       /* If "reject" break out of the loop and return reject */
+       if (p->actions[r] == MOD_ACTION_REJECT) {
+               *result = RLM_MODULE_REJECT;
+               return 0;
+       }
+       
+       /*
+        *      Otherwise, the action is a number, the preference
+        *      level of this return code. If no higher preference has
+        *      been seen yet, remember this one
+        . */
+       if (p->actions[r] >= *priority) {
+               *result = r;
+               *priority = p->actions[r];
+       }
+       
+       return 1;
+}
 
 
-/*
- *     Call a module, iteratively, with a local stack, rather than
- *     recursively.  What did Paul Graham say about Lisp...?
- */
-int modcall(int component, modcallable *c, REQUEST *request)
+static int call_modgroup(int component, modgroup *g, REQUEST *request,
+                        int default_result)
 {
-       int myresult;
-       modcall_stack stack;
-       modcallable *parent, *child;
-       modsingle *sp;
-       int if_taken, was_if;
-
-       stack.pointer = 0;
+       int myresult = default_result;
+       int priority = 0;       /* default result has lowest priority  */
+       modcallable *p;
 
-       if ((component < 0) || (component >= RLM_COMPONENT_COUNT)) {
-               return RLM_MODULE_FAIL;
+       /*
+        *      Catch people who have issues.
+        */
+       if (!g->children) {
+               DEBUG2("  WARNING! Asked to process empty group.  Returning %s.", lrad_int2str(rcode_table, myresult, "??"));
+               return default_result;
        }
 
-       if (!c) {
-               return default_component_results[component];
+       /* Loop over the children */
+       for (p = g->children; p; p = p->next) {
+               if (!call_one(component, p, request, &priority, &myresult)) {
+                       break;
+               }
        }
 
-       stack.priority[0] = 0;
-       stack.children[0] = c;
-       myresult = stack.result[0] = default_component_results[component];
-       was_if = if_taken = FALSE;
+       return myresult;
+}
 
-       while (1) {
-               /*
-                *      A module has taken too long to process the request,
-                *      and we've been told to stop processing it.
-                */
-               if (request->master_state == REQUEST_STOP_PROCESSING) {
-                       myresult = RLM_MODULE_FAIL;
-                       break;
-               }
+static int call_modloadbalance(int component, modgroup *g, REQUEST *request,
+                              int default_result)
+{
+       int count = 1;
+       modcallable *p, *child = NULL;
 
-               child = stack.children[stack.pointer];
-               rad_assert(child != NULL);
-               parent = child->parent;
-
-               if ((child->type == MOD_ELSE) || (child->type == MOD_ELSIF)) {
-                       if (!was_if) { /* error */
-                               DEBUG2("%.*s ... skipping %s for request %d: No preceding \"if\"",
-                                      stack.pointer + 1, modcall_spaces,
-                                      group_name[child->type],
-                                      request->number);
-                               goto unroll;
-                       }
-                       if (if_taken) {
-                               DEBUG2("%.*s ... skipping %s for request %d: Preceding \"if\" was taken",
-                                      stack.pointer + 1, modcall_spaces,
-                                      group_name[child->type],
-                                      request->number);
-                               goto unroll;
-                       }
+       /*
+        *      Catch people who have issues.
+        */
+       if (!g->children) {
+               DEBUG2("  WARNING! Asked to process empty load-balance group.  Returning %s.", lrad_int2str(rcode_table, default_result, "??"));
+               return default_result;
+       }
+
+       /*
+        *      Pick a random child.
+        */
+
+       /* Loop over the children */
+       for(p = g->children; p; p = p->next) {
+               if (!child) {
+                       child = p;
+                       count = 1;
+                       continue;
                }
 
                /*
-                *      "if", and the requested action wasn't the
-                *      proper return code, skip the group.
+                *      Keep track of how many load balancing servers
+                *      we've gone through.
                 */
-               if (((child->type == MOD_IF) || (child->type == MOD_ELSIF)) &&
-                   !child->actions[myresult]) {
-                       DEBUG2("%.*s ... skipping %s \"%s\" for request %d, return code was %s",
-                              stack.pointer + 1, modcall_spaces,
-                              group_name[child->type],
-                              child->name, request->number,
-                              lrad_int2str(rcode_table, myresult, "??"));
-                       stack.children[stack.pointer] = NULL;
-                       was_if = TRUE;
-                       if_taken = FALSE;
-                       goto unroll;
-               } /* else process it, as a simple group */
+               count++;
 
                /*
-                *      Child is a group that has children of it's own.
+                *      See the "camel book" for why this works.
+                *
+                *      If (rand(0..n) < 1), pick the current realm.
+                *      We add a scale factor of 65536, to avoid
+                *      floating point.
                 */
-               if (child->type != MOD_SINGLE) {
-                       int count = 1;
-                       modcallable *p, *q;
-                       modgroup *g = mod_callabletogroup(child);
-
-                       stack.pointer++;
-
-                       /*
-                        *      Catastrophic error.  This SHOULD have
-                        *      been caught when we were reading in the
-                        *      conf files.
-                        *
-                        *      FIXME: Do so.
-                        */
-                       if (stack.pointer >= MODCALL_STACK_MAX) {
-                               radlog(L_ERR, "Internal sanity check failed: module stack is too deep");
-                               exit(1);
-                       }
-
-                       stack.priority[stack.pointer] = 0;
-                       stack.result[stack.pointer] = default_component_results[component];
-                       switch (child->type) {
-                       case MOD_IF:
-                       case MOD_ELSE:
-                       case MOD_ELSIF:
-                       case MOD_GROUP:
-                               stack.children[stack.pointer] = g->children;
-                               break;
-
-                               /*
-                                *      See the "camel book" for why
-                                *      this works.
-                                *
-                                *      If (rand(0..n) < 1), pick the
-                                *      current realm.  We add a scale
-                                *      factor of 65536, to avoid
-                                *      floating point.
-                                */
-                       case MOD_LOAD_BALANCE:
-                       case MOD_REDUNDANT_LOAD_BALANCE:
-                               q = NULL;
-                               for(p = g->children; p; p = p->next) {
-                                       if (!q) {
-                                               q = p;
-                                               count = 1;
-                                               continue;
-                                       }
-
-                                       count++;
-
-                                       if ((count * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
-                                               q = p;
-                                       }
-                               }
-                               stack.children[stack.pointer] = q;
-                               break;
+               if ((count * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
+                       child = p;
+               }
+       }
+       rad_assert(child != NULL);
 
-                       default:
-                               exit(1); /* internal sanity check failure */
-                               break;
-                       }
+       /* Call the chosen child by recursing into modcall */
+       return modcall(component, child, request);
+}
 
 
-                       stack.start[stack.pointer] = stack.children[stack.pointer];
+/*
+ *     For more than 2 modules with redundancy + load balancing
+ *     across all of them, layering the "redundant" and
+ *     "load-balance" groups gets too complicated.  As a result, we
+ *     implement a special function to do this.
+ */
+static int call_modredundantloadbalance(int component, modgroup *g, REQUEST *request,
+                                       int default_result)
+{
+       int count = 1;
+       int myresult = default_result;
+       int priority = 0;       /* default result has lowest priority  */
+       modcallable *p, *child = NULL;
 
-                       DEBUG2("%.*s- entering %s %s",
-                              stack.pointer, modcall_spaces,
-                              group_name[child->type], child->name);
+       /*
+        *      Catch people who have issues.
+        */
+       if (!g->children) {
+               DEBUG2("  WARNING! Asked to process empty redundant-load-balance group.  Returning %s.", lrad_int2str(rcode_table, default_result, "??"));
+               return default_result;
+       }
 
-                       /*
-                        *      Catch the special case of a NULL group.
-                        */
-                       if (!stack.children[stack.pointer]) {
-                               /*
-                                *      Print message for NULL group
-                                */
-                               DEBUG2("%.*s- %s returns %s",
-                                      stack.pointer + 1, modcall_spaces,
-                                      comp2str[component],
-                                      lrad_int2str(rcode_table,
-                                                   stack.result[stack.pointer],
-                                                   "??"));
-                               goto do_return;
-                       }
+       /*
+        *      Pick a random child.
+        */
 
-                       /*
-                        *      The child may be a group, so we want to
-                        *      recurse into it's children, rather than
-                        *      falling through to the code below.
-                        */
+       /* Loop over the children */
+       for(p = g->children; p; p = p->next) {
+               if (!child) {
+                       child = p;
+                       count = 1;
                        continue;
                }
 
                /*
-                *      Process a stand-alone child, and fall through
-                *      to dealing with it's parent.
+                *      Keep track of how many load balancing servers
+                *      we've gone through.
                 */
-               sp = mod_callabletosingle(child);
-
-               myresult = call_modsingle(component, sp, request,
-                                         default_component_results[component]);
-               DEBUG2("%.*s[%s] returns %s",
-                      stack.pointer + 1, modcall_spaces,
-                      child->name,
-                      lrad_int2str(rcode_table, myresult, "??"));
-
+               count++;
 
                /*
-                *      FIXME: Allow modules to push a modcallable
-                *      onto this stack.  This should simplify
-                *      configuration a LOT!
-                *
-                *      Once we do that, we can't do load-time
-                *      checking of the maximum stack depth, and we've
-                *      got to cache the stack pointer before storing
-                *      myresult.
+                *      See the "camel book" for why this works.
                 *
-                *      Also, if the stack changed, we need to set
-                *      children[ptr] to NULL, and process the next
-                *      entry on the stack, rather than falling
-                *      through to finalize the processing of this
-                *      entry.
-                *
-                *      Don't put "myresult" on the stack here,
-                *      we have to do so with priority.
-                */
-
-               /*
-                *      We roll back up the stack at this point.
-                */
-       unroll:
-               /*
-                *      The child's action says return.  Do so.
+                *      If (rand(0..n) < 1), pick the current realm.
+                *      We add a scale factor of 65536, to avoid
+                *      floating point.
                 */
-               if (child->actions[myresult] == MOD_ACTION_RETURN) {
-                       stack.result[stack.pointer] = myresult;
-                       stack.children[stack.pointer] = NULL;
-                       goto do_return;
+               if ((count * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
+                       child = p;
                }
+       }
+       rad_assert(child != NULL);
 
+       /*
+        *      Call the chosen child, with fail-over to the next one
+        *      if it is down.
+        */
+       p = child;
+       do {
                /*
-                *      If "reject", break out of the loop and return
-                *      reject.
+                *      Call the chosen entry.  If we're done, then
+                *      stop.
                 */
-               if (child->actions[myresult] == MOD_ACTION_REJECT) {
-                       stack.children[stack.pointer] = NULL;
-                       stack.result[stack.pointer] = RLM_MODULE_REJECT;
-                       goto do_return;
+               if (!call_one(component, p, request, &priority, &myresult)) {
+                       break;
                }
-
+               
                /*
-                *      Otherwise, the action is a number, the
-                *      preference level of this return code. If no
-                *      higher preference has been seen yet, remember
-                *      this one.
+                *      Go to the next one, and wrap around to the beginning if
+                *      we reach the end.
                 */
-               if (child->actions[myresult] >= stack.priority[stack.pointer]) {
-                       stack.result[stack.pointer] = myresult;
-                       stack.priority[stack.pointer] = child->actions[myresult];
-               }
+               p = p->next;
+               if (!p) p = g->children;
+       } while (p != child);
 
-               /*
-                *      No parent, we must be done.
-                */
-               if (!parent) {
-                       rad_assert(stack.pointer == 0);
-                       myresult = stack.result[0];
-                       break;
-               }
+       /*
+        *      And return whatever was decided.
+        */
+       return myresult;
+}
 
-               rad_assert(child != NULL);
+int modcall(int component, modcallable *c, REQUEST *request)
+{
+       int myresult;
 
-               /*
-                *      Go to the "next" child, whatever that is.
-                */
-               switch (parent->type) {
-                       case MOD_IF:
-                       case MOD_ELSE:
-                       case MOD_ELSIF:
-                       case MOD_GROUP:
-                               stack.children[stack.pointer] = child->next;
-                               break;
-
-                       case MOD_LOAD_BALANCE:
-                               stack.children[stack.pointer] = NULL;
-                               break;
-
-                       case MOD_REDUNDANT_LOAD_BALANCE:
-                               if (child->next) {
-                                       stack.children[stack.pointer] = child->next;
-                               } else {
-                                       modgroup *g = mod_callabletogroup(parent);
-
-                                       stack.children[stack.pointer] = g->children;
-                               }
-                               if (stack.children[stack.pointer] == stack.start[stack.pointer]) {
-                                       stack.children[stack.pointer] = NULL;
-                               }
-                               break;
-                       default:
-                               exit(1);
-               }
+       /* Choose a default return value appropriate for the component */
+       switch(component) {
+       case RLM_COMPONENT_AUTZ:
+               myresult = RLM_MODULE_NOTFOUND;
+               break;
+       case RLM_COMPONENT_AUTH:
+               myresult = RLM_MODULE_REJECT;
+               break;
+       case RLM_COMPONENT_PREACCT:
+               myresult = RLM_MODULE_NOOP;
+               break;
+       case RLM_COMPONENT_ACCT:
+               myresult = RLM_MODULE_NOOP;
+               break;
+       case RLM_COMPONENT_SESS:
+               myresult = RLM_MODULE_FAIL;
+               break;
+       case RLM_COMPONENT_PRE_PROXY:
+               myresult = RLM_MODULE_NOOP;
+               break;
+       case RLM_COMPONENT_POST_PROXY:
+               myresult = RLM_MODULE_NOOP;
+               break;
+       case RLM_COMPONENT_POST_AUTH:
+               myresult = RLM_MODULE_NOOP;
+               break;
+       default:
+               myresult = RLM_MODULE_FAIL;
+               break;
+       }
 
-               /*
-                *      No child, we're done this group, and we return
-                *      "myresult" to the caller by pushing it back up
-                *      the stack.
-                */
-               if (!stack.children[stack.pointer]) {
-               do_return:
-                       rad_assert(stack.pointer > 0);
-                       myresult = stack.result[stack.pointer];
-                       stack.pointer--;
-
-                       DEBUG2("%.*s- %s %s returns %s",
-                              stack.pointer + 1, modcall_spaces,
-                              group_name[parent->type], parent->name,
-                              lrad_int2str(rcode_table, myresult, "??"));
-
-                       if (stack.pointer == 0) break;
-
-                       if ((parent->type == MOD_IF) ||
-                           (parent->type == MOD_ELSIF)) {
-                               if_taken = was_if = TRUE;
-                       } else {
-                               if_taken = was_if = FALSE;
-                       }
+       if(c == NULL) {
+               DEBUG2("modcall[%s]: NULL object returns %s for request %d",
+                      comp2str[component],
+                      lrad_int2str(rcode_table, myresult, "??"),
+                      request->number);
+               return myresult;
+       }
 
-                       /*
-                        *      Unroll the stack.
-                        */
-                       child = stack.children[stack.pointer];
-                       parent = child->parent;
-                       goto unroll;
+       switch (c->type) {
+       case MOD_LOAD_BALANCE:
+               {
+                       modgroup *g = mod_callabletogroup(c);
+                       
+                       DEBUG2("modcall: entering load-balance group %s for request %d",
+                              c->name, request->number);
+                       
+                       myresult = call_modloadbalance(component, g, request,
+                                                      myresult);
+                       
+                       DEBUG2("modcall: load-balance group %s returns %s for request %d",
+                              c->name,
+                              lrad_int2str(rcode_table, myresult, "??"),
+                              request->number);
+               }
+               break;
+               
+       case MOD_REDUNDANT_LOAD_BALANCE:
+               {
+                       modgroup *g = mod_callabletogroup(c);
+                       
+                       DEBUG2("modcall: entering redundant-load-balance group %s for request %d",
+                              c->name, request->number);
+                       
+                       myresult = call_modredundantloadbalance(component, g, request,
+                                                               myresult);
+                       
+                       DEBUG2("modcall: redundant-load-balance group %s returns %s for request %d",
+                              c->name,
+                              lrad_int2str(rcode_table, myresult, "??"),
+                              request->number);
+               }
+               break;
+               
+       case MOD_GROUP:
+               {
+                       modgroup *g = mod_callabletogroup(c);
+                       
+                       DEBUG2("modcall: entering group %s%s for request %d",
+                              lrad_int2str(grouptype_table, g->grouptype, ""),
+                              c->name, request->number);
+                       
+                       myresult = call_modgroup(component, g, request,
+                                                myresult);
+                       
+                       DEBUG2("modcall: leaving group %s%s (returns %s) for request %d",
+                              lrad_int2str(grouptype_table, g->grouptype, ""),
+                              c->name,
+                              lrad_int2str(rcode_table, myresult, "??"),
+                              request->number);
+               }
+               break;
+               
+       case MOD_SINGLE:
+               {
+                       modsingle *sp = mod_callabletosingle(c);
+                       
+                       myresult = call_modsingle(component, sp, request,
+                                                 myresult);
+                       
+                       DEBUG2("  modcall[%s]: module \"%s\" returns %s for request %d",
+                              comp2str[component], c->name,
+                              lrad_int2str(rcode_table, myresult, "??"),
+                              request->number);
                }
+               break;
 
-       } /* loop until done */
+       default:
+               radlog(L_ERR, "Internal error processing module entry");
+               break;
+       }
 
        return myresult;
 }
 
-
 #if 0
-static const char *action2str(int action)
-{
-       static char buf[32];
-       if(action==MOD_ACTION_RETURN)
-               return "return";
-       if(action==MOD_ACTION_REJECT)
-               return "reject";
-       snprintf(buf, sizeof buf, "%d", action);
-       return buf;
-}
-
 /* If you suspect a bug in the parser, you'll want to use these dump
  * functions. dump_tree should reproduce a whole tree exactly as it was found
  * in radiusd.conf, but in long form (all actions explicitly defined) */
@@ -638,8 +594,7 @@ static void dump_mc(modcallable *c, int indent)
        } else {
                modgroup *g = mod_callabletogroup(c);
                modcallable *p;
-               DEBUG("%.*s%s {", indent, "\t\t\t\t\t\t\t\t\t\t\t",
-                     group_name[c->type]);
+               DEBUG("%.*sgroup {", indent, "\t\t\t\t\t\t\t\t\t\t\t");
                for(p = g->children;p;p = p->next)
                        dump_mc(p, indent+1);
        }
@@ -659,7 +614,10 @@ static void dump_tree(int comp, modcallable *c)
        dump_mc(c, 0);
 }
 #else
-#define dump_tree(a, b)
+static void dump_tree(int comp UNUSED, modcallable *c UNUSED)
+{
+       return;
+}
 #endif
 
 /* These are the default actions. For each component, the group{} block
@@ -983,54 +941,7 @@ defaultactions[RLM_COMPONENT_COUNT][GROUPTYPE_COUNT][RLM_MODULE_NUMCODES] =
 };
 
 
-static int condition2actions(modcallable *mc, const char *actions)
-{
-       char *p, *q;
-       char buffer[1024];
-
-       if (strlen(actions) >= sizeof(buffer)) {
-               return -1;
-       }
-
-       memset(mc->actions, 0, sizeof(mc->actions));
-
-       /*
-        *      Copy, stripping space.
-        */
-       p = buffer;
-       while (*actions) {
-               if (*actions != ' ') {
-                       *(p++) = *actions;
-               }
-               actions++;
-       }
-       *p = '\0';
-
-       p = buffer;
-
-       while (*p) {
-               int rcode;
-
-               q = strchr(p, '|');
-               if (q) *q = '\0';
-
-               rcode = lrad_str2int(rcode_table, p, -1);
-               if (rcode < 0) return -1;
-               mc->actions[rcode] = 1;
-
-               if (!q) break;
-               p = q + 1;
-       }
-
-       return 0;
-}
-
-
-/*
- *     Compile one entry of a module call.
- */
-static modcallable *do_compile_modsingle(modcallable *parent,
-                                        int component, CONF_ITEM *ci,
+static modcallable *do_compile_modsingle(int component, CONF_ITEM *ci,
                                         const char *filename, int grouptype,
                                         const char **modname)
 {
@@ -1056,130 +967,31 @@ static modcallable *do_compile_modsingle(modcallable *parent,
                 */
                if (strcmp(modrefname, "group") == 0) {
                        *modname = name2;
-                       return do_compile_modgroup(parent, component, cs,
-                                                  filename,
-                                                  GROUPTYPE_SIMPLE,
-                                                  grouptype);
+                       return do_compile_modgroup(component, cs, filename,
+                                       GROUPTYPE_SIMPLE, grouptype);
                } else if (strcmp(modrefname, "redundant") == 0) {
                        *modname = name2;
-                       return do_compile_modgroup(parent, component, cs,
-                                                  filename,
-                                                  GROUPTYPE_REDUNDANT,
-                                                  grouptype);
+                       return do_compile_modgroup(component, cs, filename,
+                                       GROUPTYPE_REDUNDANT, grouptype);
                } else if (strcmp(modrefname, "append") == 0) {
                        *modname = name2;
-                       return do_compile_modgroup(parent, component, cs,
-                                                  filename,
-                                                  GROUPTYPE_APPEND,
-                                                  grouptype);
+                       return do_compile_modgroup(component, cs, filename,
+                                       GROUPTYPE_APPEND, grouptype);
                } else if (strcmp(modrefname, "load-balance") == 0) {
                        *modname = name2;
-                       csingle= do_compile_modgroup(parent, component, cs,
-                                                    filename,
-                                                    GROUPTYPE_SIMPLE,
-                                                    grouptype);
+                       csingle= do_compile_modgroup(component, cs, filename,
+                                       GROUPTYPE_SIMPLE, grouptype);
                        if (!csingle) return NULL;
                        csingle->type = MOD_LOAD_BALANCE;
                        return csingle;
                } else if (strcmp(modrefname, "redundant-load-balance") == 0) {
                        *modname = name2;
-                       csingle= do_compile_modgroup(parent, component, cs,
-                                                    filename,
-                                                    GROUPTYPE_REDUNDANT,
-                                                    grouptype);
+                       csingle= do_compile_modgroup(component, cs, filename,
+                                       GROUPTYPE_REDUNDANT, grouptype);
                        if (!csingle) return NULL;
                        csingle->type = MOD_REDUNDANT_LOAD_BALANCE;
                        return csingle;
-               } else  if (strcmp(modrefname, "if") == 0) {
-                       if (!cf_section_name2(cs)) {
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] 'if' without condition.\n",
-                                      filename, lineno);
-                               return NULL;
-                       }
-
-                       *modname = name2;
-                       csingle= do_compile_modgroup(parent, component, cs,
-                                                    filename,
-                                                    GROUPTYPE_SIMPLE,
-                                                    grouptype);
-                       if (!csingle) return NULL;
-                       csingle->type = MOD_IF;
-
-                       if (condition2actions(csingle, name2) < 0) {
-                               modcallable_free(&csingle);
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] Invalid module condition rcode '%s'.\n",
-                                      filename, lineno, name2);
-                               return NULL;
-                       }
-
-                       return csingle;
-               } else  if (strcmp(modrefname, "elsif") == 0) {
-                       if (parent &&
-                           ((parent->type == MOD_LOAD_BALANCE) ||
-                            (parent->type == MOD_REDUNDANT_LOAD_BALANCE))) {
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] 'elsif' cannot be used in this section section.\n",
-                                      filename, lineno);
-                               return NULL;
-                       }
-
-                       if (!cf_section_name2(cs)) {
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] 'elsif' without condition.\n",
-                                      filename, lineno);
-                               return NULL;
-                       }
-
-                       *modname = name2;
-                       csingle= do_compile_modgroup(parent, component, cs,
-                                                    filename,
-                                                    GROUPTYPE_SIMPLE,
-                                                    grouptype);
-                       if (!csingle) return NULL;
-                       csingle->type = MOD_ELSIF;
-
-                       if (condition2actions(csingle, name2) < 0) {
-                               modcallable_free(&csingle);
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] Invalid module condition rcode '%s'.\n",
-                                      filename, lineno, name2);
-                               return NULL;
-                       }
-
-                       return csingle;
-               } else  if (strcmp(modrefname, "else") == 0) {
-                       if (parent &&
-                           ((parent->type == MOD_LOAD_BALANCE) ||
-                            (parent->type == MOD_REDUNDANT_LOAD_BALANCE))) {
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] 'else' cannot be used in this section section.\n",
-                                      filename, lineno);
-                               return NULL;
-                       }
-
-                       if (cf_section_name2(cs)) {
-                               radlog(L_ERR|L_CONS,
-                                      "%s[%d] Cannot have conditions on 'else'.\n",
-                                      filename, lineno);
-                               return NULL;
-                       }
-
-                       *modname = name2;
-                       csingle= do_compile_modgroup(parent, component, cs,
-                                                    filename,
-                                                    GROUPTYPE_SIMPLE,
-                                                    grouptype);
-                       if (!csingle) return NULL;
-                       csingle->type = MOD_ELSE;
-                       return csingle;
                }
-
-               /*
-                *      Else it's a module reference, with updated return
-                *      codes.
-                */
        } else {
                CONF_PAIR *cp = cf_itemtopair(ci);
                lineno = cf_pair_lineno(cp);
@@ -1187,37 +999,13 @@ static modcallable *do_compile_modsingle(modcallable *parent,
        }
 
        /*
-        *      See if the module is a virtual one.  If so, return that,
-        *      rather than doing anything here.
+        *      FIXME: See if the module is a virtual one.  If so,
+        *      return that, rather than doing anything here.
         */
-       this = find_module_instance(cf_section_find("modules"), modrefname);
-       if (!this) {
-               CONF_SECTION *cs, *subcs;
-
-               /*
-                *      Then, look for it in the "instantiate" section.
-                */
-               if (((subcs = cf_section_find(NULL)) != NULL) &&
-                   ((cs = cf_section_sub_find_name2(subcs, "instantiate", NULL)) != NULL)) {
-                       subcs = cf_section_sub_find_name2(cs, NULL, modrefname);
-                       if (subcs) {
-                               /*
-                                *      As it's sole configuration, the
-                                *      virtual module takes a section which
-                                *      contains the
-                                */
-                               return do_compile_modsingle(parent,
-                                                           component,
-                                                           cf_sectiontoitem(subcs),
-                                                           filename,
-                                                           grouptype,
-                                                           modname);
-                       }
-               }
-       }
+       this = find_module_instance(modrefname);
        if (!this) {
                *modname = NULL;
-               radlog(L_ERR|L_CONS, "%s[%d] Failed to find module \"%s\".", filename,
+               radlog(L_ERR|L_CONS, "%s[%d] Unknown module \"%s\".", filename,
                       lineno, modrefname);
                return NULL;
        }
@@ -1227,11 +1015,8 @@ static modcallable *do_compile_modsingle(modcallable *parent,
         *      them in.
         */
        single = rad_malloc(sizeof(*single));
-       memset(single, 0, sizeof(*single));
        csingle = mod_singletocallable(single);
-       csingle->parent = parent;
        csingle->next = NULL;
-       csingle->lineno = lineno;
        memcpy(csingle->actions, defaultactions[component][grouptype],
               sizeof csingle->actions);
        rad_assert(modrefname != NULL);
@@ -1281,9 +1066,9 @@ static modcallable *do_compile_modsingle(modcallable *parent,
         */
        if (!this->entry->module->methods[component]) {
                radlog(L_ERR|L_CONS,
-                      "%s[%d]: \"%s\" modules aren't allowed in '%s' sections -- they have no such method.",
-                      filename, lineno, this->entry->module->name,
-                      comp2str[component]);
+                      "%s: \"%s\" modules aren't allowed in '%s' sections -- they have no such method.",
+                      filename, this->entry->module->name,
+                      component_names[component]);
                modcallable_free(&csingle);
                return NULL;
        }
@@ -1293,41 +1078,31 @@ static modcallable *do_compile_modsingle(modcallable *parent,
        return csingle;
 }
 
-modcallable *compile_modsingle(modcallable *parent,
-                              int component, CONF_ITEM *ci,
+modcallable *compile_modsingle(int component, CONF_ITEM *ci,
                               const char *filename, const char **modname)
 {
-       modcallable *ret = do_compile_modsingle(parent, component, ci,
-                                               filename,
+       modcallable *ret = do_compile_modsingle(component, ci, filename,
                                                GROUPTYPE_SIMPLE,
                                                modname);
        dump_tree(component, ret);
        return ret;
 }
 
-
-/*
- *     Internal compile group code.
- */
-static modcallable *do_compile_modgroup(modcallable *parent,
-                                       int component, CONF_SECTION *cs,
+static modcallable *do_compile_modgroup(int component, CONF_SECTION *cs,
                                        const char *filename, int grouptype,
                                        int parentgrouptype)
 {
-       int i;
        modgroup *g;
        modcallable *c;
        CONF_ITEM *ci;
 
-       g = rad_malloc(sizeof(*g));
-       memset(g, 0, sizeof(*g));
+       g = rad_malloc(sizeof *g);
        g->grouptype = grouptype;
 
        c = mod_grouptocallable(g);
-       c->parent = parent;
        c->next = NULL;
-       c->lineno = cf_section_lineno(cs);
-       memset(c->actions, 0, sizeof(c->actions));
+       memcpy(c->actions, defaultactions[component][parentgrouptype],
+              sizeof(c->actions));
 
        /*
         *      Remember the name for printing, etc.
@@ -1340,18 +1115,11 @@ static modcallable *do_compile_modgroup(modcallable *parent,
        c->type = MOD_GROUP;
        g->children = NULL;
 
-       /*
-        *      Loop over the children of this group.
-        */
        for (ci=cf_item_find_next(cs, NULL);
             ci != NULL;
             ci=cf_item_find_next(cs, ci)) {
 
-               /*
-                *      Sections are references to other groups, or
-                *      to modules with updated return codes.
-                */
-               if (cf_item_is_section(ci)) {
+               if(cf_item_is_section(ci)) {
                        const char *junk = NULL;
                        modcallable *single;
                        int lineno;
@@ -1359,8 +1127,7 @@ static modcallable *do_compile_modgroup(modcallable *parent,
 
                        lineno = cf_section_lineno(subcs);
 
-                       single = do_compile_modsingle(c, component, ci,
-                                                     filename,
+                       single = do_compile_modsingle(component, ci, filename,
                                                      grouptype, &junk);
                        if (!single) {
                                radlog(L_ERR|L_CONS,
@@ -1390,12 +1157,9 @@ static modcallable *do_compile_modgroup(modcallable *parent,
                                modcallable *single;
                                const char *junk = NULL;
 
-                               single = do_compile_modsingle(c,
-                                                             component,
-                                                             cf_pairtoitem(cp),
-                                                             filename,
-                                                             grouptype,
-                                                             &junk);
+                               single = do_compile_modsingle(component,
+                                               cf_pairtoitem(cp), filename,
+                                               grouptype, &junk);
                                if (!single) {
                                        radlog(L_ERR|L_CONS,
                                               "%s[%d] Failed to parse \"%s\" entry.\n",
@@ -1417,26 +1181,15 @@ static modcallable *do_compile_modgroup(modcallable *parent,
        }
 
        /*
-        *      Set the default actions, if they haven't already been
-        *      set.
-        */
-       for (i = 0; i < RLM_MODULE_NUMCODES; i++) {
-               if (!c->actions[i]) {
-                       c->actions[i] = defaultactions[component][parentgrouptype][i];
-               }
-       }
-
-       /*
         *      FIXME: If there are no children, return NULL?
         */
        return mod_grouptocallable(g);
 }
 
-modcallable *compile_modgroup(modcallable *parent,
-                             int component, CONF_SECTION *cs,
-                             const char *filename)
+modcallable *compile_modgroup(int component, CONF_SECTION *cs,
+               const char *filename)
 {
-       modcallable *ret = do_compile_modgroup(parent, component, cs, filename,
+       modcallable *ret = do_compile_modgroup(component, cs, filename,
                                               GROUPTYPE_SIMPLE,
                                               GROUPTYPE_SIMPLE);
        dump_tree(component, ret);
@@ -1444,17 +1197,16 @@ modcallable *compile_modgroup(modcallable *parent,
 }
 
 void add_to_modcallable(modcallable **parent, modcallable *this,
-                       int component, const char *name)
+                       int component, char *name)
 {
        modgroup *g;
-
+       
        rad_assert(this != NULL);
 
        if (*parent == NULL) {
                modcallable *c;
 
                g = rad_malloc(sizeof *g);
-               memset(g, 0, sizeof(*g));
                g->grouptype = GROUPTYPE_SIMPLE;
                c = mod_grouptocallable(g);
                c->next = NULL;
index d0e343f..987fe36 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2000  Alan Curry <pacman@world.std.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modpriv.h>
-#include <freeradius-devel/modcall.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modpriv.h"
+#include "modules.h"
+#include "modcall.h"
+#include "conffile.h"
+#include "ltdl.h"
+#include "rad_assert.h"
+
+/*
+ *     Internal list of all of the modules we have loaded.
+ */
+static module_list_t *module_list = NULL;
+
+/*
+ *     Internal list of each module instance.
+ */
+static module_instance_t *module_instance_list = NULL;
 
 typedef struct indexed_modcallable {
-       int comp;
+       struct indexed_modcallable *next;
        int idx;
        modcallable *modulelist;
 } indexed_modcallable;
@@ -39,141 +58,148 @@ typedef struct indexed_modcallable {
 /*
  *     For each component, keep an ordered list of ones to call.
  */
-static rbtree_t *components;
-
-static rbtree_t *module_tree = NULL;
-
-typedef struct section_type_value_t {
-       const char      *section;
-       const char      *typename;
-       int             attr;
-} section_type_value_t;
-
+static indexed_modcallable *components[RLM_COMPONENT_COUNT];
 
 /*
- *     Ordered by component
+ *     The component names.
+ *
+ *     Hmm... we probably should be getting these from the configuration
+ *     file, too.
  */
-static const section_type_value_t section_type_value[RLM_COMPONENT_COUNT] = {
-       { "authenticate", "Auth-Type",       PW_AUTH_TYPE },
-       { "authorize",    "Autz-Type",       PW_AUTZ_TYPE },
-       { "preacct",      "Pre-Acct-Type",   PW_PRE_ACCT_TYPE },
-       { "accounting",   "Acct-Type",       PW_ACCT_TYPE },
-       { "session",      "Session-Type",    PW_SESSION_TYPE },
-       { "pre-proxy",    "Pre-Proxy-Type",  PW_PRE_PROXY_TYPE },
-       { "post-proxy",   "Post-Proxy-Type", PW_POST_PROXY_TYPE },
-       { "post-auth",    "Post-Auth-Type",  PW_POST_AUTH_TYPE },
+const char *component_names[RLM_COMPONENT_COUNT] =
+{
+       "authenticate",
+       "authorize",
+       "preacct",
+       "accounting",
+       "session",
+       "pre-proxy",
+       "post-proxy",
+       "post-auth"
 };
 
 /*
  *     Delete ASAP.
  */
-static const section_type_value_t old_section_type_value[] = {
-       { "authenticate", "authtype", PW_AUTH_TYPE },
-       { "authorize",    "autztype", PW_AUTZ_TYPE },
-       { "preacct",      "Pre-Acct-Type",   PW_PRE_ACCT_TYPE },/* unused */
-       { "accounting",   "acctype", PW_ACCT_TYPE },
-       { "session",      "sesstype", PW_SESSION_TYPE },
-       { "pre-proxy",    "Pre-Proxy-Type",  PW_PRE_PROXY_TYPE }, /* unused */
-       { "post-proxy",   "Post-Proxy-Type", PW_POST_PROXY_TYPE }, /* unused */
-       { "post-auth",    "post-authtype", PW_POST_AUTH_TYPE }
+static const char *old_subcomponent_names[RLM_COMPONENT_COUNT] =
+{
+       "authtype",
+       "autztype",
+       "preacctype",
+       "acctype",
+       "sesstype",
+       "pre-proxytype",
+       "post-proxytype",
+       "post-authtype"
 };
 
-
-static void indexed_modcallable_free(void *data)
+static const char *subcomponent_names[RLM_COMPONENT_COUNT] =
 {
-       indexed_modcallable *c = data;
-
-       modcallable_free(&c->modulelist);
-       free(c);
-}
+       "Auth-Type",
+       "Autz-Type",
+       "Pre-Acct-Type",
+       "Acct-Type",
+       "Session-Type",
+       "Pre-Proxy-Type",
+       "Post-Proxy-Type",
+       "Post-Auth-Type"
+};
 
-static int indexed_modcallable_cmp(const void *one, const void *two)
+static void indexed_modcallable_free(indexed_modcallable **cf)
 {
-       const indexed_modcallable *a = one;
-       const indexed_modcallable *b = two;
-
-       if (a->comp < b->comp) return -1;
-       if (a->comp >  b->comp) return +1;
+       indexed_modcallable     *c, *next;
 
-       return a->idx - b->idx;
+       c = *cf;
+       while (c) {
+               next = c->next;
+               modcallable_free(&c->modulelist);
+               free(c);
+               c = next;
+       }
+       *cf = NULL;
 }
 
-
-/*
- *     Free a module instance.
- */
-static void module_instance_free(void *data)
+static void instance_list_free(module_instance_t **i)
 {
-       module_instance_t *this = data;
+       module_instance_t       *c, *next;
 
-       if (this->entry->module->detach)
-               (this->entry->module->detach)(this->insthandle);
+       c = *i;
+       while (c) {
+               next = c->next;
+               if(c->entry->module->detach)
+                       (c->entry->module->detach)(c->insthandle);
 #ifdef HAVE_PTHREAD_H
-       if (this->mutex) {
-               /*
-                *      FIXME
-                *      The mutex MIGHT be locked...
-                *      we'll check for that later, I guess.
-                */
-               pthread_mutex_destroy(this->mutex);
-               free(this->mutex);
-       }
+               if (c->mutex) {
+                       /*
+                        *      FIXME
+                        *      The mutex MIGHT be locked...
+                        *      we'll check for that later, I guess.
+                        */
+                       pthread_mutex_destroy(c->mutex);
+                       free(c->mutex);
+               }
 #endif
-       free(this);
+               free(c);
+               c = next;
+       }
+       *i = NULL;
 }
 
-
 /*
- *     Compare two module entries
+ *     Remove all of the modules.
  */
-static int module_entry_cmp(const void *one, const void *two)
+int detach_modules(void)
 {
-       const module_entry_t *a = one;
-       const module_entry_t *b = two;
+       module_list_t *ml, *next;
+       int i;
 
-       return strcmp(a->name, b->name);
-}
+       /*
+        *      Delete the internal component pointers.
+        */
+       for (i = 0; i < RLM_COMPONENT_COUNT; i++) {
+               indexed_modcallable_free(&components[i]);
+       }
 
-/*
- *     Free a module entry.
- */
-static void module_entry_free(void *data)
-{
-       module_entry_t *this = data;
-
-       lt_dlclose(this->handle);       /* ignore any errors */
-       free(this);
-}
+       instance_list_free(&module_instance_list);
 
+       ml = module_list;
+       while (ml) {
+               next = ml->next;
+               if (ml->module->destroy)
+                       (ml->module->destroy)();
+               lt_dlclose(ml->handle); /* ignore any errors */
+               free(ml);
+               ml = next;
+       }
 
-/*
- *     Remove the module lists.
- */
-int detach_modules(void)
-{
-       rbtree_free(components);
-       rbtree_free(module_tree);
+       module_list = NULL;
 
        return 0;
 }
 
-
 /*
  *     Find a module on disk or in memory, and link to it.
  */
-static module_entry_t *linkto_module(const char *module_name,
-                                    const char *cffilename, int cflineno)
+static module_list_t *linkto_module(const char *module_name,
+               const char *cffilename, int cflineno)
 {
-       module_entry_t myentry;
-       module_entry_t *node;
+       module_list_t *node;
        lt_dlhandle handle;
        char module_struct[256];
        char *p;
-       const void *module;
 
-       strlcpy(myentry.name, module_name, sizeof(myentry.name));
-       node = rbtree_finddata(module_tree, &myentry);
-       if (node) return node;
+       /*
+        *      Look through the global module library list for the
+        *      named module.
+        */
+       for (node = module_list; node != NULL; node = node->next) {
+               /*
+                *      Found the named module.  Return it.
+                */
+               if (strcmp(node->name, module_name) == 0)
+                       return node;
+
+       }
 
        /*
         *      Keep the handle around so we can dlclose() it.
@@ -181,81 +207,95 @@ static module_entry_t *linkto_module(const char *module_name,
        handle = lt_dlopenext(module_name);
        if (handle == NULL) {
                radlog(L_ERR|L_CONS, "%s[%d] Failed to link to module '%s':"
-                      " %s\n", cffilename, cflineno, module_name, lt_dlerror());
+                               " %s\n", cffilename, cflineno, module_name, lt_dlerror());
                return NULL;
        }
 
+       /* make room for the module type */
+       node = (module_list_t *) rad_malloc(sizeof(module_list_t));
+
+       /* fill in the module structure */
+       node->next = NULL;
+       node->handle = handle;
+       strNcpy(node->name, module_name, sizeof(node->name));
+
        /*
         *      Link to the module's rlm_FOO{} module structure.
-        *
-        *      The module_name variable has the version number
-        *      embedded in it, and we don't want that here.
         */
+       /* module_name has the version embedded; strip it. */
        strcpy(module_struct, module_name);
        p = strrchr(module_struct, '-');
-       if (p) *p = '\0';
-
-       DEBUG3("    (Loaded %s, checking if it's valid)", module_name);
-
-       /*
-        *      libltld MAY core here, if the handle it gives us contains
-        *      garbage data.
-        */
-       module = lt_dlsym(handle, module_struct);
-       if (!module) {
+       if (p)
+               *p = '\0';
+       node->module = (module_t *) lt_dlsym(node->handle, module_struct);
+       if (!node->module) {
                radlog(L_ERR|L_CONS, "%s[%d] Failed linking to "
                                "%s structure in %s: %s\n",
                                cffilename, cflineno,
                                module_name, cffilename, lt_dlerror());
-               lt_dlclose(handle);
-               return NULL;
-       }
-       /*
-        *      Before doing anything else, check if it's sane.
-        */
-       if ((*(const uint32_t *) module) != RLM_MODULE_MAGIC_NUMBER) {
-               lt_dlclose(handle);
-               radlog(L_ERR|L_CONS, "%s[%d] Invalid version in module '%s'",
-                      cffilename, cflineno, module_name);
+               lt_dlclose(node->handle);       /* ignore any errors */
+               free(node);
                return NULL;
-
        }
 
-       /* make room for the module type */
-       node = rad_malloc(sizeof(*node));
-       memset(node, 0, sizeof(*node));
-       strlcpy(node->name, module_name, sizeof(node->name));
-       node->module = module;
-       node->handle = handle;
-
-       DEBUG(" Module: Linked to module %s", module_name);
-
-       /*
-        *      Add the module as "rlm_foo-version" to the configuration
-        *      section.
-        */
-       if (!rbtree_insert(module_tree, node)) {
-               radlog(L_ERR, "Failed to cache module %s", module_name);
-               lt_dlclose(handle);
+       /* call the modules initialization */
+       if (node->module->init && (node->module->init)() < 0) {
+               radlog(L_ERR|L_CONS, "%s[%d] Module initialization failed.\n",
+                               cffilename, cflineno);
+               lt_dlclose(node->handle);       /* ignore any errors */
                free(node);
                return NULL;
        }
 
+       DEBUG("Module: Loaded %s ", node->module->name);
+
+       node->next = module_list;
+       module_list = node;
+
        return node;
 }
 
 /*
  *     Find a module instance.
  */
-module_instance_t *find_module_instance(CONF_SECTION *modules,
-                                       const char *instname)
+module_instance_t *find_module_instance(const char *instname)
 {
-       CONF_SECTION *cs;
+       CONF_SECTION *cs, *inst_cs;
        const char *name1, *name2;
-       module_instance_t *node;
+       module_instance_t *node, **last;
        char module_name[256];
 
-       if (!modules) return NULL;
+       /*
+        *      Look through the global module instance list for the
+        *      named module.
+        */
+       last = &module_instance_list;
+       for (node = module_instance_list; node != NULL; node = node->next) {
+               /*
+                *      Found the named instance.  Return it.
+                */
+               if (strcmp(node->name, instname) == 0)
+                       return node;
+
+               /*
+                *      Keep a pointer to the last entry to update...
+                */
+               last = &node->next;
+       }
+
+       /*
+        *      Instance doesn't exist yet. Try to find the
+        *      corresponding configuration section and create it.
+        */
+
+       /*
+        *      Look for the 'modules' configuration section.
+        */
+       cs = cf_section_find("modules");
+       if (cs == NULL) {
+               radlog(L_ERR|L_CONS, "ERROR: Cannot find a 'modules' section in the configuration file.\n");
+               return NULL;
+       }
 
        /*
         *      Module instances are declared in the modules{} block
@@ -263,55 +303,64 @@ module_instance_t *find_module_instance(CONF_SECTION *modules,
         *      name2 from the config section, or name1 if there was
         *      no name2.
         */
-       cs = cf_section_sub_find_name2(modules, NULL, instname);
-       if (cs == NULL) {
+       name1 = name2 = NULL;
+       for(inst_cs=cf_subsection_find_next(cs, NULL, NULL);
+                       inst_cs != NULL;
+                       inst_cs=cf_subsection_find_next(cs, inst_cs, NULL)) {
+               name1 = cf_section_name1(inst_cs);
+               name2 = cf_section_name2(inst_cs);
+               if ( (name2 && !strcmp(name2, instname)) ||
+                    (!name2 && !strcmp(name1, instname)) )
+                       break;
+       }
+       if (inst_cs == NULL) {
                radlog(L_ERR|L_CONS, "ERROR: Cannot find a configuration entry for module \"%s\".\n", instname);
                return NULL;
        }
 
        /*
-        *      If there's already a module instance, return it.
-        */
-       node = cf_data_find(cs, "instance");
-       if (node) return node;
-
-       name1 = cf_section_name1(cs);
-       name2 = cf_section_name2(cs);
-
-       /*
         *      Found the configuration entry.
         */
        node = rad_malloc(sizeof(*node));
-       memset(node, 0, sizeof(*node));
-
+       node->next = NULL;
        node->insthandle = NULL;
 
        /*
-        *      Names in the "modules" section aren't prefixed
-        *      with "rlm_", so we add it here.
+        *      Link to the module by name: rlm_FOO-major.minor
         */
-       snprintf(module_name, sizeof(module_name), "rlm_%s", name1);
+       if (strncmp(name1, "rlm_", 4)) {
+#if 0
+               snprintf(module_name, sizeof(module_name), "rlm_%s-%d.%d",
+                        name1, RADIUSD_MAJOR_VERSION, RADIUSD_MINOR_VERSION);
+#else
+               snprintf(module_name, sizeof(module_name), "rlm_%s",
+                        name1);
+#endif
+       } else {
+               strNcpy(module_name, name1, sizeof(module_name));
+
+       }
 
-       node->entry = linkto_module(module_name,
-                                   mainconfig.radiusd_conf,
-                                   cf_section_lineno(cs));
+       /*
+        *  FIXME: "radiusd.conf" is wrong here; must find cf filename
+        */
+       node->entry = linkto_module(module_name, "radiusd.conf",
+                                   cf_section_lineno(inst_cs));
        if (!node->entry) {
                free(node);
                /* linkto_module logs any errors */
                return NULL;
        }
 
-       DEBUG2(" Module: Instantiating %s", instname);
-
        /*
         *      Call the module's instantiation routine.
         */
        if ((node->entry->module->instantiate) &&
-           ((node->entry->module->instantiate)(cs, &node->insthandle) < 0)) {
+           ((node->entry->module->instantiate)(inst_cs,
+                       &node->insthandle) < 0)) {
                radlog(L_ERR|L_CONS,
-                               "%s[%d]: %s: Module instantiation failed.\n",
-                      mainconfig.radiusd_conf, cf_section_lineno(cs),
-                      instname);
+                               "radiusd.conf[%d]: %s: Module instantiation failed.\n",
+                               cf_section_lineno(inst_cs), instname);
                free(node);
                return NULL;
        }
@@ -320,7 +369,7 @@ module_instance_t *find_module_instance(CONF_SECTION *modules,
         *      We're done.  Fill in the rest of the data structure,
         *      and link it to the module instance list.
         */
-       strlcpy(node->name, instname, sizeof(node->name));
+       strNcpy(node->name, instname, sizeof(node->name));
 
 #ifdef HAVE_PTHREAD_H
        /*
@@ -342,148 +391,146 @@ module_instance_t *find_module_instance(CONF_SECTION *modules,
        }
 
 #endif
-       cf_data_add(cs, "instance", node, module_instance_free);
+       *last = node;
+
+       DEBUG("Module: Instantiated %s (%s) ", name1, node->name);
 
        return node;
 }
 
-static indexed_modcallable *lookup_by_index(int comp, int idx)
+static indexed_modcallable *lookup_by_index(indexed_modcallable *head, int idx)
 {
-       indexed_modcallable myc;
-
-       myc.comp = comp;
-       myc.idx = idx;
+       indexed_modcallable *p;
 
-       return rbtree_finddata(components, &myc);
+       for (p = head; p != NULL; p = p->next) {
+               if( p->idx == idx)
+                       return p;
+       }
+       return NULL;
 }
 
-/*
- *     Create a new sublist.
- */
 static indexed_modcallable *new_sublist(int comp, int idx)
 {
-       indexed_modcallable *c;
-
-       c = lookup_by_index(comp, idx);
-
-       /* It is an error to try to create a sublist that already
-        * exists. It would almost certainly be caused by accidental
-        * duplication in the config file.
-        *
-        * index 0 is the exception, because it is used when we want
-        * to collect _all_ listed modules under a single index by
-        * default, which is currently the case in all components
-        * except authenticate. */
-       if (c) {
-               if (idx == 0) {
-                       return c;
+       indexed_modcallable **head = &components[comp];
+       indexed_modcallable *node = *head;
+       indexed_modcallable **last = head;
+
+       while (node) {
+               /* It is an error to try to create a sublist that already
+                * exists. It would almost certainly be caused by accidental
+                * duplication in the config file.
+                *
+                * index 0 is the exception, because it is used when we want
+                * to collect _all_ listed modules under a single index by
+                * default, which is currently the case in all components
+                * except authenticate. */
+               if (node->idx == idx) {
+                       if (idx == 0)
+                               return node;
+                       else
+                               return NULL;
                }
-               return NULL;
-       }
-
-       c = rad_malloc(sizeof(*c));
-       c->modulelist = NULL;
-       c->comp = comp;
-       c->idx = idx;
-
-       if (!rbtree_insert(components, c)) {
-               free(c);
-               return NULL;
+               last = &node->next;
+               node = node->next;
        }
 
-       return c;
+       node = rad_malloc(sizeof *node);
+       node->next = NULL;
+       node->modulelist = NULL;
+       node->idx = idx;
+       *last = node;
+       return node;
 }
 
 static int indexed_modcall(int comp, int idx, REQUEST *request)
 {
-       int rcode;
        indexed_modcallable *this;
 
-       this = lookup_by_index(comp, idx);
+       this = lookup_by_index(components[comp], idx);
        if (!this) {
                if (idx != 0) DEBUG2("  ERROR: Unknown value specified for %s.  Cannot perform requested action.",
-                                    section_type_value[comp].typename);
-               request->component = section_type_value[comp].typename;
-               rcode = modcall(comp, NULL, request); /* does default action */
-       } else {
-               DEBUG2("  Processing the %s section of %s",
-                      section_type_value[comp].section,
-                      mainconfig.radiusd_conf);
-               request->component = section_type_value[comp].typename;
-               rcode = modcall(comp, this->modulelist, request);
+                                    subcomponent_names[comp]);
+               /* Return a default value appropriate for the component */
+               switch(comp) {
+                       case RLM_COMPONENT_AUTZ:    return RLM_MODULE_NOTFOUND;
+                       case RLM_COMPONENT_AUTH:    return RLM_MODULE_REJECT;
+                       case RLM_COMPONENT_PREACCT: return RLM_MODULE_NOOP;
+                       case RLM_COMPONENT_ACCT:    return RLM_MODULE_NOOP;
+                       case RLM_COMPONENT_SESS:    return RLM_MODULE_FAIL;
+                       case RLM_COMPONENT_PRE_PROXY:  return RLM_MODULE_NOOP;
+                       case RLM_COMPONENT_POST_PROXY: return RLM_MODULE_NOOP;
+                       case RLM_COMPONENT_POST_AUTH:  return RLM_MODULE_NOOP;
+                       default:                    return RLM_MODULE_FAIL;
+               }
        }
-       request->module = "<server-core>";
-       request->component = "<server-core>";
-       return rcode;
+
+       DEBUG2("  Processing the %s section of radiusd.conf",
+              component_names[comp]);
+       return modcall(comp, this->modulelist, request);
 }
 
-/*
- *     Load a sub-module list, as found inside an Auth-Type foo {}
- *     block
- */
-static int load_subcomponent_section(modcallable *parent,
-                                    CONF_SECTION *cs, int comp,
-                                    const char *filename)
+/* Load a flat module list, as found inside an authtype{} block */
+static int load_subcomponent_section(CONF_SECTION *cs, int comp,
+                                     const char *filename)
 {
+       int idx;
        indexed_modcallable *subcomp;
        modcallable *ml;
        DICT_VALUE *dval;
-       const char *name2 = cf_section_name2(cs);
 
-       rad_assert(comp >= RLM_COMPONENT_AUTH);
-       rad_assert(comp <= RLM_COMPONENT_COUNT);
+       static int meaningless_counter = 1;
 
-       /*
-        *      Sanity check.
-        */
-       if (!name2) {
-               radlog(L_ERR|L_CONS,
-                      "%s[%d]: No name specified for %s block",
-                      filename, cf_section_lineno(cs),
-                      section_type_value[comp].typename);
-               return 1;
-       }
-
-       /*
-        *      Compile the group.
-        */
-       ml = compile_modgroup(parent, comp, cs, filename);
+       ml = compile_modgroup(comp, cs, filename);
        if (!ml) {
                return 0;
        }
 
-       /*
-        *      We must assign a numeric index to this subcomponent.
-        *      It is generated and placed in the dictionary by
-        *      setup_modules(), when it loads the sections.  If it
-        *      isn't found, it's a serious error.
-        */
-       dval = dict_valbyname(section_type_value[comp].attr, name2);
-       if (!dval) {
-               radlog(L_ERR|L_CONS,
-                      "%s[%d] %s %s Not previously configured",
-                      filename, cf_section_lineno(cs),
-                      section_type_value[comp].typename, name2);
-               modcallable_free(&ml);
-               return 0;
+       /* We must assign a numeric index to this subcomponent. For
+        * auth, it is generated and placed in the dictionary by
+        * new_sectiontype_value(). The others are just numbers that are pulled
+        * out of thin air, and the names are neither put into the dictionary
+        * nor checked for uniqueness, but all that could be fixed in a few
+        * minutes, if anyone finds a real use for indexed config of
+        * components other than auth. */
+       dval = NULL;
+       if (comp==RLM_COMPONENT_AUTH) {
+               dval = dict_valbyname(PW_AUTH_TYPE, cf_section_name2(cs));
+       } else if (comp == RLM_COMPONENT_AUTZ) {
+               dval = dict_valbyname(PW_AUTZ_TYPE, cf_section_name2(cs));
+       } else if (comp == RLM_COMPONENT_ACCT) {
+               dval = dict_valbyname(PW_ACCT_TYPE, cf_section_name2(cs));
+       } else if (comp == RLM_COMPONENT_SESS) {
+               dval = dict_valbyname(PW_SESSION_TYPE, cf_section_name2(cs));
+       } else if (comp == RLM_COMPONENT_PRE_PROXY) {
+               dval = dict_valbyname(PW_PRE_PROXY_TYPE, cf_section_name2(cs));
+       } else if (comp == RLM_COMPONENT_POST_PROXY) {
+               dval = dict_valbyname(PW_POST_PROXY_TYPE, cf_section_name2(cs));
+       } else if (comp == RLM_COMPONENT_POST_AUTH) {
+               dval = dict_valbyname(PW_POST_AUTH_TYPE, cf_section_name2(cs));
        }
 
-       subcomp = new_sublist(comp, dval->value);
+       if (dval) {
+               idx = dval->value;
+       } else {
+               idx = meaningless_counter++;
+       }
+
+       subcomp = new_sublist(comp, idx);
        if (!subcomp) {
                radlog(L_ERR|L_CONS,
-                      "%s[%d] %s %s already configured - skipping",
-                      filename, cf_section_lineno(cs),
-                      section_type_value[comp].typename, name2);
+                               "%s[%d] %s %s already configured - skipping",
+                               filename, cf_section_lineno(cs),
+                               subcomponent_names[comp], cf_section_name2(cs));
                modcallable_free(&ml);
                return 1;
        }
 
        subcomp->modulelist = ml;
-       return 1;               /* OK */
+
+       return 1;
 }
 
-static int load_component_section(modcallable *parent,
-                                 CONF_SECTION *cs, int comp,
+static int load_component_section(CONF_SECTION *cs, int comp,
                                  const char *filename)
 {
        modcallable *this;
@@ -491,25 +538,14 @@ static int load_component_section(modcallable *parent,
        int idx;
        indexed_modcallable *subcomp;
        const char *modname;
-       const char *visiblename;
+       char *visiblename;
 
-       /*
-        *      Loop over the entries in the named section.
-        */
-       for (modref = cf_item_find_next(cs, NULL);
-            modref != NULL;
-            modref = cf_item_find_next(cs, modref)) {
+       for (modref=cf_item_find_next(cs, NULL);
+                       modref != NULL;
+                       modref=cf_item_find_next(cs, modref)) {
                CONF_PAIR *cp = NULL;
                CONF_SECTION *scs = NULL;
 
-               /*
-                *      Look for Auth-Type foo {}, which are special
-                *      cases of named sections, and allowable ONLY
-                *      at the top-level.
-                *
-                *      i.e. They're not allowed in a "group" or "redundant"
-                *      subsection.
-                */
                if (cf_item_is_section(modref)) {
                        const char *sec_name;
                        scs = cf_itemtosection(modref);
@@ -517,9 +553,8 @@ static int load_component_section(modcallable *parent,
                        sec_name = cf_section_name1(scs);
 
                        if (strcmp(sec_name,
-                                  section_type_value[comp].typename) == 0) {
-                               if (!load_subcomponent_section(parent, scs,
-                                                              comp,
+                                  subcomponent_names[comp]) == 0) {
+                               if (!load_subcomponent_section(scs, comp,
                                                               filename)) {
                                        return -1; /* FIXME: memleak? */
                                }
@@ -530,33 +565,26 @@ static int load_component_section(modcallable *parent,
                         *      Allow old names, too.
                         */
                        if (strcmp(sec_name,
-                                  old_section_type_value[comp].typename) == 0) {
-                               if (!load_subcomponent_section(parent, scs,
-                                                              comp,
+                                  old_subcomponent_names[comp]) == 0) {
+                               if (!load_subcomponent_section(scs, comp,
                                                               filename)) {
                                        return -1; /* FIXME: memleak? */
                                }
                                continue;
                        }
                        cp = NULL;
-               } else if (cf_item_is_pair(modref)) {
-                       cp = cf_itemtopair(modref);
                } else {
-                       continue; /* ignore it */
+                       cp = cf_itemtopair(modref);
                }
 
-               /*
-                *      Try to compile one entry.
-                */
-               this = compile_modsingle(parent, comp, modref, filename,
-                                        &modname);
-               if (!this) {
-                       radlog(L_ERR|L_CONS,
-                              "%s[%d] Failed to parse %s section.\n",
-                              filename, cf_section_lineno(cs),
-                              cf_section_name1(cs));
-                       return -1;
-               }
+               this = compile_modsingle(comp, modref, filename, &modname);
+                if (!this) {
+                        radlog(L_ERR|L_CONS,
+                               "%s[%d] Failed to parse %s section.\n",
+                               filename, cf_section_lineno(cs),
+                               cf_section_name1(cs));
+                        return -1;
+                }
 
                if (comp == RLM_COMPONENT_AUTH) {
                        DICT_VALUE *dval;
@@ -569,6 +597,7 @@ static int load_component_section(modcallable *parent,
                        } else {
                                modrefname = cf_section_name2(scs);
                                lineno = cf_section_lineno(scs);
+
                                if (!modrefname) {
                                        radlog(L_ERR|L_CONS,
                                               "%s[%d] Failed to parse %s sub-section.\n",
@@ -577,16 +606,16 @@ static int load_component_section(modcallable *parent,
                                        return -1;
                                }
                        }
-
+                       
                        dval = dict_valbyname(PW_AUTH_TYPE, modrefname);
                        if (!dval) {
                                /*
                                 *      It's a section, but nothing we
                                 *      recognize.  Die!
                                 */
-                               radlog(L_ERR|L_CONS, "%s[%d] Unknown Auth-Type \"%s\" in %s sub-section.",
+                               radlog(L_ERR|L_CONS, "%s[%d] Unknown Auth-Type \"%s\" in %s section.",
                                       filename, lineno,
-                                      modrefname, section_type_value[comp].section);
+                                      modrefname, component_names[comp]);
                                return -1;
                        }
                        idx = dval->value;
@@ -600,7 +629,7 @@ static int load_component_section(modcallable *parent,
                if (subcomp == NULL) {
                        radlog(L_INFO|L_CONS,
                                        "%s %s %s already configured - skipping",
-                                       filename, section_type_value[comp].typename,
+                                       filename, subcomponent_names[comp],
                                        modname);
                        modcallable_free(&this);
                        continue;
@@ -612,12 +641,41 @@ static int load_component_section(modcallable *parent,
                if (visiblename == NULL)
                        visiblename = cf_section_name1(cs);
                add_to_modcallable(&subcomp->modulelist, this,
-                                  comp, visiblename);
+                               comp, visiblename);
        }
 
        return 0;
 }
 
+typedef struct section_type_value_t {
+       const char      *section;
+       const char      *typename;
+       int             attr;
+} section_type_value_t;
+
+static const section_type_value_t section_type_value[] = {
+       { "authorize",    "Autz-Type",       PW_AUTZ_TYPE },
+       { "authenticate", "Auth-Type",       PW_AUTH_TYPE },
+       { "accounting",   "Acct-Type",       PW_ACCT_TYPE },
+       { "session",      "Session-Type",    PW_SESSION_TYPE },
+       { "post-auth",    "Post-Auth-Type",  PW_POST_AUTH_TYPE },
+       { "preacct",      "Pre-Acct-Type",   PW_PRE_ACCT_TYPE },
+       { "post-proxy",   "Post-Proxy-Type", PW_POST_PROXY_TYPE },
+       { "pre-proxy",    "Pre-Proxy-Type",  PW_PRE_PROXY_TYPE },
+       { NULL, NULL, 0 }
+};
+
+/*
+ *     Delete ASAP.
+ */
+static const section_type_value_t old_section_type_value[] = {
+       { "authorize",    "autztype", PW_AUTZ_TYPE },
+       { "authenticate", "authtype", PW_AUTH_TYPE },
+       { "accounting",   "acctype", PW_ACCT_TYPE },
+       { "session",      "sesstype", PW_SESSION_TYPE },
+       { "post-auth",    "post-authtype", PW_POST_AUTH_TYPE },
+       { NULL, NULL, 0 }
+};
 
 /*
  *     Parse the module config sections, and load
@@ -626,17 +684,20 @@ static int load_component_section(modcallable *parent,
  *     Libtool makes your life a LOT easier, especially with libltdl.
  *     see: http://www.gnu.org/software/libtool/
  */
-int setup_modules(int reload)
+int setup_modules(void)
 {
-       int             comp;
-       CONF_SECTION    *cs, *modules;
-       int             do_component[RLM_COMPONENT_COUNT];
-       rad_listen_t    *listener;
+       int comp;
+       CONF_SECTION *cs;
 
        /*
-        *      If necessary, initialize libltdl.
+        *  FIXME: This should be pulled from somewhere else.
         */
-       if (!reload) {
+       const char *filename="radiusd.conf";
+
+       /*
+        *      No current list of modules: Go initialize libltdl.
+        */
+       if (!module_list) {
                /*
                 *      Set the default list of preloaded symbols.
                 *      This is used to initialize libltdl's list of
@@ -649,7 +710,8 @@ int setup_modules(int reload)
                if (lt_dlinit() != 0) {
                        radlog(L_ERR|L_CONS, "Failed to initialize libraries: %s\n",
                                        lt_dlerror());
-                       return -1;
+                       exit(1); /* FIXME */
+
                }
 
                /*
@@ -659,75 +721,23 @@ int setup_modules(int reload)
                 */
                lt_dlsetsearchpath(radlib_dir);
 
-               DEBUG2("radiusd: Library search path is %s",
-                      lt_dlgetsearchpath());
+               DEBUG2("Module: Library search path is %s",
+                               lt_dlgetsearchpath());
 
                /*
-                *      Set up the internal module struct.
+                *      Initialize the components.
                 */
-               module_tree = rbtree_create(module_entry_cmp,
-                                           module_entry_free, 0);
-               if (!module_tree) {
-                       radlog(L_ERR|L_CONS, "Failed to initialize modules\n");
-                       return -1;
+               for (comp = 0; comp < RLM_COMPONENT_COUNT; comp++) {
+                       components[comp] = NULL;
                }
        } else {
-               rbtree_free(components);
-       }
-
-       components = rbtree_create(indexed_modcallable_cmp,
-                                  indexed_modcallable_free, 0);
-       if (!components) {
-               radlog(L_ERR|L_CONS, "Failed to initialize components\n");
-               return -1;
-       }
-
-       /*
-        *      Figure out which sections to load.
-        */
-       memset(do_component, 0, sizeof(do_component));
-       for (listener = mainconfig.listen;
-            listener != NULL;
-            listener = listener->next) {
-               switch (listener->type) {
-               case RAD_LISTEN_AUTH:
-                       do_component[RLM_COMPONENT_AUTZ] = 1;
-                       do_component[RLM_COMPONENT_AUTH] = 1;
-                       do_component[RLM_COMPONENT_POST_AUTH] = 1;
-                       do_component[RLM_COMPONENT_SESS] = 1;
-                       break;
-
-               case RAD_LISTEN_DETAIL: /* just like acct */
-               case RAD_LISTEN_ACCT:
-                       do_component[RLM_COMPONENT_PREACCT] = 1;
-                       do_component[RLM_COMPONENT_ACCT] = 1;
-                       break;
-
-               case RAD_LISTEN_PROXY:
-                       do_component[RLM_COMPONENT_PRE_PROXY] = 1;
-                       do_component[RLM_COMPONENT_POST_PROXY] = 1;
-                       break;
-
-                       /*
-                        *      Ignore this.
-                        */
-               case RAD_LISTEN_SNMP:
-                       break;
-
-               default:
-                       rad_assert(0 == 1);
-                       break;
-               }
-       }
-
-       for (comp = RLM_COMPONENT_AUTH; comp < RLM_COMPONENT_COUNT; comp++) {
                /*
-                *      Have the debugging messages all in one place.
+                *      Else do NOT detach modules.  Instead, just
+                *      forget about any module instances we may have
+                *      previously loaded.  While this leaks memory,
+                *      it's better than the server crashing.
                 */
-               if (!do_component[comp]) {
-                       DEBUG2("modules: Not loading %s{} section",
-                              section_type_value[comp].section);
-               }
+               module_instance_list = NULL;
        }
 
        /*
@@ -737,8 +747,7 @@ int setup_modules(int reload)
         *      let the user create new names, we've got to look for
         *      those names, and create DICT_VALUE's for them.
         */
-       for (comp = RLM_COMPONENT_AUTH; comp < RLM_COMPONENT_COUNT; comp++) {
-               int             value;
+       for (comp = 0; section_type_value[comp].section != NULL; comp++) {
                const char      *name2;
                DICT_ATTR       *dattr;
                DICT_VALUE      *dval;
@@ -746,11 +755,10 @@ int setup_modules(int reload)
                CONF_PAIR       *cp;
 
                /*
-                *      Not needed, don't load it.
+                *  Big-time YUCK
                 */
-               if (!do_component[comp]) {
-                       continue;
-               }
+               static int my_value = 32767;
+
                cs = cf_section_find(section_type_value[comp].section);
 
                if (!cs) continue;
@@ -762,12 +770,13 @@ int setup_modules(int reload)
                         *      name.
                         */
                        next = cf_subsection_find_next(cs, sub,
-                                                      section_type_value[comp].typename);
+                                                     section_type_value[comp].typename);
 
                        /*
                         *      Allow some old names, too.
                         */
                        if (!next && (comp <= 4)) {
+
                                next = cf_subsection_find_next(cs, sub,
                                                               old_section_type_value[comp].typename);
                        }
@@ -793,28 +802,14 @@ int setup_modules(int reload)
                                 *      Find the attribute for the value.
                         */
                        dattr = dict_attrbyvalue(section_type_value[comp].attr);
-                       if (!dattr) {
-                               radlog(L_ERR, "%s[%d]: No such attribute %s",
-                                      mainconfig.radiusd_conf,
-                                      cf_section_lineno(sub),
-                                      section_type_value[comp].typename);
-                               continue;
-                       }
+                       if (!dattr) continue;
 
                        /*
-                        *      Create a new unique value with a
-                        *      meaningless number.  You can't look at
-                        *      it from outside of this code, so it
-                        *      doesn't matter.  The only requirement
-                        *      is that it's unique.
+                        *      Finally, create the new attribute.
                         */
-                       do {
-                               value = lrad_rand() & 0x00ffffff;
-                       } while (dict_valbyattr(dattr->attr, value));
-
-                       if (dict_addvalue(name2, dattr->name, value) < 0) {
+                       if (dict_addvalue(name2, dattr->name, my_value++) < 0) {
                                radlog(L_ERR, "%s", librad_errstr);
-                               return -1;
+                               exit(1);
                        }
                } while (sub != NULL);
 
@@ -844,37 +839,19 @@ int setup_modules(int reload)
                                 *      Find the attribute for the value.
                         */
                        dattr = dict_attrbyvalue(section_type_value[comp].attr);
-                       if (!dattr) {
-                               radlog(L_ERR, "%s[%d]: No such attribute %s",
-                                      mainconfig.radiusd_conf,
-                                      cf_section_lineno(sub),
-                                      section_type_value[comp].typename);
-                               continue;
-                       }
+                       if (!dattr) continue;
 
                        /*
                         *      Finally, create the new attribute.
                         */
-                       do {
-                               value = lrad_rand() & 0x00ffffff;
-                       } while (dict_valbyattr(dattr->attr, value));
-                       if (dict_addvalue(name2, dattr->name, value) < 0) {
+                       if (dict_addvalue(name2, dattr->name, my_value++) < 0) {
                                radlog(L_ERR, "%s", librad_errstr);
-                               return -1;
+                               exit(1);
                        }
                } while (cp != NULL);
        } /* over the sections which can have redundent sub-sections */
 
        /*
-        *      Remember where the modules were stored.
-        */
-       modules = cf_section_find("modules");
-       if (!modules) {
-               radlog(L_ERR, "Cannot find a \"modules\" section in the configuration file!");
-               return -1;
-       }
-
-       /*
         *  Look for the 'instantiate' section, which tells us
         *  the instantiation order of the modules, and also allows
         *  us to load modules with no authorize/authenticate/etc.
@@ -887,8 +864,6 @@ int setup_modules(int reload)
                module_instance_t *module;
                const char *name;
 
-               DEBUG2(" instantiate {");
-
                /*
                 *  Loop over the items in the 'instantiate' section.
                 */
@@ -896,54 +871,37 @@ int setup_modules(int reload)
                     ci != NULL;
                     ci=cf_item_find_next(cs, ci)) {
 
-                       /*
-                        *      Skip sections.  They'll be handled
-                        *      later, if they're referenced at all...
-                        */
                        if (cf_item_is_section(ci)) {
-                               continue;
+                               radlog(L_ERR|L_CONS,
+                                      "%s[%d] Subsection for module instantiate is not allowed\n", filename,
+
+                                      cf_section_lineno(cf_itemtosection(ci)));
+                               exit(1);
                        }
 
                        cp = cf_itemtopair(ci);
                        name = cf_pair_attr(cp);
-                       module = find_module_instance(modules, name);
+                       module = find_module_instance(name);
                        if (!module) {
-                               return -1;
+                               exit(1);
                        }
                } /* loop over items in the subsection */
-
-               DEBUG2(" }");
        } /* if there's an 'instantiate' section. */
 
-       DEBUG2(" modules {");
-
        /*
         *      Loop over all of the known components, finding their
         *      configuration section, and loading it.
         */
        for (comp = 0; comp < RLM_COMPONENT_COUNT; ++comp) {
-               cs = cf_section_find(section_type_value[comp].section);
+               cs = cf_section_find(component_names[comp]);
                if (cs == NULL)
                        continue;
 
-               if (!do_component[comp]) {
-                       continue;
-               }
-
-               if (cf_item_find_next(cs, NULL) == NULL) {
-                       continue; /* section is empty */
-               }
-
-               DEBUG2(" Module: Checking %s {...} for more modules to load",
-                      section_type_value[comp].section);
-
-               if (load_component_section(NULL, cs, comp, mainconfig.radiusd_conf) < 0) {
-                       return -1;
+               if (load_component_section(cs, comp, filename) < 0) {
+                       exit(1);
                }
        }
 
-       DEBUG2(" }");
-
        return 0;
 }
 
@@ -953,6 +911,17 @@ int setup_modules(int reload)
  */
 int module_authorize(int autz_type, REQUEST *request)
 {
+       /*
+        *      We have a proxied packet, and we've been told
+        *      to NOT pass proxied packets through 'authorize'
+        *      a second time.  So stop.
+        */
+       if ((request->proxy != NULL &&
+            mainconfig.post_proxy_authorize == FALSE)) {
+               DEBUG2(" authorize: Skipping authorize in post-proxy stage");
+               return RLM_MODULE_NOOP;
+       }
+
        return indexed_modcall(RLM_COMPONENT_AUTZ, autz_type, request);
 }
 
@@ -989,6 +958,9 @@ int module_checksimul(int sess_type, REQUEST *request, int maxsimul)
 {
        int rcode;
 
+       if(!components[RLM_COMPONENT_SESS])
+               return 0;
+
        if(!request->username)
                return 0;
 
diff --git a/src/main/nas.c b/src/main/nas.c
new file mode 100644 (file)
index 0000000..8d7bbcb
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * nas.c       Functions to do with a NASLIST. This is here because
+ *             radzap needs it as well.
+ *
+ * Version:     $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
+ * Copyright 2000  Alan DeKok <aland@ox.org>
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+
+static NAS *naslist = NULL;
+
+/*
+ *     Free a NAS list.
+ */
+static void nas_free(NAS *cl)
+{
+       NAS *next;
+
+       while(cl) {
+               next = cl->next;
+               free(cl);
+               cl = next;
+       }
+}
+
+/*
+ *     Read the nas file.
+ */
+int read_naslist_file(char *file)
+{
+       FILE *fp;
+       char buffer[256];
+       char hostnm[256];
+       char shortnm[256];
+       char nastype[256];
+       int lineno = 0;
+       char *p;
+       NAS *nas;
+
+       nas_free(naslist);
+       naslist = NULL;
+
+       if (!file) return 0;
+
+       if ((fp = fopen(file, "r")) == NULL) {
+               /* The naslist file is no longer required.  All configuration
+                  information comes from radiusd.conf.  If naslist exists it
+                  will be used, but if it doesn't exist it will be silently
+                  ignored. */
+               return 0;
+       }
+       radlog(L_INFO, "Using deprecated naslist file.  Support for this will go away soon.");
+       while(fgets(buffer, 256, fp) != NULL) {
+               lineno++;
+               if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
+                       radlog(L_ERR, "%s[%d]: line too long", file, lineno);
+                       return -1;
+               }
+               if (buffer[0] == '#' || buffer[0] == '\n')
+                       continue;
+
+               p = buffer;
+               if (!getword(&p, hostnm, sizeof(hostnm)) ||
+                   !getword(&p, shortnm, sizeof(shortnm))) {
+                       radlog(L_ERR, "%s[%d]: unexpected end of line",
+                              file, lineno);
+                       continue;
+               }
+               (void)getword(&p, nastype, sizeof(nastype));
+
+               /*
+                *      Double-check lengths to be sure they're sane
+                */
+               if (strlen(hostnm) >= sizeof(nas->longname)) {
+                       radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(hostnm),
+                              (int) sizeof(nas->longname) - 1);
+                       return -1;
+               }
+               if (strlen(shortnm) > sizeof(nas->shortname)) {
+                       radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(shortnm),
+                              (int) sizeof(nas->shortname) - 1);
+                       return -1;
+               }
+               if (strlen(nastype) >= sizeof(nas->nastype)) {
+                       radlog(L_ERR, "%s[%d]: NAS type of length %d is greater than the allowed maximum of %d.",
+                              file, lineno,
+                              (int) strlen(nastype),
+                              (int) sizeof(nas->nastype) - 1);
+                       return -1;
+               }
+
+               /*
+                *      It should be OK now, let's create the buffer.
+                */
+               nas = rad_malloc(sizeof(NAS));
+               memset(nas, 0, sizeof(*nas));
+
+               strcpy(nas->nastype, nastype);
+               strcpy(nas->shortname, shortnm);
+
+               if (strcmp(hostnm, "DEFAULT") == 0) {
+                       nas->ipaddr = 0;
+                       strcpy(nas->longname, hostnm);
+               } else {
+                       nas->ipaddr = ip_getaddr(hostnm);
+                       ip_hostname(nas->longname, sizeof(nas->longname),
+                                       nas->ipaddr);
+               }
+
+               nas->next = naslist;
+               naslist = nas;
+       }
+       fclose(fp);
+
+       return 0;
+}
+
+
+/*
+ *     Find a nas by IP address.
+ *     If it can't be found, return the DEFAULT nas, instead.
+ */
+NAS *nas_find(uint32_t ipaddr)
+{
+       NAS *nas;
+       NAS *default_nas;
+
+       default_nas = NULL;
+
+       for (nas = naslist; nas; nas = nas->next) {
+               if (ipaddr == nas->ipaddr)
+                       return nas;
+               if (strcmp(nas->longname, "DEFAULT") == 0)
+                       default_nas = nas;
+       }
+
+       return default_nas;
+}
+
+
+/*
+ *     Find a nas by name.
+ *     If it can't be found, return the DEFAULT nas, instead.
+ */
+NAS *nas_findbyname(char *nasname)
+{
+       NAS     *nas;
+       NAS     *default_nas;
+
+       default_nas = NULL;
+
+       for (nas = naslist; nas; nas = nas->next) {
+               if (strcmp(nasname, nas->shortname) == 0 ||
+                               strcmp(nasname, nas->longname) == 0)
+                       return nas;
+               if (strcmp(nas->longname, "DEFAULT") == 0)
+                       default_nas = nas;
+       }
+
+       return default_nas;
+}
+
+
+/*
+ *     Find the name of a nas (prefer short name).
+ */
+const char *nas_name(uint32_t ipaddr)
+{
+       NAS *nas;
+
+       if ((nas = nas_find(ipaddr)) != NULL) {
+               if (nas->shortname[0])
+                       return nas->shortname;
+               else
+                       return nas->longname;
+       }
+
+       return "UNKNOWN-NAS";
+}
+
+/*
+ *     Find the name of a nas (prefer short name) based on the request.
+ */
+const char *nas_name2(RADIUS_PACKET *packet)
+{
+       NAS *nas;
+
+       if ((nas = nas_find(packet->src_ipaddr)) != NULL) {
+               if (nas->shortname[0])
+                       return nas->shortname;
+               else
+                       return nas->longname;
+       }
+
+       return "UNKNOWN-NAS";
+}
+
+/*
+ *     Find the name of a nas (prefer short name) based on ipaddr,
+ *     store in passed buffer.  If NAS is unknown, return dotted quad.
+ */
+char * nas_name3(char *buf, size_t buflen, uint32_t ipaddr)
+{
+       NAS *nas;
+
+       if ((nas = nas_find(ipaddr)) != NULL) {
+               if (nas->shortname[0]) {
+                       strNcpy(buf, (char *)nas->shortname, buflen);
+                       return buf;
+               }
+               else {
+                       strNcpy(buf, (char *)nas->longname, buflen);
+                       return buf;
+               }
+       }
+       ip_ntoa(buf, ipaddr);
+       return buf;
+}
+
+
diff --git a/src/main/proxy.c b/src/main/proxy.c
new file mode 100644 (file)
index 0000000..e0c7f31
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * proxy.c     Proxy stuff.
+ *
+ * Version:    $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
+ * Copyright 2000  Chris Parker <cparker@starnetusa.com>
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <sys/socket.h>
+
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "modules.h"
+#include "request_list.h"
+
+/*
+ *     We received a response from a remote radius server.
+ *     Find the original request, then return.
+ *     Returns:   1 replication don't reply
+ *                0 proxy found
+ *               -1 error don't reply
+ */
+int proxy_receive(REQUEST *request)
+{
+        int rcode;
+       int post_proxy_type = 0;
+       VALUE_PAIR *vp;
+
+        /*
+         *     Delete any reply we had accumulated until now.
+        */
+        pairfree(&request->reply->vps);
+
+       /*
+        *      Run the packet through the post-proxy stage,
+        *      BEFORE playing games with the attributes.
+        */
+       vp = pairfind(request->config_items, PW_POST_PROXY_TYPE);
+       if (vp) {
+               DEBUG2("  Found Post-Proxy-Type %s", vp->strvalue);
+               post_proxy_type = vp->lvalue;
+       }
+       rcode = module_post_proxy(post_proxy_type, request);
+
+        /*
+         *     Delete the Proxy-State Attributes from the reply.
+         *     These include Proxy-State attributes from us and
+         *     remote server.
+        */
+        pairdelete(&request->proxy_reply->vps, PW_PROXY_STATE);
+
+       /*
+        *      Add the attributes left in the proxy reply to
+        *      the reply list.
+        */
+        pairadd(&request->reply->vps, request->proxy_reply->vps);
+        request->proxy_reply->vps = NULL;
+
+        /*
+        *      Free proxy request pairs.
+         */
+        pairfree(&request->proxy->vps);
+
+        return rcode;
+}
+
+/*
+ *     Add a proxy-pair to the end of the request.
+ */
+static void proxy_addinfo(REQUEST *request)
+{
+       VALUE_PAIR *proxy_pair;
+
+       proxy_pair = paircreate(PW_PROXY_STATE, PW_TYPE_STRING);
+       if (proxy_pair == NULL) {
+               radlog(L_ERR|L_CONS, "no memory");
+               exit(1);
+       }
+       sprintf((char *)proxy_pair->strvalue, "%d", request->packet->id);
+       proxy_pair->length = strlen((char *)proxy_pair->strvalue);
+
+       pairadd(&request->proxy->vps, proxy_pair);
+}
+
+
+/*
+ *     Like realm find, but does load balancing, and we don't
+ *     wake up any sleeping realms.  Someone should already have
+ *     done that.
+ *
+ *     It also does NOT do fail-over to default if the realms are dead,
+ *     as that decision has already been made.
+ */
+static REALM *proxy_realm_ldb(REQUEST *request, const char *realm_name,
+                             int accounting)
+{
+       int             redone = 0;
+       REALM           *cl, *lb;
+       uint32_t        count;
+
+ redo:
+       lb = NULL;
+       count = 0;
+       for (cl = mainconfig.realms; cl; cl = cl->next) {
+               /*
+                *      Wake up any sleeping realm.
+                *
+                *      Note that the 'realm find' function will only
+                *      wake up the FIRST realm which matches.  We've
+                *      got to wake up ALL of the matching realms.
+                */
+               if (cl->wakeup <= request->timestamp) {
+                       cl->active = TRUE;
+               }
+               if (cl->acct_wakeup <= request->timestamp) {
+                       cl->acct_active = TRUE;
+               }
+
+               /*
+                *      Asked for auth/acct, and the auth/acct server
+                *      is not active.  Skip it.
+                */
+               if ((!accounting && !cl->active) ||
+                   (accounting && !cl->acct_active)) {
+                       continue;
+               }
+
+               /*
+                *      The realm name doesn't match, skip it.
+                */
+               if (strcasecmp(cl->realm, realm_name) != 0) {
+                       continue;
+               }
+
+               /*
+                *      Fail-over, pick the first one that matches.
+                */
+               if ((count == 0) && /* if size > 0, we have round-robin */
+                   (cl->ldflag == 0)) {
+                       return cl;
+               }
+
+               /*
+                *      We're doing load-balancing.  Pick a random
+                *      number, which will be used to determine which
+                *      home server is chosen.
+                */
+               if (!lb) {
+                       lb = cl;
+                       count = 1;
+                       continue;
+               }
+
+               /*
+                *      Keep track of how many load balancing servers
+                *      we've gone through.
+                */
+               count++;
+
+               /*
+                *      See the "camel book" for why this works.
+                *
+                *      If (rand(0..n) < 1), pick the current realm.
+                *      We add a scale factor of 65536, to avoid
+                *      floating point.
+                */
+               if ((count * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
+                       lb = cl;
+               }
+       } /* loop over the realms */
+
+       /*
+        *      All are dead, see if we have to wake
+        */
+       if (!redone && !lb && mainconfig.wake_all_if_all_dead) {
+               for (cl = mainconfig.realms; cl; cl = cl->next) {
+                       if(strcasecmp(cl->realm,realm_name) == 0) {
+                               if (!accounting && !cl->active) {
+                                       cl->active = TRUE;
+                               }
+                               else if (accounting &&
+                                        !cl->acct_active) {
+                                       cl->acct_active = TRUE;
+                               }
+                       }
+               }
+               redone = 1;
+               goto redo;
+       }
+
+       /*
+        *      Return the load-balanced realm.
+        */
+       return lb;
+}
+
+/*
+ *     Relay the request to a remote server.
+ *     Returns:
+ *
+ *      RLM_MODULE_FAIL: we don't reply, caller returns without replying
+ *      RLM_MODULE_NOOP: caller falls through to normal processing
+ *      RLM_MODULE_HANDLED  : we reply, caller returns without replying
+ */
+int proxy_send(REQUEST *request)
+{
+       int rcode;
+       int pre_proxy_type = 0;
+       VALUE_PAIR *realmpair;
+       VALUE_PAIR *strippedname;
+       VALUE_PAIR *delaypair;
+       VALUE_PAIR *vp;
+       REALM *realm;
+       char *realmname;
+
+       /*
+        *      Not authentication or accounting.  Stop it.
+        */
+       if ((request->packet->code != PW_AUTHENTICATION_REQUEST) &&
+           (request->packet->code != PW_ACCOUNTING_REQUEST)) {
+               DEBUG2("  ERROR: Cannot proxy packets of type %d",
+                      request->packet->code);
+               return RLM_MODULE_FAIL;
+       }
+
+       /*
+        *      The timestamp is used below to figure the
+        *      next_try. The request needs to "hang around" until
+        *      either the other server sends a reply or the retry
+        *      count has been exceeded.  Until then, it should not
+        *      be eligible for the time-based cleanup.  --Pac. */
+
+       realmpair = pairfind(request->config_items, PW_PROXY_TO_REALM);
+       if (!realmpair) {
+               /*
+                *      Not proxying, so we can exit from the proxy
+                *      code.
+                */
+               return RLM_MODULE_NOOP;
+       }
+
+       /*
+        *      If the server has already decided to reject the request,
+        *      then don't try to proxy it.
+        */
+       if (request->reply->code == PW_AUTHENTICATION_REJECT) {
+               DEBUG2("Cancelling proxy as request was already rejected");
+               return RLM_MODULE_REJECT;
+       }
+       if (((vp = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL) &&
+           (vp->lvalue == PW_AUTHTYPE_REJECT)) {
+               DEBUG2("Cancelling proxy as request was already rejected");
+               return RLM_MODULE_REJECT;
+       }
+       /*
+        *      Length == 0 means it exists, but there's no realm.
+        *      Don't proxy it.
+        */
+       if (realmpair->length == 0) {
+               return RLM_MODULE_NOOP;
+       }
+
+       realmname = (char *)realmpair->strvalue;
+
+       /*
+        *      Look for the realm, using the load balancing
+        *      version of realm find.
+        */
+       realm = proxy_realm_ldb(request, realmname,
+                               (request->packet->code == PW_ACCOUNTING_REQUEST));
+       if (realm == NULL) {
+               DEBUG2("  ERROR: Failed to find live home server for realm %s",
+                      realmname);
+               return RLM_MODULE_FAIL;
+       }
+
+       /*
+        *      Remember that we sent the request to a Realm.
+        */
+       pairadd(&request->packet->vps,
+               pairmake("Realm", realm->realm, T_OP_EQ));
+
+       /*
+        *      Access-Request: look for LOCAL realm.
+        *      Accounting-Request: look for LOCAL realm.
+        */
+       if (((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
+            (realm->ipaddr == htonl(INADDR_NONE))) ||
+           ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
+            (realm->acct_ipaddr == htonl(INADDR_NONE)))) {
+               DEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",
+                      realm->realm);
+               return RLM_MODULE_NOOP;
+       }
+
+       /*
+        *      Allocate the proxy packet, only if it wasn't already
+        *      allocated by a module.  This check is mainly to support
+        *      the proxying of EAP-TTLS and EAP-PEAP tunneled requests.
+        *
+        *      In those cases, the EAP module creates a "fake"
+        *      request, and recursively passes it through the
+        *      authentication stage of the server.  The module then
+        *      checks if the request was supposed to be proxied, and
+        *      if so, creates a proxy packet from the TUNNELED request,
+        *      and not from the EAP request outside of the tunnel.
+        *
+        *      The proxy then works like normal, except that the response
+        *      packet is "eaten" by the EAP module, and encapsulated into
+        *      an EAP packet.
+        */
+       if (!request->proxy) {
+               /*
+                *      Now build a new RADIUS_PACKET.
+                *
+                *      FIXME: it could be that the id wraps around
+                *      too fast if we have a lot of requests, it
+                *      might be better to keep a seperate ID value
+                *      per remote server.
+                *
+                *      OTOH the remote radius server should be smart
+                *      enough to compare _both_ ID and vector.
+                *      Right?
+                */
+               if ((request->proxy = rad_alloc(TRUE)) == NULL) {
+                       radlog(L_ERR|L_CONS, "no memory");
+                       exit(1);
+               }
+
+               /*
+                *      We now massage the attributes to be proxied...
+                */
+
+               /*
+                *      Copy the request, then look up name and
+                *      plain-text password in the copy.
+                *
+                *      Note that the User-Name attribute is the
+                *      *original* as sent over by the client.  The
+                *      Stripped-User-Name attribute is the one hacked
+                *      through the 'hints' file.
+                */
+               request->proxy->vps =  paircopy(request->packet->vps);
+       }
+
+       /*
+        *      Strip the name, if told to.
+        *
+        *      Doing it here catches the case of proxied tunneled
+        *      requests.
+        */
+       if (realm->striprealm == TRUE &&
+          (strippedname = pairfind(request->proxy->vps, PW_STRIPPED_USER_NAME)) != NULL) {
+               /*
+                *      If there's a Stripped-User-Name attribute in
+                *      the request, then use THAT as the User-Name
+                *      for the proxied request, instead of the
+                *      original name.
+                *
+                *      This is done by making a copy of the
+                *      Stripped-User-Name attribute, turning it into
+                *      a User-Name attribute, deleting the
+                *      Stripped-User-Name and User-Name attributes
+                *      from the vps list, and making the new
+                *      User-Name the head of the vps list.
+                */
+               vp = pairfind(request->proxy->vps, PW_USER_NAME);
+               if (!vp) {
+                       vp = paircreate(PW_USER_NAME, PW_TYPE_STRING);
+                       if (!vp) {
+                               radlog(L_ERR|L_CONS, "no memory");
+                               exit(1);
+                       }
+                       vp->next = request->proxy->vps;
+                       request->proxy->vps = vp;
+               }
+               memcpy(vp->strvalue, strippedname->strvalue,
+                      sizeof(vp->strvalue));
+               vp->length = strippedname->length;
+
+               /*
+                *      Do NOT delete Stripped-User-Name.
+                */
+       }
+       
+       /*
+        *      If there is no PW_CHAP_CHALLENGE attribute but
+        *      there is a PW_CHAP_PASSWORD we need to add it
+        *      since we can't use the request authenticator
+        *      anymore - we changed it.
+        */
+       if (pairfind(request->proxy->vps, PW_CHAP_PASSWORD) &&
+           pairfind(request->proxy->vps, PW_CHAP_CHALLENGE) == NULL) {
+               vp = paircreate(PW_CHAP_CHALLENGE, PW_TYPE_STRING);
+               if (!vp) {
+                       radlog(L_ERR|L_CONS, "no memory");
+                       exit(1);
+               }
+               vp->length = AUTH_VECTOR_LEN;
+               memcpy(vp->strvalue, request->packet->vector, AUTH_VECTOR_LEN);
+               pairadd(&(request->proxy->vps), vp);
+       }
+
+       request->proxy->code = request->packet->code;
+       if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
+               request->proxy->dst_port = realm->auth_port;
+               request->proxy->dst_ipaddr = realm->ipaddr;
+       } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
+               request->proxy->dst_port = realm->acct_port;
+               request->proxy->dst_ipaddr = realm->acct_ipaddr;
+       }
+
+       /*
+        *      Add PROXY_STATE attribute, before pre-proxy stage,
+        *      so the pre-proxy modules have access to it.
+        *
+        *      Note that, at this point, the proxied request HAS NOT
+        *      been assigned a RADIUS Id.
+        */
+       proxy_addinfo(request);
+
+       /*
+        *      Set up for sending the request.
+        */
+       memcpy(request->proxysecret, realm->secret, sizeof(request->proxysecret));
+       request->proxy_try_count = mainconfig.proxy_retry_count - 1;
+       request->proxy_next_try = request->timestamp + mainconfig.proxy_retry_delay;
+       delaypair = pairfind(request->proxy->vps, PW_ACCT_DELAY_TIME);
+       request->proxy->timestamp = request->timestamp - (delaypair ? delaypair->lvalue : 0);
+
+       /*
+        *  Do pre-proxying
+        */
+       vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE);
+       if (vp) {
+               DEBUG2("  Found Pre-Proxy-Type %s", vp->strvalue);
+               pre_proxy_type = vp->lvalue;
+       }
+       rcode = module_pre_proxy(pre_proxy_type, request);
+
+       /*
+        *      Do NOT free request->proxy->vps, the pairs are needed
+        *      for the retries! --Pac.
+        */
+
+       /*
+        *      Delay sending the proxy packet until after we've
+        *      done the work above, playing with the request.
+        *
+        *      After this point, it becomes dangerous to play
+        *      with the request data structure, as the reply MAY
+        *      come in and get processed before we're done with it here.
+        *
+        *      Only proxy the packet if the pre-proxy code succeeded.
+        */
+       if ((rcode == RLM_MODULE_OK) ||
+           (rcode == RLM_MODULE_NOOP) ||
+           (rcode == RLM_MODULE_UPDATED)) {
+               request->options |= RAD_REQUEST_OPTION_PROXIED;
+
+               /*
+                *      IF it's a fake request, don't send the proxy
+                *      packet.  The outer tunnel session will take
+                *      care of doing that.
+                */
+               if ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0) {
+                       /*
+                        *      Add the proxied request to the
+                        *      list of outstanding proxied
+                        *      requests, BEFORE we send it, so
+                        *      we have fewer problems with race
+                        *      conditions when the responses come
+                        *      back very quickly.
+                        */
+                       if (!rl_add_proxy(request)) {
+                               DEBUG("ERROR: Failed to proxy request %d",
+                                     request->number);
+                               return RLM_MODULE_FAIL; /* caller doesn't reply */
+                       }
+
+                       rad_send(request->proxy, NULL,
+                                (char *)request->proxysecret);
+               }
+               rcode = RLM_MODULE_HANDLED; /* caller doesn't reply */
+       } else {
+               rcode = RLM_MODULE_FAIL; /* caller doesn't reply */
+       }
+
+       return rcode;
+}
index 59b7311..b2c2def 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/libradius.h>
-#include <freeradius-devel/conf.h>
-#include <freeradius-devel/radpaths.h>
+#include <stdio.h>
+#include <stdlib.h>
 
+#ifdef HAVE_UNISTD_H
+#      include <unistd.h>
+#endif
+
+#include <string.h>
 #include <ctype.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#      include <sys/select.h>
+#endif
 
 #ifdef HAVE_GETOPT_H
 #      include <getopt.h>
@@ -37,6 +51,11 @@ RCSID("$Id$")
 
 #include <assert.h>
 
+#include "conf.h"
+#include "radpaths.h"
+#include "missing.h"
+#include "libradius.h"
+
 static int retries = 10;
 static float timeout = 3;
 static const char *secret = NULL;
@@ -47,19 +66,16 @@ static int totallost = 0;
 
 static int server_port = 0;
 static int packet_code = 0;
-static lrad_ipaddr_t server_ipaddr;
+static uint32_t server_ipaddr = 0;
 static int resend_count = 1;
 static int done = 1;
-static int print_filename = 0;
-
-static lrad_ipaddr_t client_ipaddr;
-static int client_port = 0;
 
 static int sockfd;
+static int radius_id[256];
 static int last_used_id = -1;
 
 static rbtree_t *filename_tree = NULL;
-static lrad_packet_list_t *pl = NULL;
+static rbtree_t *request_tree = NULL;
 
 static int sleep_time = -1;
 
@@ -100,8 +116,6 @@ static void NEVER_RETURNS usage(void)
        fprintf(stderr, "  -t timeout  Wait 'timeout' seconds before retrying (may be a floating point number).\n");
        fprintf(stderr, "  -v          Show program version information.\n");
        fprintf(stderr, "  -x          Debugging mode.\n");
-       fprintf(stderr, "  -4          Use IPv4 address of server\n");
-       fprintf(stderr, "  -6          Use IPv6 address of server.\n");
 
        exit(1);
 }
@@ -184,7 +198,7 @@ static radclient_t *radclient_init(const char *filename)
 
                radclient->request = rad_alloc(1);
                if (!radclient->request) {
-                       librad_perror("radclient: Y");
+                       librad_perror("radclient: X");
                        radclient_free(radclient);
                        if (fp != stdin) fclose(fp);
                        return NULL; /* memory leak "start" */
@@ -197,7 +211,7 @@ static radclient_t *radclient_init(const char *filename)
                /*
                 *      Read the VP's.
                 */
-               radclient->request->vps = readvp2(fp, &filedone, "radclient:");
+               radclient->request->vps = readvp2(fp, &filedone, "radclient: X");
                if (!radclient->request->vps) {
                        radclient_free(radclient);
                        if (fp != stdin) fclose(fp);
@@ -207,15 +221,13 @@ static radclient_t *radclient_init(const char *filename)
                /*
                 *      Keep a copy of the the User-Password attribute.
                 */
-               if ((vp = pairfind(radclient->request->vps, PW_USER_PASSWORD)) != NULL) {
-                       strlcpy(radclient->password, vp->vp_strvalue,
-                               sizeof(radclient->password));
+               if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
+                       strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
                        /*
                         *      Otherwise keep a copy of the CHAP-Password attribute.
                         */
                } else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
-                       strlcpy(radclient->password, vp->vp_strvalue,
-                               sizeof(radclient->password));
+                       strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
                } else {
                        radclient->password[0] = '\0';
                }
@@ -233,35 +245,11 @@ static radclient_t *radclient_init(const char *filename)
                                 *      the attributes read from the file.
                                 */
                        case PW_PACKET_TYPE:
-                               radclient->request->code = vp->vp_integer;
+                               radclient->request->code = vp->lvalue;
                                break;
 
                        case PW_PACKET_DST_PORT:
-                               radclient->request->dst_port = (vp->vp_integer & 0xffff);
-                               break;
-
-                       case PW_PACKET_DST_IP_ADDRESS:
-                               radclient->request->dst_ipaddr.af = AF_INET;
-                               radclient->request->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
-                               break;
-
-                       case PW_PACKET_DST_IPV6_ADDRESS:
-                               radclient->request->dst_ipaddr.af = AF_INET6;
-                               radclient->request->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
-                               break;
-
-                       case PW_PACKET_SRC_PORT:
-                               radclient->request->src_port = (vp->vp_integer & 0xffff);
-                               break;
-
-                       case PW_PACKET_SRC_IP_ADDRESS:
-                               radclient->request->src_ipaddr.af = AF_INET;
-                               radclient->request->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
-                               break;
-
-                       case PW_PACKET_SRC_IPV6_ADDRESS:
-                               radclient->request->src_ipaddr.af = AF_INET6;
-                               radclient->request->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
+                               radclient->request->dst_port = (vp->lvalue & 0xffff);
                                break;
 
                        case PW_DIGEST_REALM:
@@ -275,11 +263,10 @@ static radclient_t *radclient_init(const char *filename)
                        case PW_DIGEST_NONCE_COUNT:
                        case PW_DIGEST_USER_NAME:
                                /* overlapping! */
-                               memmove(&vp->vp_octets[2], &vp->vp_octets[0],
-                                       vp->length);
-                               vp->vp_octets[0] = vp->attribute - PW_DIGEST_REALM + 1;
+                               memmove(&vp->strvalue[2], &vp->strvalue[0], vp->length);
+                               vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
                                vp->length += 2;
-                               vp->vp_octets[1] = vp->length;
+                               vp->strvalue[1] = vp->length;
                                vp->attribute = PW_DIGEST_ATTRIBUTES;
                                break;
                        }
@@ -312,14 +299,8 @@ static int radclient_sane(radclient_t *radclient)
        if (radclient->request->dst_port == 0) {
                radclient->request->dst_port = server_port;
        }
-       if (radclient->request->dst_ipaddr.af == AF_UNSPEC) {
-               if (server_ipaddr.af == AF_UNSPEC) {
-                       fprintf(stderr, "radclient: No server was given, but request %d in file %s did not contain Packet-Dst-IP-Address\n",
-                               radclient->packet_number, radclient->filename);
-                       return -1;
-               }
-               radclient->request->dst_ipaddr = server_ipaddr;
-       }
+       radclient->request->dst_ipaddr = server_ipaddr;
+
        if (radclient->request->code == 0) {
                if (packet_code == -1) {
                        fprintf(stderr, "radclient: Request was \"auto\", but request %d in file %s did not contain Packet-Type\n",
@@ -329,7 +310,7 @@ static int radclient_sane(radclient_t *radclient)
 
                radclient->request->code = packet_code;
        }
-       radclient->request->sockfd = -1;
+       radclient->request->sockfd = sockfd;
 
        return 0;
 }
@@ -380,10 +361,40 @@ static int filename_walk(void *context, void *data)
 
 
 /*
- *     Deallocate packet ID, etc.
+ *     Compare two RADIUS_PACKET data structures, based on a number
+ *     of criteria.
+ */
+static int request_cmp(const void *one, const void *two)
+{
+       const radclient_t *a = one;
+       const radclient_t *b = two;
+
+       /*
+        *      The following code looks unreasonable, but it's
+        *      the only way to make the comparisons work.
+        */
+       if (a->request->id < b->request->id) return -1;
+       if (a->request->id > b->request->id) return +1;
+
+       if (a->request->dst_ipaddr < b->request->dst_ipaddr) return -1;
+       if (a->request->dst_ipaddr > b->request->dst_ipaddr) return +1;
+
+       if (a->request->dst_port < b->request->dst_port) return -1;
+       if (a->request->dst_port > b->request->dst_port) return +1;
+
+       /*
+        *      Everything's equal.  Say so.
+        */
+       return 0;
+}
+
+/*
+ *     "Free" a request.
  */
-static void deallocate_id(radclient_t *radclient)
+static void request_free(void *data)
 {
+       radclient_t *radclient = (radclient_t *) data;
+
        if (!radclient || !radclient->request ||
            (radclient->request->id < 0)) {
                return;
@@ -392,7 +403,7 @@ static void deallocate_id(radclient_t *radclient)
        /*
         *      One more unused RADIUS ID.
         */
-       lrad_packet_list_id_free(pl, radclient->request);
+       radius_id[radclient->request->id] = 0;
        radclient->request->id = -1;
 
        /*
@@ -409,72 +420,13 @@ static void deallocate_id(radclient_t *radclient)
 }
 
 
-static void print_hex(RADIUS_PACKET *packet)
-{
-       int i;
-
-       if (!packet->data) return;
-
-       printf("  Code:\t\t%u\n", packet->data[0]);
-       printf("  Id:\t\t%u\n", packet->data[1]);
-       printf("  Length:\t%u\n", ((packet->data[2] << 8) |
-                                  (packet->data[3])));
-       printf("  Vector:\t");
-       for (i = 4; i < 20; i++) {
-               printf("%02x", packet->data[i]);
-       }
-       printf("\n");
-
-       if (packet->data_len > 20) {
-               int total;
-               const uint8_t *ptr;
-               printf("  Data:");
-
-               total = packet->data_len - 20;
-               ptr = packet->data + 20;
-
-               while (total > 0) {
-                       int attrlen;
-
-                       printf("\t\t");
-                       if (total < 2) { /* too short */
-                               printf("%02x\n", *ptr);
-                               break;
-                       }
-
-                       if (ptr[1] > total) { /* too long */
-                               for (i = 0; i < total; i++) {
-                                       printf("%02x ", ptr[i]);
-                               }
-                               break;
-                       }
-
-                       printf("%02x  %02x  ", ptr[0], ptr[1]);
-                       attrlen = ptr[1] - 2;
-                       ptr += 2;
-                       total -= 2;
-
-                       for (i = 0; i < attrlen; i++) {
-                               if ((i > 0) && ((i & 0x0f) == 0x00))
-                                       printf("\t\t\t");
-                               printf("%02x ", ptr[i]);
-                               if ((i & 0x0f) == 0x0f) printf("\n");
-                       }
-
-                       if ((attrlen & 0x0f) != 0x00) printf("\n");
-
-                       ptr += attrlen;
-                       total -= attrlen;
-               }
-       }
-       fflush(stdout);
-}
-
 /*
  *     Send one packet.
  */
 static int send_one_packet(radclient_t *radclient)
 {
+       int i;
+
        assert(radclient->done == 0);
 
        /*
@@ -490,33 +442,29 @@ static int send_one_packet(radclient_t *radclient)
         *      Haven't sent the packet yet.  Initialize it.
         */
        if (radclient->request->id == -1) {
-               int i, rcode;
+               int found = 0;
 
                assert(radclient->reply == NULL);
 
                /*
-                *      Didn't find a free packet ID, we're not done,
-                *      we don't sleep, and we stop trying to process
-                *      this packet.
+                *      Find a free packet Id
                 */
-       retry:
-               rcode = lrad_packet_list_id_alloc(pl, radclient->request);
-               if (rcode < 0) {
-                       int mysockfd;
-
-                       mysockfd = lrad_socket(&client_ipaddr, 0);
-                       if (!mysockfd) {
-                               fprintf(stderr, "radclient: Can't open new socket\n");
-                               exit(1);
-                       }
-                       if (!lrad_packet_list_socket_add(pl, mysockfd)) {
-                               fprintf(stderr, "radclient: Can't add new socket\n");
-                               exit(1);
+               for (i = 0; i < 256; i++) {
+                       if (radius_id[(last_used_id + i) & 0xff] == 0) {
+                               last_used_id = (last_used_id + i) & 0xff;
+                               radius_id[last_used_id] = 1;
+                               radclient->request->id = last_used_id++;
+                               found = 1;
+                               break;
                        }
-                       goto retry;
                }
 
-               if (rcode == 0) {
+               /*
+                *      Didn't find a free packet ID, we're not done,
+                *      we don't sleep, and we stop trying to process
+                *      this packet.
+                */
+               if (!found) {
                        done = 0;
                        sleep_time = 0;
                        return 0;
@@ -525,9 +473,8 @@ static int send_one_packet(radclient_t *radclient)
                assert(radclient->request->id != -1);
                assert(radclient->request->data == NULL);
 
-               for (i = 0; i < 4; i++) {
-                       *((uint32_t *) radclient->request->vector) = lrad_rand();
-               }
+               librad_md5_calc(radclient->request->vector, radclient->request->vector,
+                               sizeof(radclient->request->vector));
 
                /*
                 *      Update the password, so it can be encrypted with the
@@ -536,24 +483,15 @@ static int send_one_packet(radclient_t *radclient)
                if (radclient->password[0] != '\0') {
                        VALUE_PAIR *vp;
 
-                       if ((vp = pairfind(radclient->request->vps, PW_USER_PASSWORD)) != NULL) {
-                               strlcpy(vp->vp_strvalue, radclient->password,
-                                       sizeof(vp->vp_strvalue));
-                               vp->length = strlen(vp->vp_strvalue);
+                       if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
+                               strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
+                               vp->length = strlen(vp->strvalue);
 
                        } else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
-                         /*
-                          *    FIXME: AND there's no CHAP-Challenge,
-                          *           AND vp->length != 17
-                          *           AND rad_chap_encode() != vp->vp_octets
-                          */
-                               strlcpy(vp->vp_strvalue, radclient->password,
-                                       sizeof(vp->vp_strvalue));
-                               vp->length = strlen(vp->vp_strvalue);
-
-                               rad_chap_encode(radclient->request,
-                                               vp->vp_octets,
-                                               radclient->request->id, vp);
+                               strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
+                               vp->length = strlen(vp->strvalue);
+
+                               rad_chap_encode(radclient->request, (char *) vp->strvalue, radclient->request->id, vp);
                                vp->length = 17;
                        }
                }
@@ -565,11 +503,10 @@ static int send_one_packet(radclient_t *radclient)
                /*
                 *      Duplicate found.  Serious error!
                 */
-               if (!lrad_packet_list_insert(pl, &radclient->request)) {
+               if (rbtree_insert(request_tree, radclient) == 0) {
                        assert(0 == 1);
                }
 
-
        } else {                /* radclient->request->id >= 0 */
                time_t now = time(NULL);
 
@@ -600,17 +537,19 @@ static int send_one_packet(radclient_t *radclient)
                 *      We're not trying later, maybe the packet is done.
                 */
                if (radclient->tries == retries) {
+                       rbnode_t *node;
                        assert(radclient->request->id >= 0);
-
+                       
                        /*
                         *      Delete the request from the tree of
                         *      outstanding requests.
                         */
-                       lrad_packet_list_yank(pl, radclient->request);
-
-                       fprintf(stderr, "radclient: no response from server for ID %d socket %d\n", radclient->request->id, radclient->request->sockfd);
-                       deallocate_id(radclient);
-
+                       node = rbtree_find(request_tree, radclient);
+                       assert(node != NULL);
+                       
+                       fprintf(stderr, "radclient: no response from server for ID %d\n", radclient->request->id);
+                       rbtree_delete(request_tree, node);
+                       
                        /*
                         *      Normally we mark it "done" when we've received
                         *      the response, but this is a special case.
@@ -638,8 +577,6 @@ static int send_one_packet(radclient_t *radclient)
                        radclient->request->id, librad_errstr);
        }
 
-       if (librad_debug > 2) print_hex(radclient->request);
-
        return 0;
 }
 
@@ -650,15 +587,14 @@ static int recv_one_packet(int wait_time)
 {
        fd_set          set;
        struct timeval  tv;
-       radclient_t     *radclient;
-       RADIUS_PACKET   *reply, **request_p;
-       volatile int max_fd;
+       radclient_t     myclient, *radclient;
+       RADIUS_PACKET   myrequest, *reply;
+       rbnode_t        *node;
+
 
        /* And wait for reply, timing out as necessary */
        FD_ZERO(&set);
-
-       max_fd = lrad_packet_list_fd_set(pl, &set);
-       if (max_fd < 0) exit(1); /* no sockets to listen on! */
+       FD_SET(sockfd, &set);
 
        if (wait_time <= 0) {
                tv.tv_sec = 0;
@@ -670,55 +606,54 @@ static int recv_one_packet(int wait_time)
        /*
         *      No packet was received.
         */
-       if (select(max_fd, &set, NULL, NULL, &tv) <= 0) {
+       if (select(sockfd + 1, &set, NULL, NULL, &tv) != 1) {
                return 0;
        }
 
        /*
         *      Look for the packet.
         */
-       reply = lrad_packet_list_recv(pl, &set);
+       reply = rad_recv(sockfd);
        if (!reply) {
                fprintf(stderr, "radclient: received bad packet: %s\n",
                        librad_errstr);
                return -1;      /* bad packet */
        }
 
-       if (librad_debug > 2) print_hex(reply);
+       myclient.request = &myrequest;
+       myrequest.id = reply->id;
+       myrequest.dst_ipaddr = reply->src_ipaddr;
+       myrequest.dst_port = reply->src_port;
 
-       request_p = lrad_packet_list_find_byreply(pl, reply);
-       if (!request_p) {
-               fprintf(stderr, "radclient: received response to request we did not send. (id=%d socket %d)\n", reply->id, reply->sockfd);
+       node = rbtree_find(request_tree, &myclient);
+       if (!node) {
+               fprintf(stderr, "radclient: received response to request we did not send.\n");
                rad_free(&reply);
                return -1;      /* got reply to packet we didn't send */
        }
-       radclient = lrad_packet2myptr(radclient_t, request, request_p);
+
+       radclient = rbtree_node2data(request_tree, node);
+       assert(radclient != NULL);
+       rbtree_delete(request_tree, node);
+       assert(radclient->request->id == -1);
+       assert(radclient->request->data == NULL);
+
+       assert(radclient->reply == NULL);
+       radclient->reply = reply;
 
        /*
-        *      Fails the signature validation: not a real reply.
-        *      FIXME: Silently drop it and listen for another packet.
+        *      FIXME: Do stuff to process the reply.
         */
-       if (rad_verify(reply, radclient->request, secret) < 0) {
+       if (rad_verify(reply, radclient->request, secret) != 0) {
                librad_perror("rad_verify");
                totallost++;
                goto packet_done; /* shared secret is incorrect */
        }
 
-       lrad_packet_list_yank(pl, radclient->request);
-       if (print_filename) printf("%s:%d %d\n",
-                                  radclient->filename,
-                                  radclient->packet_number,
-                                  reply->code);
-       deallocate_id(radclient);
-       radclient->reply = reply;
-
-       /*
-        *      If this fails, we're out of memory.
-        */
        if (rad_decode(reply, radclient->request, secret) != 0) {
                librad_perror("rad_decode");
                totallost++;
-               goto packet_done;
+               goto packet_done; /* shared secret is incorrect */
        }
 
        /* libradius debug already prints out the value pairs for us */
@@ -734,21 +669,20 @@ static int recv_one_packet(int wait_time)
        }
 
 packet_done:
+       rad_free(&radclient->reply);
+
        /*
         *      Once we've sent the packet as many times as requested,
         *      mark it done.
         */
-       if ((radclient->done) ||
-           (radclient->resend == resend_count)) {
-               assert(lrad_packet_list_find(pl, radclient->request) == NULL);
+       if (radclient->resend == resend_count) {
+               assert((node = rbtree_find(request_tree, radclient)) == NULL);
                radclient->done = 1;
        }
-       rad_free(&radclient->reply);
 
        return 0;
 }
 
-
 static int getport(const char *name)
 {
        struct  servent         *svp;
@@ -772,7 +706,6 @@ int main(int argc, char **argv)
        int persec = 0;
        int parallel = 1;
        radclient_t     *this;
-       int force_af = AF_UNSPEC;
 
        librad_debug = 0;
 
@@ -782,13 +715,13 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       while ((c = getopt(argc, argv, "46c:d:f:Fhi:n:p:qr:sS:t:vx")) != EOF) switch(c) {
-               case '4':
-                       force_af = AF_INET;
-                       break;
-               case '6':
-                       force_af = AF_INET6;
-                       break;
+       request_tree = rbtree_create(request_cmp, request_free, 0);
+       if (!request_tree) {
+               fprintf(stderr, "radclient: Out of memory\n");
+               exit(1);
+       }
+
+       while ((c = getopt(argc, argv, "c:d:f:hi:n:p:qr:sS:t:vx")) != EOF) switch(c) {
                case 'c':
                        if (!isdigit((int) *optarg))
                                usage();
@@ -800,10 +733,7 @@ int main(int argc, char **argv)
                case 'f':
                        rbtree_insert(filename_tree, optarg);
                        break;
-               case 'F':
-                       print_filename = 1;
-                       break;
-               case 'i':       /* currently broken */
+               case 'i':
                        if (!isdigit((int) *optarg))
                                usage();
                        last_used_id = atoi(optarg);
@@ -817,13 +747,6 @@ int main(int argc, char **argv)
                        if (persec <= 0) usage();
                        break;
 
-                       /*
-                        *      Note that sending MANY requests in
-                        *      parallel can over-run the kernel
-                        *      queues, and Linux will happily discard
-                        *      packets.  So even if the server responds,
-                        *      the client may not see the response.
-                        */
                case 'p':
                        parallel = atoi(optarg);
                        if (parallel <= 0) usage();
@@ -900,45 +823,21 @@ int main(int argc, char **argv)
        }
 
        /*
-        *      Resolve hostname.
+        *      Strip port from hostname if needed.
         */
-       server_ipaddr.af = force_af;
-       if (strcmp(argv[1], "-") != 0) {
-               const char *hostname = argv[1];
-               const char *portname = argv[1];
-               char buffer[256];
-
-               if (*argv[1] == '[') { /* IPv6 URL encoded */
-                       p = strchr(argv[1], ']');
-                       if ((p - argv[1]) >= sizeof(buffer)) {
-                               usage();
-                       }
-
-                       memcpy(buffer, argv[1] + 1, p - argv[1] - 1);
-                       buffer[p - argv[1] - 1] = '\0';
-
-                       hostname = buffer;
-                       portname = p + 1;
-
-               }
-               p = strchr(portname, ':');
-               if (p && (strchr(p + 1, ':') == NULL)) {
-                       *p = '\0';
-                       portname = p + 1;
-               } else {
-                       portname = NULL;
-               }
-
-               if (ip_hton(hostname, force_af, &server_ipaddr) < 0) {
-                       fprintf(stderr, "radclient: Failed to find IP address for host %s: %s\n", hostname, strerror(errno));
-                       exit(1);
-               }
+       if ((p = strchr(argv[1], ':')) != NULL) {
+               *p++ = 0;
+               server_port = atoi(p);
+       }
 
-               /*
-                *      Strip port from hostname if needed.
-                */
-               if (portname) server_port = atoi(portname);
+       /*
+        *      Grab the socket.
+        */
+       if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("radclient: socket: ");
+               exit(1);
        }
+       memset(radius_id, 0, sizeof(radius_id));
 
        /*
         *      See what kind of request we want to send.
@@ -984,6 +883,15 @@ int main(int argc, char **argv)
        }
 
        /*
+        *      Resolve hostname.
+        */
+       server_ipaddr = ip_getaddr(argv[1]);
+       if (server_ipaddr == INADDR_NONE) {
+               fprintf(stderr, "radclient: Failed to find IP address for host %s\n", argv[1]);
+               exit(1);
+       }
+
+       /*
         *      Add the secret.
         */
        if (argv[3]) secret = argv[3];
@@ -1011,46 +919,17 @@ int main(int argc, char **argv)
        }
 
        /*
-        *      Bind to the first specified IP address and port.
-        *      This means we ignore later ones.
-        */
-       if (radclient_head->request->src_ipaddr.af == AF_UNSPEC) {
-               memset(&client_ipaddr, 0, sizeof(client_ipaddr));
-               client_ipaddr.af = server_ipaddr.af;
-               client_port = 0;
-       } else {
-               client_ipaddr = radclient_head->request->src_ipaddr;
-               client_port = radclient_head->request->src_port;
-       }
-       sockfd = lrad_socket(&client_ipaddr, client_port);
-       if (sockfd < 0) {
-               fprintf(stderr, "radclient: socket: %s\n", librad_errstr);
-               exit(1);
-       }
-
-       pl = lrad_packet_list_create(1);
-       if (!pl) {
-               fprintf(stderr, "radclient: Out of memory\n");
-               exit(1);
-       }
-
-       if (!lrad_packet_list_socket_add(pl, sockfd)) {
-               fprintf(stderr, "radclient: Out of memory\n");
-               exit(1);
-       }
-
-       /*
         *      Walk over the list of packets, sanity checking
         *      everything.
         */
        for (this = radclient_head; this != NULL; this = this->next) {
-               this->request->src_ipaddr = client_ipaddr;
-               this->request->src_port = client_port;
                if (radclient_sane(this) != 0) {
                        exit(1);
                }
        }
 
+       if (last_used_id < 0) last_used_id = getpid() & 0xff;
+
        /*
         *      Walk over the packets to send, until
         *      we're all done.
@@ -1131,7 +1010,7 @@ int main(int argc, char **argv)
                                                tv.tv_sec = 0;
                                                tv.tv_usec = 1000000/persec;
                                        }
-
+                                       
                                        /*
                                         *      Sleep for milliseconds,
                                         *      portably.
@@ -1162,7 +1041,7 @@ int main(int argc, char **argv)
                /*
                 *      Still have outstanding requests.
                 */
-               if (lrad_packet_list_num_elements(pl) > 0) {
+               if (rbtree_num_elements(request_tree) > 0) {
                        done = 0;
                } else {
                        sleep_time = 0;
@@ -1181,8 +1060,7 @@ int main(int argc, char **argv)
        } while (!done);
 
        rbtree_free(filename_tree);
-       lrad_packet_list_free(pl);
-       dict_free();
+       rbtree_free(request_tree);
 
        if (do_summary) {
                printf("\n\t   Total approved auths:  %d\n", totalapp);
index 20d64b0..7151a95 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Jochen Friedrich <jochen@scram.de>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] =
+"$Id$";
 
-#include <freeradius-devel/radiusd.h>
+#include "autoconf.h"
 
 #ifdef WITH_SNMP
 
-#include <freeradius-devel/smux.h>
-#include <freeradius-devel/radius_snmp.h>
+#include "libradius.h"
+
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#include <string.h>
+
+#include "smux.h"
+#include "radius_snmp.h"
+#include "radiusd.h"
+#include "conffile.h"
+
+extern int need_reload;
 
 /*
  *     More globals (sigh);
  */
 rad_snmp_t             rad_snmp;
 
-
-#define RADACCOID  1,3,6,1,2,1,67,2,1,1,1
+\f
+#define RADACCOID 1,3,6,1,2,1,67,2,1,1,1
 #define RADAUTHOID 1,3,6,1,2,1,67,1,1,1,1
-#define RADIUSOID  1,3,6,1,4,1,11344,1,1,1
+#define RADIUSOID 1,3,6,1,4,1,3317,1,3,1
 
-static const oid radacc_oid [] = { RADACCOID };
-static const oid radauth_oid [] = { RADAUTHOID };
-static const oid radius_oid [] = { RADIUSOID };
+static oid radacc_oid [] = { RADACCOID };
+static oid radauth_oid [] = { RADAUTHOID };
+static oid radius_oid [] = { RADIUSOID };
 
 #define COUNTER ASN_COUNTER
 #define INTEGER ASN_INTEGER
@@ -130,7 +142,7 @@ static const unsigned char *radAuthEntry(struct variable *vp,
        size_t  *var_len,
        WriteMethod **write_method);
 
-static const struct variable radiusacc_variables[] =
+static struct variable radiusacc_variables[] =
 {
        {RADIUSACCSERVIDENT, STRING, RONLY, radAccServ, 1, {1}},
        {RADIUSACCSERVUPTIME, TIMETICKS, RONLY, radAccServ, 1, {2}},
@@ -157,7 +169,7 @@ static const struct variable radiusacc_variables[] =
        {RADIUSACCSERVUNKNOWNTYPES, COUNTER, RONLY, radAccEntry, 3, {14,1,11}},
 };
 
-static const struct variable radiusauth_variables[] =
+static struct variable radiusauth_variables[] =
 {
        {RADIUSAUTHSERVIDENT, STRING, RONLY, radAuthServ, 1, {1}},
        {RADIUSAUTHSERVUPTIME, TIMETICKS, RONLY, radAuthServ, 1, {2}},
@@ -186,9 +198,10 @@ static const struct variable radiusauth_variables[] =
        {RADIUSAUTHSERVUNKNOWNTYPES, COUNTER, RONLY, radAuthEntry, 3, {15,1,12}},
 };
 
+\f
 static RADCLIENT *
-get_client(struct variable *v, oid objid[], size_t *objid_len, int exact)
-{
+get_client(struct variable *v, oid objid[], size_t *objid_len, int exact) {
+
        RADCLIENT *c;
        int i, len;
 
@@ -205,28 +218,39 @@ get_client(struct variable *v, oid objid[], size_t *objid_len, int exact)
                        return NULL;
 
                i = objid[v->namelen]-1;
-
-               return client_findbynumber(mainconfig.clients, i);
+               c = mainconfig.clients;
+               while (i && c)
+               {
+                       c = c->next;
+                       i--;
+               }
+               if (c)
+                       return c;
+               return NULL;
        }
+       i = objid[v->namelen]-1;
        *objid_len = v->namelen + 1;
        if (!len || (objid[v->namelen] == 0)) {
                objid[v->namelen]=1;
-               return client_findbynumber(mainconfig.clients, 0);
+               return mainconfig.clients;
+       }
+       c = mainconfig.clients->next;
+       while (i && c) {
+               c = c->next;
+               i--;
        }
-
-       i = objid[v->namelen]-1;
-       c = client_findbynumber(mainconfig.clients, i);
        if (c) {
                objid[v->namelen]++;
-       }
-       return c;
+               return c;
+       } else
+               return NULL;
 }
 
 static int
-radServReset(int action, u_char *var_val, u_char var_val_type,
-            size_t var_val_len, UNUSED const unsigned char *statP,
-            UNUSED oid *name, UNUSED size_t name_len)
-{
+radServReset (int action, u_char *var_val, u_char var_val_type,
+               size_t var_val_len, const unsigned char *statP, oid *name,
+               size_t name_len) {
+
        long i;
        int big = SNMP_MAX_LEN;
 
@@ -242,7 +266,7 @@ radServReset(int action, u_char *var_val, u_char var_val_type,
                                return SNMP_ERR_WRONGVALUE;
                        break;
                case COMMIT:
-                       radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
+                       need_reload = TRUE;
                        break;
                case FREE:
                        break;
@@ -331,7 +355,6 @@ radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
                size_t *var_len, WriteMethod **write_method) {
 
        RADCLIENT *c;
-       static const uint32_t zero = 0;
 
        *write_method = NULL; /* table is read only */
        c = get_client(vp, name, length, exact);
@@ -342,13 +365,11 @@ radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
 
        switch (vp->magic) {
                case RADIUSACCCLIENTADDRESS:
-                       if (c->ipaddr.af != AF_INET) return NULL;
-
-                       *var_len = sizeof(c->ipaddr.ipaddr.ip4addr);
-                       return (unsigned char *)&(c->ipaddr.ipaddr.ip4addr);
+                       *var_len = sizeof(c->ipaddr);
+                       return (unsigned char *)&(c->ipaddr);
 
                case RADIUSACCCLIENTID:
-                       if (c->shortname && c->shortname[0]) {
+                       if (strlen(c->shortname)) {
                                *var_len = strlen(c->shortname);
                                return c->shortname;
                        }
@@ -356,41 +377,29 @@ radAccEntry(struct variable *vp, oid *name, size_t *length, int exact,
                        return c->longname;
 
                case RADIUSACCSERVPACKETSDROPPED:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->packets_dropped;
+                       return (unsigned char *) NULL;
 
                case RADIUSACCSERVREQUESTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->requests;
+                       return (unsigned char *) NULL;
 
                case RADIUSACCSERVDUPREQUESTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->dup_requests;
+                       return (unsigned char *) NULL;
 
                case RADIUSACCSERVRESPONSES:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->responses;
+                       return (unsigned char *) NULL;
 
                case RADIUSACCSERVBADAUTHENTICATORS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->bad_authenticators;
+                       return (unsigned char *) NULL;
 
                case RADIUSACCSERVMALFORMEDREQUESTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->malformed_requests;
+                       return (unsigned char *) NULL;
 
-                       /*
-                        *      Received && responded to, but not
-                        *      recorded anywhere.  This is always
-                        *      zero.
-                        */
                case RADIUSACCSERVNORECORDS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &zero;
+                       return (unsigned char *) NULL;
 
                case RADIUSACCSERVUNKNOWNTYPES:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->acct->unknown_types;
+                       return (unsigned char *) NULL;
+
        }
        return NULL;
 }
@@ -410,6 +419,7 @@ radAuthServ(struct variable *vp, oid *name, size_t *length, int exact,
        /* return the current value of the variable */
 
        switch (vp->magic) {
+
                case RADIUSAUTHSERVIDENT:
                        *var_len = strlen(rad_snmp.auth.ident);
                        return (const unsigned char *) rad_snmp.auth.ident;
@@ -490,60 +500,49 @@ radAuthEntry(struct variable *vp, oid      *name, size_t *length, int exact,
        switch (vp->magic) {
 
                case RADIUSAUTHCLIENTADDRESS:
-                       if (c->ipaddr.af != AF_INET) return NULL;
-
-                       *var_len = sizeof(c->ipaddr.ipaddr.ip4addr);
-                       return (unsigned char *)&(c->ipaddr.ipaddr.ip4addr);
+                       *var_len = sizeof(c->ipaddr);
+                       return (unsigned char *)&(c->ipaddr);
 
                case RADIUSAUTHCLIENTID:
-                       if (c->shortname && c->shortname[0]) {
+                       if (strlen(c->shortname)) {
                                *var_len = strlen(c->shortname);
-                               return c->shortname;
+                                       return c->shortname;
                        }
-                       *var_len = strlen(c->longname);
+               *var_len = strlen(c->longname);
                        return c->longname;
 
                case RADIUSAUTHSERVACCESSREQUESTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->requests;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVDUPACCESSREQUESTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->dup_requests;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVACCESSACCEPTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->accepts;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVACCESSREJECTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->rejects;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVACCESSCHALLENGES:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->challenges;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVMALFORMEDACCESSREQUESTS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->malformed_requests;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVBADAUTHENTICATORS:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->bad_authenticators;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVPACKETSDROPPED:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->packets_dropped;
+                       return (unsigned char *) NULL;
 
                case RADIUSAUTHSERVUNKNOWNTYPES:
-                       *var_len = sizeof(int32_t);
-                       return (unsigned char *) &c->auth->unknown_types;
+                       return (unsigned char *) NULL;
 
        }
        return NULL;
 }
 
-static const CONF_PARSER snmp_config[] = {
+static CONF_PARSER snmp_config[] = {
        { "smux_password", PW_TYPE_STRING_PTR, 0, &rad_snmp.smux_password, "" },
        { "snmp_write_access",  PW_TYPE_BOOLEAN, 0, &rad_snmp.snmp_write_access, "no" },
        { NULL, -1, 0, NULL, NULL }
@@ -556,34 +555,29 @@ radius_snmp_init (void) {
 
        CONF_SECTION *cs;
 
-       static int initialized = FALSE;
-
-       if (!initialized) {
-               /*
-                *  Initialize the RADIUS SNMP data structure.
-                */
-               memset(&rad_snmp, 0, sizeof(rad_snmp));
-
-               rad_snmp.auth.ident = radiusd_version;
-               rad_snmp.acct.ident = radiusd_version;
-
-               rad_snmp.smux_event = SMUX_NONE;
-               rad_snmp.smux_password = NULL;
-               rad_snmp.snmp_write_access = FALSE;
-               rad_snmp.smux_fd = -1;
-               rad_snmp.smux_max_failures = 3; /* FIXME! get from config */
-               rad_snmp.smux_failures = 0;
-
-               rad_snmp.auth.start_time = time(NULL);
-               rad_snmp.auth.last_reset_time = rad_snmp.auth.start_time;
-
-               rad_snmp.acct.start_time = rad_snmp.auth.start_time;
-               rad_snmp.acct.last_reset_time = rad_snmp.auth.start_time;
-       } else {
-               rad_snmp.auth.last_reset_time = time(NULL);
-               rad_snmp.acct.last_reset_time = rad_snmp.auth.last_reset_time;
-               rad_snmp.smux_failures = 0;
-       }
+       /*
+        *  Initialize the RADIUS SNMP data structure.
+        */
+       memset(&rad_snmp, 0, sizeof(rad_snmp));
+
+       rad_snmp.auth.ident = radiusd_version;
+       rad_snmp.acct.ident = radiusd_version;
+
+       rad_snmp.smux_event = SMUX_NONE;
+       rad_snmp.smux_password = NULL;
+       rad_snmp.snmp_write_access = FALSE;
+       rad_snmp.smux_fd = -1;
+       rad_snmp.smux_max_failures = 3; /* FIXME! get from config */
+       rad_snmp.smux_failures = 0;
+
+       /*
+        *  We really should get better clock resolution..
+        */
+       rad_snmp.auth.start_time = time(NULL);
+       rad_snmp.auth.last_reset_time = rad_snmp.auth.start_time;
+
+       rad_snmp.acct.start_time = rad_snmp.auth.start_time;
+       rad_snmp.acct.last_reset_time = rad_snmp.auth.start_time;
 
        /*
         *  Parse the SNMP configuration information.
@@ -592,23 +586,13 @@ radius_snmp_init (void) {
        if (cs != NULL)
                cf_section_parse(cs, NULL, snmp_config);
 
-       smux_stop();
-
-       if (!mainconfig.do_snmp) return;
-
        /*
         *  Do SMUX initialization.
         */
        smux_init (radius_oid, sizeof (radius_oid) / sizeof (oid));
-
-       if (!initialized) {
-               SMUX_REGISTER_MIB("mibII/radius-acc-server", radiusacc_variables, variable, radacc_oid);
-               SMUX_REGISTER_MIB("mibII/radius-auth-server", radiusauth_variables, variable, radauth_oid);
-       }
-
+       REGISTER_MIB("mibII/radius-acc-server", radiusacc_variables, variable, radacc_oid);
+       REGISTER_MIB("mibII/radius-auth-server", radiusauth_variables, variable, radauth_oid);
        smux_start ();
-
-       initialized = TRUE;
 }
 
 #endif /* WITH_SNMP */
index eeccf68..3066ffd 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000-2004,2006  The FreeRADIUS server project
+ * Copyright 2000,2001,2002,2003,2004  The FreeRADIUS server project
  * Copyright 1999,2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2000  Alan Curry <pacman-radius@cqc.com>
  * Copyright 2000  Chad Miller <cmiller@surfsouth.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+/* don't look here for the version, run radiusd -v or look in version.c */
+static const char rcsid[] =
+"$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/radius_snmp.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
 
 #include <sys/file.h>
 
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
 
+#ifdef HAVE_UNISTD_H
+#      include <unistd.h>
+#endif
+
 #include <signal.h>
 
 #ifdef HAVE_GETOPT_H
 #      include <getopt.h>
 #endif
 
+#ifdef HAVE_SYS_SELECT_H
+#      include <sys/select.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#      include <syslog.h>
+#endif
+
 #ifdef HAVE_SYS_WAIT_H
 #      include <sys/wait.h>
 #endif
@@ -53,6 +71,13 @@ RCSID("$Id$")
 #      define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 #endif
 
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "conffile.h"
+#include "modules.h"
+#include "request_list.h"
+#include "radius_snmp.h"
+
 /*
  *  Global variables.
  */
@@ -60,24 +85,27 @@ const char *progname = NULL;
 const char *radius_dir = NULL;
 const char *radacct_dir = NULL;
 const char *radlog_dir = NULL;
+radlog_dest_t radlog_dest = RADLOG_FILES;
 const char *radlib_dir = NULL;
+int syslog_facility;
 int log_stripped_names;
 int debug_flag = 0;
 int log_auth_detail = FALSE;
-
-
+int need_reload = FALSE;
+int sig_hup_block = FALSE;
 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
 
-time_t time_now;
+static time_t time_now;
 static pid_t radius_pid;
-static int debug_memory = 0;
-static int has_detail_listener = FALSE;
-
-static int radius_self_pipe[2];
 
 /*
  *  Configuration items.
  */
+static int dont_fork = FALSE;
+static time_t start_time = 0;
+static int spawn_flag = TRUE;
+static int do_exit = 0;
+static int debug_memory = 0;
 
 /*
  *     Static functions.
@@ -87,30 +115,694 @@ static void usage(int);
 static void sig_fatal (int);
 static void sig_hup (int);
 
+static int rad_status_server(REQUEST *request);
+
+/*
+ *  Parse a string into a syslog facility level.
+ */
+static int str2fac(const char *s)
+{
+#ifdef LOG_KERN
+       if(!strcmp(s, "kern"))
+               return LOG_KERN;
+       else
+#endif
+#ifdef LOG_USER
+       if(!strcmp(s, "user"))
+               return LOG_USER;
+       else
+#endif
+#ifdef LOG_MAIL
+       if(!strcmp(s, "mail"))
+               return LOG_MAIL;
+       else
+#endif
+#ifdef LOG_DAEMON
+       if(!strcmp(s, "daemon"))
+               return LOG_DAEMON;
+       else
+#endif
+#ifdef LOG_AUTH
+       if(!strcmp(s, "auth"))
+               return LOG_AUTH;
+       else
+#endif
+#ifdef LOG_SYSLOG
+       if(!strcmp(s, "auth"))
+               return LOG_AUTH;
+       else
+#endif
+#ifdef LOG_LPR
+       if(!strcmp(s, "lpr"))
+               return LOG_LPR;
+       else
+#endif
+#ifdef LOG_NEWS
+       if(!strcmp(s, "news"))
+               return LOG_NEWS;
+       else
+#endif
+#ifdef LOG_UUCP
+       if(!strcmp(s, "uucp"))
+               return LOG_UUCP;
+       else
+#endif
+#ifdef LOG_CRON
+       if(!strcmp(s, "cron"))
+               return LOG_CRON;
+       else
+#endif
+#ifdef LOG_AUTHPRIV
+       if(!strcmp(s, "authpriv"))
+               return LOG_AUTHPRIV;
+       else
+#endif
+#ifdef LOG_FTP
+       if(!strcmp(s, "ftp"))
+               return LOG_FTP;
+       else
+#endif
+#ifdef LOG_LOCAL0
+       if(!strcmp(s, "local0"))
+               return LOG_LOCAL0;
+       else
+#endif
+#ifdef LOG_LOCAL1
+       if(!strcmp(s, "local1"))
+               return LOG_LOCAL1;
+       else
+#endif
+#ifdef LOG_LOCAL2
+       if(!strcmp(s, "local2"))
+               return LOG_LOCAL2;
+       else
+#endif
+#ifdef LOG_LOCAL3
+       if(!strcmp(s, "local3"))
+               return LOG_LOCAL3;
+       else
+#endif
+#ifdef LOG_LOCAL4
+       if(!strcmp(s, "local4"))
+               return LOG_LOCAL4;
+       else
+#endif
+#ifdef LOG_LOCAL5
+       if(!strcmp(s, "local5"))
+               return LOG_LOCAL5;
+       else
+#endif
+#ifdef LOG_LOCAL6
+       if(!strcmp(s, "local6"))
+               return LOG_LOCAL6;
+       else
+#endif
+#ifdef LOG_LOCAL7
+       if(!strcmp(s, "local7"))
+               return LOG_LOCAL7;
+       else
+#endif
+       {
+               fprintf(stderr, "%s: Error: Unknown syslog facility: %s\n",
+                       progname, s);
+               exit(1);
+       }
+
+       /* this should never be reached */
+       return LOG_DAEMON;
+}
+
+
+/*
+ *     Check if an incoming request is "ok"
+ *
+ *     It takes packets, not requests.  It sees if the packet looks
+ *     OK.  If so, it does a number of sanity checks on it.
+  */
+static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
+                                 rad_listen_t *listener)
+{
+       REQUEST         *curreq;
+       RAD_REQUEST_FUNP fun = NULL;
+
+       /*
+        *      Some sanity checks, based on the packet code.
+        */
+       switch(packet->code) {
+               case PW_AUTHENTICATION_REQUEST:
+                       /*
+                        *      Check for requests sent to the wrong
+                        *      port, and ignore them, if so.
+                        */
+                       if (listener->type != RAD_LISTEN_AUTH) {
+                               RAD_SNMP_INC(rad_snmp.auth.total_packets_dropped);
+                               radlog(L_ERR, "Authentication-Request sent to a non-authentication port from "
+                                       "client %s:%d - ID %d : IGNORED",
+                                       client_name(packet->src_ipaddr),
+                                      packet->src_port, packet->id);
+                               return NULL;
+                       }
+                       fun = rad_authenticate;
+                       break;
+
+               case PW_ACCOUNTING_REQUEST:
+                       /*
+                        *      Check for requests sent to the wrong
+                        *      port, and ignore them, if so.
+                        */
+                       if (listener->type != RAD_LISTEN_ACCT) {
+                               RAD_SNMP_INC(rad_snmp.acct.total_packets_dropped);
+                               radlog(L_ERR, "Accounting-Request packet sent to a non-accounting port from "
+                                      "client %s:%d - ID %d : IGNORED",
+                                      client_name(packet->src_ipaddr),
+                                      packet->src_port, packet->id);
+                               return NULL;
+                       }
+                       fun = rad_accounting;
+                       break;
+
+               case PW_AUTHENTICATION_ACK:
+               case PW_ACCESS_CHALLENGE:
+               case PW_AUTHENTICATION_REJECT:
+                       /*
+                        *      Replies NOT sent to the proxy port get
+                        *      an error message logged, and the
+                        *      packet is dropped.
+                        */
+                       if (listener->type != RAD_LISTEN_PROXY) {
+                               RAD_SNMP_INC(rad_snmp.auth.total_packets_dropped);
+                               radlog(L_ERR, "Authentication reply packet code %d sent to a non-proxy reply port from "
+                                      "client %s:%d - ID %d : IGNORED",
+                                      packet->code,
+                                      client_name(packet->src_ipaddr),
+                                      packet->src_port, packet->id);
+                               return NULL;
+                       }
+                       fun = rad_authenticate;
+                       break;
+
+               case PW_ACCOUNTING_RESPONSE:
+                       /*
+                        *      Replies NOT sent to the proxy port get
+                        *      an error message logged, and the
+                        *      packet is dropped.
+                        */
+                       if (listener->type != RAD_LISTEN_PROXY) {
+                               RAD_SNMP_INC(rad_snmp.acct.total_packets_dropped);
+                               radlog(L_ERR, "Accounting reply packet code %d sent to a non-proxy reply port from "
+                                      "client %s:%d - ID %d : IGNORED",
+                                      packet->code,
+                                      client_name(packet->src_ipaddr),
+                                      packet->src_port, packet->id);
+                               return 0;
+                       }
+                       fun = rad_accounting;
+                       break;
+
+               case PW_STATUS_SERVER:
+                       if (!mainconfig.status_server) {
+                               DEBUG("WARNING: Ignoring Status-Server request due to security configuration");
+                               return NULL;
+                       }
+                       fun = rad_status_server;
+                       break;
+
+               case PW_PASSWORD_REQUEST:
+                       RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
+
+                       /*
+                        *  We don't support this anymore.
+                        */
+                       radlog(L_ERR, "Deprecated password change request from client %s:%d - ID %d : IGNORED",
+                                       client_name(packet->src_ipaddr),
+                              packet->src_port, packet->id);
+                       return NULL;
+                       break;
+
+               default:
+                       RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);
+
+                       radlog(L_ERR, "Unknown packet code %d from client %s:%d "
+                              "- ID %d : IGNORED", packet->code,
+                              client_name(packet->src_ipaddr),
+                              packet->src_port, packet->id);
+                       return NULL;
+                       break;
+
+       } /* switch over packet types */
+
+       /*
+        *      Don't handle proxy replies here.  They need to
+        *      return the *old* request, so we can re-process it.
+        */
+       if (listener->type == RAD_LISTEN_PROXY) {
+               return fun;
+       }
+
+       /*
+        *      If there is no existing request of id, code, etc.,
+        *      then we can return, and let it be processed.
+        */
+       if ((curreq = rl_find(packet)) == NULL) {
+               /*
+                *      Count the total number of requests, to see if
+                *      there are too many.  If so, return with an
+                *      error.
+                */
+               if (mainconfig.max_requests) {
+                       int request_count = rl_num_requests();
+
+                       /*
+                        *      This is a new request.  Let's see if
+                        *      it makes us go over our configured
+                        *      bounds.
+                        */
+                       if (request_count > mainconfig.max_requests) {
+                               radlog(L_ERR, "Dropping request (%d is too many): "
+                                      "from client %s:%d - ID: %d", request_count,
+                                      client_name(packet->src_ipaddr),
+                                      packet->src_port, packet->id);
+                               radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n"
+                                      "\tThe value for 'max_requests' is probably set too low.\n");
+                               return NULL;
+                       } /* else there were a small number of requests */
+               } /* else there was no configured limit for requests */
+
+               /*
+                *      FIXME: Add checks for system load.  If the
+                *      system is busy, start dropping requests...
+                *
+                *      We can probably keep some statistics
+                *      ourselves...  if there are more requests
+                *      coming in than we can handle, start dropping
+                *      some.
+                */
+
+               return fun;
+       }
+
+       /*
+        *      "fake" requests MUST NEVER be in the request list.
+        *
+        *      They're used internally in the server.  Any reply
+        *      is a reply to the local server, and any proxied packet
+        *      gets sent outside of the tunnel.
+        */
+       rad_assert((curreq->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0);
+
+       /*
+        *      The current request isn't finished, which
+        *      means that the NAS sent us a new packet, while
+        *      we are still processing the old request.
+        */
+       if (!curreq->finished) {
+               /*
+                *      If the authentication vectors are identical,
+                *      then the NAS is re-transmitting it, trying to
+                *      kick us into responding to the request.
+                */
+               if (memcmp(curreq->packet->vector, packet->vector,
+                          sizeof(packet->vector)) == 0) {
+                       RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
+
+                       /*
+                        *      It's not finished because the request
+                        *      was proxied, but there was no reply
+                        *      from the home server.
+                        */
+                       if (curreq->proxy && !curreq->proxy_reply) {
+                               /*
+                                *      We're taking care of sending
+                                *      duplicate proxied packets, so
+                                *      we ignore any duplicate
+                                *      requests from the NAS.
+                                *
+                                *      FIXME: Make it ALWAYS synchronous!
+                                */
+                               if (!mainconfig.proxy_synchronous) {
+                                       RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
+
+                                       DEBUG2("Ignoring duplicate packet from client "
+                                              "%s:%d - ID: %d, due to outstanding proxied request %d.",
+                                              client_name(packet->src_ipaddr),
+                                              packet->src_port, packet->id,
+                                              curreq->number);
+                                       return NULL;
+
+                                       /*
+                                        *      We ARE proxying the request,
+                                        *      and we have NOT received a
+                                        *      proxy reply yet, and we ARE
+                                        *      doing synchronous proxying.
+                                        *
+                                        *      In that case, go kick
+                                        *      the home RADIUS server
+                                        *      again.
+                                        */
+                               } else {
+                                       char buffer[64];
+
+                                       DEBUG2("Sending duplicate proxied request to home server %s:%d - ID: %d",
+                                              ip_ntoa(buffer, curreq->proxy->dst_ipaddr),
+                                              curreq->proxy->dst_port,
+
+                                              curreq->proxy->id);
+                               }
+                               curreq->proxy_next_try = time_now + mainconfig.proxy_retry_delay;
+                               rad_send(curreq->proxy, curreq->packet,
+                                        curreq->proxysecret);
+                               return NULL;
+                       } /* else the packet was not proxied */
+
+                       /*
+                        *      Someone's still working on it, so we
+                        *      ignore the duplicate request.
+                        */
+                       radlog(L_ERR, "Discarding duplicate request from "
+                              "client %s:%d - ID: %d due to unfinished request %d",
+                              client_name(packet->src_ipaddr),
+                              packet->src_port, packet->id,
+                              curreq->number);
+                       return NULL;
+               } /* else the authentication vectors were different */
+
+               /*
+                *      The authentication vectors are different, so
+                *      the NAS has given up on us, as we've taken too
+                *      long to process the request.  This is a
+                *      SERIOUS problem!
+                */
+               RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
+
+               radlog(L_ERR, "Dropping conflicting packet from "
+                      "client %s:%d - ID: %d due to unfinished request %d",
+                      client_name(packet->src_ipaddr),
+                      packet->src_port, packet->id,
+                      curreq->number);
+               return NULL;
+       }
+
+       /*
+        *      The old request is finished.  We now check the
+        *      authentication vectors.  If the client has sent us a
+        *      request with identical code && ID, but different
+        *      vector, then they MUST have gotten our response, so we
+        *      can delete the original request, and process the new
+        *      one.
+        *
+        *      If the vectors are the same, then it's a duplicate
+        *      request, and we can send a duplicate reply.
+        */
+       if (memcmp(curreq->packet->vector, packet->vector,
+                  sizeof(packet->vector)) == 0) {
+               RAD_SNMP_INC(rad_snmp.auth.total_dup_requests);
+
+               /*
+                *      If the packet has been delayed, then silently
+                *      send a response, and clear the delayed flag.
+                *
+                *      Note that this means if the NAS kicks us while
+                *      we're delaying a reject, then the reject may
+                *      be sent sooner than otherwise.
+                *
+                *      This COULD be construed as a bug.  Maybe what
+                *      we want to do is to ignore the duplicate
+                *      packet, and send the reject later.
+                */
+               if (curreq->options & RAD_REQUEST_OPTION_DELAYED_REJECT) {
+                       curreq->options &= ~RAD_REQUEST_OPTION_DELAYED_REJECT;
+                       rad_send(curreq->reply, curreq->packet, curreq->secret);
+                       return NULL;
+               }
+
+               /*
+                *      Maybe we've saved a reply packet.  If so,
+                *      re-send it.  Otherwise, just complain.
+                */
+               if (curreq->reply->code != 0) {
+                       DEBUG2("Sending duplicate reply "
+                              "to client %s:%d - ID: %d",
+                              client_name(packet->src_ipaddr),
+                              packet->src_port, packet->id);
+                       rad_send(curreq->reply, curreq->packet, curreq->secret);
+                       return NULL;
+               }
+
+               /*
+                *      Else we never sent a reply to the NAS,
+                *      as we decided somehow we didn't like the request.
+                *
+                *      This shouldn't happen, in general...
+                */
+               DEBUG2("Discarding duplicate request from client %s:%d - ID: %d",
+                      client_name(packet->src_ipaddr),
+                      packet->src_port, packet->id);
+               return NULL;
+       } /* else the vectors were different, so we discard the old request. */
+
+       /*
+        *      'packet' has the same source IP, source port, code,
+        *      and Id as 'curreq', but a different authentication
+        *      vector.  We can therefore delete 'curreq', as we were
+        *      only keeping it around to send out duplicate replies,
+        *      if the first reply got lost in the network.
+        */
+       rl_delete(curreq);
+
+       /*
+        *      The request is OK.  We can process it...
+        *
+        *      Don't bother checking the maximum nubmer of requests
+        *      here.  we've just deleted one, so we KNOW we're under
+        *      the limit if we add one more.
+        */
+       return fun;
+}
+
+
+/*
+ *  Do a proxy check of the REQUEST list when using the new proxy code.
+ */
+static REQUEST *proxy_ok(RADIUS_PACKET *packet)
+{
+       REALM *cl;
+       REQUEST *oldreq;
+       char buffer[32];
+
+       /*
+        *      Find the original request in the request list
+        */
+       oldreq = rl_find_proxy(packet);
+
+       /*
+        *      If we haven't found the original request which was
+        *      sent, to get this reply.  Complain, and discard this
+        *      request, as there's no way for us to send it to a NAS.
+        */
+       if (!oldreq) {
+               radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s:%d - ID %d",
+                      ip_ntoa(buffer, packet->src_ipaddr),
+                      packet->src_port, packet->id);
+               return NULL;
+       }
+
+       /*
+        *      The proxy reply has arrived too late, as the original
+        *      (old) request has timed out, been rejected, and marked
+        *      as finished.  The client has already received a
+        *      response, so there is nothing that can be done. Delete
+        *      the tardy reply from the home server, and return NULL.
+        */
+       if ((oldreq->reply->code != 0) ||
+           (oldreq->finished)) {
+               radlog(L_ERR, "Reply from home server %s:%d  - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
+                      ip_ntoa(buffer, packet->src_ipaddr),
+                      packet->src_port, packet->id,
+                      oldreq->number);
+               return NULL;
+       }
+
+       /*
+        *      If there is already a reply, maybe this one is a
+        *      duplicate?
+        */
+       if (oldreq->proxy_reply) {
+               if (memcmp(oldreq->proxy_reply->vector,
+                          packet->vector,
+                          sizeof(oldreq->proxy_reply->vector)) == 0) {
+                       radlog(L_ERR, "Discarding duplicate reply from home server %s:%d  - ID: %d for request %d",
+                              ip_ntoa(buffer, packet->src_ipaddr),
+                              packet->src_port, packet->id,
+                              oldreq->number);
+               } else {
+                       /*
+                        *      ? The home server gave us a new *
+                        *      proxy reply, which doesn't match * the
+                        *      old one.  Delete it
+                        !  */
+                       DEBUG2("Ignoring conflicting proxy reply");
+               }
+
+               /*
+                *      We've already received a reply, so
+                *      we discard this one, as we don't want
+                *      to do duplicate work.
+                */
+               return NULL;
+       } /* else there wasn't a proxy reply yet, so we can process it */
+
+       /*
+        *       Refresh the old request, and update it with the proxy
+        *       reply.
+        *
+        *      ? Can we delete the proxy request here?  * Is there
+        *      any more need for it?
+        *
+        *      FIXME: we probably shouldn't be updating the time
+        *      stamp here.
+        */
+       oldreq->timestamp = time_now;
+       oldreq->proxy_reply = packet;
+
+       /*
+        *      Now that we've verified the packet IS actually
+        *      from that realm, and not forged, we can go mark the
+        *      realms for this home server as active.
+        *
+        *      If we had done this check in the 'find realm by IP address'
+        *      function, then an attacker could force us to use a home
+        *      server which was inactive, by forging reply packets
+        *      which didn't match any request.  We would think that
+        *      the reply meant the home server was active, would
+        *      re-activate the realms, and THEN bounce the packet
+        *      as garbage.
+        */
+       for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
+               if (oldreq->proxy_reply->src_ipaddr == cl->ipaddr) {
+                       if (oldreq->proxy_reply->src_port == cl->auth_port) {
+                               cl->active = TRUE;
+                               cl->last_reply = oldreq->timestamp;
+                       } else if (oldreq->proxy_reply->src_port == cl->acct_port) {
+                               cl->acct_active = TRUE;
+                               cl->last_reply = oldreq->timestamp;
+                       }
+               }
+       }
+
+       return oldreq;
+}
+
+/*
+ *     Do more checks, this time on the REQUEST data structure.
+ *
+ *     The main purpose of this code is to handle proxied requests.
+ */
+static REQUEST *request_ok(RADIUS_PACKET *packet, uint8_t *secret,
+                          rad_listen_t *listener)
+{
+       REQUEST         *request = NULL;
+
+       /*
+        *      If the request has come in on the proxy FD, then
+        *      it's a proxy reply, so pass it through the code which
+        *      tries to find the original request, which we should
+        *      process, rather than processing the reply as a "new"
+        *      request.
+        */
+       if (listener->type == RAD_LISTEN_PROXY) {
+               /*
+                *      Find the old request, based on the current
+                *      packet.
+                */
+               request = proxy_ok(packet);
+               if (!request) {
+                       return NULL;
+               }
+               rad_assert(request->magic == REQUEST_MAGIC);
+
+               /*
+                *      We must have passed through the code below
+                *      for the original request, which adds the
+                *      reply packet to it.
+                */
+               rad_assert(request->reply != NULL);
+
+       } else {                /* remember the new request */
+               /*
+                *      A unique per-request counter.
+                */
+               static int request_num_counter = 0;
+
+               request = request_alloc(); /* never fails */
+               request->packet = packet;
+               request->number = request_num_counter++;
+               strNcpy(request->secret, (char *)secret,
+                       sizeof(request->secret));
+
+               /*
+                *      Remember the request.
+                */
+               rl_add(request);
+
+               /*
+                *      ADD IN "server identifier" from "listen"
+                *      directive!
+                */
+
+               /*
+                *      The request passes many of our sanity checks.
+                *      From here on in, if anything goes wrong, we
+                *      send a reject message, instead of dropping the
+                *      packet.
+                *
+                *      Build the reply template from the request
+                *      template.
+                */
+               rad_assert(request->reply == NULL);
+               if ((request->reply = rad_alloc(0)) == NULL) {
+                       radlog(L_ERR, "No memory");
+                       exit(1);
+               }
+               request->reply->sockfd = request->packet->sockfd;
+               request->reply->dst_ipaddr = request->packet->src_ipaddr;
+               request->reply->src_ipaddr = request->packet->dst_ipaddr;
+               request->reply->dst_port = request->packet->src_port;
+               request->reply->src_port = request->packet->dst_port;
+               request->reply->id = request->packet->id;
+               request->reply->code = 0; /* UNKNOWN code */
+               memcpy(request->reply->vector, request->packet->vector,
+                      sizeof(request->reply->vector));
+               request->reply->vps = NULL;
+               request->reply->data = NULL;
+               request->reply->data_len = 0;
+       }
+
+       return request;
+}
+
+
 /*
  *     The main guy.
  */
 int main(int argc, char *argv[])
 {
        REQUEST *request;
+       RADIUS_PACKET *packet;
+       u_char *secret;
        unsigned char buffer[4096];
        fd_set readfds;
        int argval;
        int pid;
        int max_fd;
        int status;
-       int dont_fork = FALSE;
-       int spawn_flag = TRUE;
-       int sig_hup_block = FALSE;
-       struct timeval tv, *ptv = NULL;
-       int read_from_detail = FALSE;
-       int fd_flags;
-
+       struct timeval *tv = NULL;
 #ifdef HAVE_SIGACTION
        struct sigaction act;
 #endif
        rad_listen_t *listener;
 
+       syslog_facility = LOG_DAEMON;
+
 #ifdef OSFC2
        set_auth_parameters(argc,argv);
 #endif
@@ -128,25 +820,14 @@ int main(int argc, char *argv[])
         *      Ensure that the configuration is initialized.
         */
        memset(&mainconfig, 0, sizeof(mainconfig));
-       mainconfig.myip.af = AF_UNSPEC;
-       mainconfig.port = -1;
-       mainconfig.radiusd_conf = strdup("radiusd.conf");
-
 #ifdef HAVE_SIGACTION
        memset(&act, 0, sizeof(act));
        act.sa_flags = 0 ;
        sigemptyset( &act.sa_mask ) ;
 #endif
 
-       /*
-        *      Don't put output anywhere until we get told a little
-        *      more.
-        */
-       mainconfig.radlog_fd = -1;
-       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:bcd:fg:hi:l:mp:sSvxXyz")) != EOF) {
 
                switch(argval) {
 
@@ -155,7 +836,7 @@ int main(int argc, char *argv[])
                                break;
 
                        case 'a':
-                               if (radacct_dir) free(radacct_dir);
+                               if (radacct_dir) xfree(radacct_dir);
                                radacct_dir = strdup(optarg);
                                break;
 
@@ -164,7 +845,7 @@ int main(int argc, char *argv[])
                                break;
 
                        case 'd':
-                               if (radius_dir) free(radius_dir);
+                               if (radius_dir) xfree(radius_dir);
                                radius_dir = strdup(optarg);
                                break;
 
@@ -177,55 +858,35 @@ int main(int argc, char *argv[])
                                break;
 
                        case 'i':
-                               if (ip_hton(optarg, AF_UNSPEC, &mainconfig.myip) < 0) {
-                                       fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
+                               if ((mainconfig.myip = ip_getaddr(optarg)) == INADDR_NONE) {
+                                       fprintf(stderr, "radiusd: %s: host unknown\n",
+                                               optarg);
                                        exit(1);
                                }
                                break;
 
                        case 'l':
-                               if ((strcmp(optarg, "stdout") == 0) ||
-                                   (strcmp(optarg, "stderr") == 0) ||
-                                   (strcmp(optarg, "syslog") == 0)) {
-                                       fprintf(stderr, "radiusd: -l %s is unsupported.  Use log_destination in radiusd.conf\n", optarg);
-                                       exit(1);
-                               }
-                               if (radlog_dir) free(radlog_dir);
                                radlog_dir = strdup(optarg);
                                break;
 
+                               /*
+                                *  We should also have this as a configuration
+                                *  file directive.
+                                */
                        case 'g':
-                               fprintf(stderr, "radiusd: -g is unsupported.  Use log_destination in radiusd.conf.\n");
-                               exit(1);
+                               syslog_facility = str2fac(optarg);
                                break;
 
                        case 'm':
                                debug_memory = 1;
                                break;
 
-                       case 'n':
-                               if ((strchr(optarg, '/') != NULL) ||
-                                   (strchr(optarg, '.') != NULL) ||
-                                   (strlen(optarg) > 45)) usage(1);
-
-                               snprintf(buffer, sizeof(buffer), "%s.conf",
-                                        optarg);
-                               if (mainconfig.radiusd_conf)
-                                       free(mainconfig.radiusd_conf);
-                               mainconfig.radiusd_conf = strdup(buffer);
-                               break;
-
                        case 'S':
                                log_stripped_names++;
                                break;
 
                        case 'p':
-                               mainconfig.port = atoi(optarg);
-                               if ((mainconfig.port <= 0) ||
-                                   (mainconfig.port >= 65536)) {
-                                       fprintf(stderr, "radiusd: Invalid port number %s\n", optarg);
-                                       exit(1);
-                               }
+                               fprintf(stderr, "Ignoring deprecated command-line option -p");
                                break;
 
                        case 's':       /* Single process mode */
@@ -248,8 +909,7 @@ int main(int argc, char *argv[])
                                mainconfig.log_auth = TRUE;
                                mainconfig.log_auth_badpass = TRUE;
                                mainconfig.log_auth_goodpass = TRUE;
-                               mainconfig.radlog_dest = RADLOG_STDOUT;
-                               mainconfig.radlog_fd = STDOUT_FILENO;
+                               radlog_dir = strdup("stdout");
                                break;
 
                        case 'x':
@@ -272,15 +932,10 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (debug_flag) {
-               radlog(L_INFO, "%s", radiusd_version);
-               radlog(L_INFO, "Copyright (C) 2000-2007 The FreeRADIUS server project.\n");
-               radlog(L_INFO, "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n");
-               radlog(L_INFO, "PARTICULAR PURPOSE.\n");
-               radlog(L_INFO, "You may redistribute copies of FreeRADIUS under the terms of the\n");
-               radlog(L_INFO, "GNU General Public License.\n");
-               fflush(NULL);
-       }
+       /*
+        *      Get our PID.
+        */
+       radius_pid = getpid();
 
        /*  Read the configuration files, BEFORE doing anything else.  */
        if (read_mainconfig(0) < 0) {
@@ -288,6 +943,61 @@ int main(int argc, char *argv[])
        }
 
        /*
+        *      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
+       }
+
+       /*  Reload the modules.  */
+       DEBUG2("radiusd:  entering modules setup");
+       if (setup_modules() < 0) {
+               radlog(L_ERR|L_CONS, "Errors setting up modules");
+               exit(1);
+       }
+
+#ifdef HAVE_SYSLOG_H
+       /*
+        *  If they asked for syslog, then give it to them.
+        *  Also, initialize the logging facility with the
+        *  configuration that they asked for.
+        */
+       if (strcmp(radlog_dir, "syslog") == 0) {
+               openlog(progname, LOG_PID, syslog_facility);
+               radlog_dest = RADLOG_SYSLOG;
+       }
+       /* Do you want a warning if -g is used without a -l to activate it? */
+#endif
+       if (strcmp(radlog_dir, "stdout") == 0) {
+               radlog_dest = RADLOG_STDOUT;
+       } else if (strcmp(radlog_dir, "stderr") == 0) {
+               radlog_dest = RADLOG_STDERR;
+       }
+
+       /*  Initialize the request list.  */
+       rl_init();
+
+       /*
+        *  Register built-in compare functions.
+        */
+       pair_builtincompare_init();
+
+#ifdef WITH_SNMP
+       if (mainconfig.do_snmp) radius_snmp_init();
+#endif
+
+       /*
         *  Disconnect from session
         */
        if (debug_flag == 0 && dont_fork == FALSE) {
@@ -300,7 +1010,7 @@ int main(int argc, char *argv[])
                /*
                 *  The parent exits, so the child can run in the background.
                 */
-               if (pid > 0) {
+               if(pid > 0) {
                        exit(0);
                }
 #ifdef HAVE_SETSID
@@ -309,29 +1019,12 @@ int main(int argc, char *argv[])
        }
 
        /*
-        *      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.
         */
        radius_pid = getpid();
 
+
        /*
         *  Only write the PID file if we're running as a daemon.
         *
@@ -357,30 +1050,10 @@ int main(int argc, char *argv[])
        }
 
        /*
-        *      Child threads need a pipe to signal us, as do the
-        *      signal handlers.
-        */
-       if (pipe(radius_self_pipe) < 0) {
-               radlog(L_ERR, "radiusd: Error opening internal pipe: %s",
-                      strerror(errno));
-               exit(1);
-       }
-       if (fcntl(radius_self_pipe[0], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
-               radlog(L_ERR, "radiusd: Error setting internal flags: %s",
-                      strerror(errno));
-               exit(1);
-       }
-       if (fcntl(radius_self_pipe[1], F_SETFL, O_NONBLOCK | FD_CLOEXEC) < 0) {
-               radlog(L_ERR, "radiusd: Error setting internal flags: %s",
-                      strerror(errno));
-               exit(1);
-       }
-
-       /*
         *      If we're running as a daemon, close the default file
         *      descriptors, AFTER forking.
         */
-       if (!debug_flag) {
+       if (debug_flag == FALSE) {
                int devnull;
 
                devnull = open("/dev/null", O_RDWR);
@@ -390,22 +1063,24 @@ int main(int argc, char *argv[])
                        exit(1);
                }
                dup2(devnull, STDIN_FILENO);
-               if (mainconfig.radlog_dest == RADLOG_STDOUT) {
-                       mainconfig.radlog_fd = dup(STDOUT_FILENO);
-               }
                dup2(devnull, STDOUT_FILENO);
-               if (mainconfig.radlog_dest == RADLOG_STDERR) {
-                       mainconfig.radlog_fd = dup(STDERR_FILENO);
-               }
                dup2(devnull, STDERR_FILENO);
                close(devnull);
        }
 
+#ifdef HAVE_PTHREAD_H
        /*
-        *      It's called the thread pool, but it does a little
-        *      more than that.
+        *  If we're spawning children, set up the thread pool.
         */
-       radius_event_init(spawn_flag);
+       if (spawn_flag == TRUE) {
+               thread_pool_init();
+       }
+#else
+       /*
+        *      Without threads, we ALWAYS run in single-server mode.
+        */
+       spawn_flag = FALSE;
+#endif
 
        /*
         *  Use linebuffered or unbuffered stdout if
@@ -420,28 +1095,26 @@ int main(int argc, char *argv[])
        for (listener = mainconfig.listen;
             listener != NULL;
             listener = listener->next) {
-               listener->print(listener, buffer, sizeof(buffer));
+               if (listener->ipaddr == INADDR_ANY) {
+                       strcpy((char *)buffer, "*");
+               } else {
+                       ip_ntoa((char *)buffer, listener->ipaddr);
+               }
+               
                switch (listener->type) {
                case RAD_LISTEN_AUTH:
-                       DEBUG("Listening on authentication address %s", buffer);
+                       DEBUG("Listening on authentication %s:%d",
+                             buffer, listener->port);
                        break;
 
                case RAD_LISTEN_ACCT:
-                       DEBUG("Listening on accounting address %s", buffer);
+                       DEBUG("Listening on accounting %s:%d",
+                             buffer, listener->port);
                        break;
 
                case RAD_LISTEN_PROXY:
-                       DEBUG("Listening on proxy address %s", buffer);
-                       break;
-
-               case RAD_LISTEN_DETAIL:
-                       has_detail_listener = TRUE;
-                       read_from_detail = TRUE;
-                       DEBUG("Listening on detail file %s", buffer);
-                       break;
-
-               case RAD_LISTEN_SNMP:
-                       DEBUG("Listening on SNMP %s", buffer);
+                       DEBUG("Listening on proxy %s:%d",
+                             buffer, listener->port);
                        break;
 
                default:
@@ -480,14 +1153,111 @@ int main(int argc, char *argv[])
 #endif
        }
 
- restart:
        radlog(L_INFO, "Ready to process requests.");
+       start_time = time(NULL);
 
        /*
         *  Receive user requests
         */
        for (;;) {
-               ssize_t rcode;
+               /*
+                *      If we've been told to exit, then do so,
+                *      even if we have data waiting.
+                */
+               if (do_exit) {
+                       DEBUG("Exiting...");
+
+                       /*
+                        *      Ignore the TERM signal: we're about
+                        *      to die.
+                        */
+                       signal(SIGTERM, SIG_IGN);
+
+                       /*
+                        *      Send a TERM signal to all associated
+                        *      processes (including us, which gets
+                        *      ignored.)
+                        */
+                       kill(-radius_pid, SIGTERM);
+
+                       /*
+                        *      FIXME: Kill child threads, and
+                        *      clean up?
+                        */
+
+                       /*
+                        *      Detach any modules.
+                        */
+                       detach_modules();
+
+                       /*
+                        *      FIXME: clean up any active REQUEST
+                        *      handles.
+                        */
+
+                       /*
+                        *      We're exiting, so we can delete the PID
+                        *      file.  (If it doesn't exist, we can ignore
+                        *      the error returned by unlink)
+                        */
+                       if (dont_fork == FALSE) {
+                               unlink(mainconfig.pid_file);
+                       }
+
+                       /*
+                        *      Free the configuration items.
+                        */
+                       free_mainconfig();
+                       free(radius_dir);
+
+                       /*
+                        *      SIGTERM gets do_exit=0,
+                        *      and we want to exit cleanly.
+                        *
+                        *      Other signals make us exit
+                        *      with an error status.
+                        */
+                       exit(do_exit - 1);
+               }
+
+               if (need_reload) {
+#ifdef HAVE_PTHREAD_H
+                       /*
+                        *      Threads: wait for all threads to stop
+                        *      processing before re-loading the
+                        *      config, so we don't pull the rug out
+                        *      from under them.
+                        */
+                       int max_wait = 0;
+                       if (spawn_flag) for(;;) {
+                               /*
+                                * Block until there are '0' threads
+                                * with a REQUEST handle.
+                                */
+                               sig_hup_block = TRUE;
+                               if( (total_active_threads() == 0) ||
+                                    (max_wait >= 5) ) {
+                                 sig_hup_block = FALSE;
+                                 break;
+                               }
+                               sleep(1);
+                               max_wait++;
+                       }
+#endif
+                       if (read_mainconfig(TRUE) < 0) {
+                               exit(1);
+                       }
+
+                       /*  Reload the modules.  */
+                       DEBUG2("radiusd:  entering modules setup");
+                       if (setup_modules() < 0) {
+                               radlog(L_ERR|L_CONS, "Errors setting up modules");
+                               exit(1);
+                       }
+
+                       need_reload = FALSE;
+                       radlog(L_INFO, "Ready to process requests.");
+               }
 
                FD_ZERO(&readfds);
                max_fd = 0;
@@ -498,39 +1268,36 @@ int main(int argc, char *argv[])
                for (listener = mainconfig.listen;
                     listener != NULL;
                     listener = listener->next) {
-                       if (listener->fd < 0) continue;
-
-                       if (!read_from_detail &&
-                           (listener->type == RAD_LISTEN_DETAIL)) continue;
-
                        FD_SET(listener->fd, &readfds);
                        if (listener->fd > max_fd) max_fd = listener->fd;
                }
 
-               /*
-                *      Add in the self pipe FD, for signals or
-                *      notices from the child threads.
-                */
-               FD_SET(radius_self_pipe[0], &readfds);
-               if (radius_self_pipe[0] > max_fd) {
-                       max_fd = radius_self_pipe[0];
-               }
-
-               if (!ptv) {
-                       DEBUG2("Nothing to do.  Sleeping until we see a request.");
-               } else if (tv.tv_sec) {
-                               DEBUG2("Waking up in %d seconds...",
-                                      (int) tv.tv_sec);
+#ifdef WITH_SNMP
+               if (mainconfig.do_snmp &&
+                   (rad_snmp.smux_fd >= 0)) {
+                       FD_SET(rad_snmp.smux_fd, &readfds);
+                       if (rad_snmp.smux_fd > max_fd) max_fd = rad_snmp.smux_fd;
                }
-
-               status = select(max_fd + 1, &readfds, NULL, NULL, ptv);
-               if ((status < 0) && (errno != EINTR)) {
+#endif
+               status = select(max_fd + 1, &readfds, NULL, NULL, tv);
+               if (status == -1) {
+                       /*
+                        *      On interrupts, we clean up the request
+                        *      list.  We then continue with the loop,
+                        *      so that if we're supposed to exit,
+                        *      then the code at the start of the loop
+                        *      catches that, and exits.
+                        */
+                       if (errno == EINTR) {
+                               tv = rl_clean_list(time(NULL));
+                               continue;
+                       }
                        radlog(L_ERR, "Unexpected error in select(): %s",
-                              strerror(errno));
-                               exit(1);
+                                       strerror(errno));
+                       exit(1);
                }
-               time_now = time(NULL);
 
+               time_now = time(NULL);
 #ifndef HAVE_PTHREAD_H
                /*
                 *      If there are no child threads, then there may
@@ -544,206 +1311,606 @@ int main(int argc, char *argv[])
 #endif
 
                /*
-                *      Before doing anything else, check the self pipe.
+                *      Loop over the open socket FD's, reading any data.
                 */
-               if (FD_ISSET(radius_self_pipe[0], &readfds) &&
-                   (rcode = read(radius_self_pipe[0], buffer, sizeof(buffer))) > 0) {
-                       ssize_t i;
+               for (listener = mainconfig.listen;
+                    listener != NULL;
+                    listener = listener->next) {
+                       RAD_REQUEST_FUNP fun;
 
-                       for (i = 1; i < rcode; i++) {
-                               buffer[0] |= buffer[i];
+                       if (!FD_ISSET(listener->fd, &readfds))
+                               continue;
+                       /*
+                        *  Receive the packet.
+                        */
+                       if (sig_hup_block != FALSE) {
+                         continue;
+                       }
+                       packet = rad_recv(listener->fd);
+                       if (packet == NULL) {
+                               radlog(L_ERR, "%s", librad_errstr);
+                               continue;
                        }
 
-                       if ((buffer[0] & (RADIUS_SIGNAL_SELF_EXIT | RADIUS_SIGNAL_SELF_TERM)) != 0) {
-                               DEBUG("Exiting...");
-
-                               /*
-                                *      Ignore the TERM signal: we're
-                                *      about to die.
-                                */
-                               signal(SIGTERM, SIG_IGN);
+                       /*
+                        *      If the destination IP is unknown, check
+                        *      if the listener has a known IP.  If so,
+                        *      use that.
+                        */
+                       if ((packet->dst_ipaddr == htonl(INADDR_ANY)) &&
+                           (packet->dst_ipaddr != listener->ipaddr)) {
+                               packet->dst_ipaddr = listener->ipaddr;
+                       }
 
-                               /*
-                                *      Send a TERM signal to all
-                                *      associated processes
-                                *      (including us, which gets
-                                *      ignored.)
-                                */
-                               kill(-radius_pid, SIGTERM);
+                       /*
+                        *      Fill in the destination port.
+                        */
+                       packet->dst_port = listener->port;
 
-                               /*
-                                *      FIXME: Kill child threads, and
-                                *      clean up?
-                                */
+                       RAD_SNMP_TYPE_INC(listener, total_requests);
 
-                               /*
-                                *      FIXME: clean up any active REQUEST
-                                *      handles.
-                                */
+                       /*
+                        *      FIXME: Move this next check into
+                        *      the packet_ok() function, and add
+                        *      a 'secret' to the RAIDUS_PACKET
+                        *      data structure.  This involves changing
+                        *      a bunch of code, but it's probably the
+                        *      best thing to do.
+                        */
 
-                               /*
-                                *      We're exiting, so we can delete the PID
-                                *      file.  (If it doesn't exist, we can ignore
-                                *      the error returned by unlink)
-                                */
-                               if (dont_fork == FALSE) {
-                                       unlink(mainconfig.pid_file);
+                       /*
+                        *  Check if we know this client for
+                        *  authentication and accounting.  Check if we know
+                        *  this proxy for proxying.
+                        */
+                       if (listener->type != RAD_LISTEN_PROXY) {
+                               RADCLIENT *cl;
+                               if ((cl = client_find(packet->src_ipaddr)) == NULL) {
+                                       RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
+
+                                       radlog(L_ERR, "Ignoring request from unknown client %s:%d",
+                                       ip_ntoa((char *)buffer, packet->src_ipaddr),
+                                       packet->src_port);
+                                       rad_free(&packet);
+                                       continue;
+                               }
+                               secret = cl->secret;
+                       } else {    /* It came in on the proxy port */
+                               REALM *rl;
+                               if ((rl = realm_findbyaddr(packet->src_ipaddr,packet->src_port)) == NULL) {
+                                       radlog(L_ERR, "Ignoring request from unknown home server %s:%d",
+                                       ip_ntoa((char *)buffer, packet->src_ipaddr),
+                                       packet->src_port);
+                                       rad_free(&packet);
+                                       continue;
                                }
-
-                               radius_event_free();
-
-                               /*
-                                *      Free the configuration items.
-                                */
-                               free_mainconfig();
 
                                /*
-                                *      Detach any modules.
+                                *      The secret isn't needed here,
+                                *      as it's already in the old request
                                 */
-                               detach_modules();
-
-                               free(radius_dir);
+                               secret = NULL;
+                       }
 
-                               /*
-                                *      SIGTERM gets do_exit=0,
-                                *      and we want to exit cleanly.
-                                *
-                                *      Other signals make us exit
-                                *      with an error status.
-                                */
-                               if ((buffer[0] & RADIUS_SIGNAL_SELF_EXIT) != 0) {
-                                       exit(1);
-                               }
-                               exit(0);
-                       } /* else exit/term flags weren't set */
+                       /*
+                        *      Do some simple checks before we process
+                        *      the request.
+                        */
+                       if ((fun = packet_ok(packet, listener)) == NULL) {
+                               rad_free(&packet);
+                               continue;
+                       }
+                       
+                       /*
+                        *      Allocate a new request for packets from
+                        *      our clients, OR find the old request,
+                        *      for packets which are replies from a home
+                        *      server.
+                        */
+                       request = request_ok(packet, secret, listener);
+                       if (!request) {
+                               rad_free(&packet);
+                               continue;
+                       }
 
-                       if ((buffer[0] & RADIUS_SIGNAL_SELF_HUP) != 0) {
-                               DEBUG("Received HUP signal");
+                       /*
+                        *      Drop the request into the thread pool,
+                        *      and let the thread pool take care of
+                        *      doing something with it.
+                        */
 #ifdef HAVE_PTHREAD_H
-                               /*
-                                *      Threads: wait for all threads to stop
-                                *      processing before re-loading the
-                                *      config, so we don't pull the rug out
-                                *      from under them.
-                                */
-                               int max_wait = 0;
-                               if (spawn_flag) for(;;) {
+                       if (spawn_flag) {
+                               if (!thread_pool_addrequest(request, fun)) {
                                        /*
-                                        *      Block until there are
-                                        *      zero threads with a
-                                        *      REQUEST handle.
-                                        *
-                                        *      FIXME: Wait for
-                                        *      threads to send us a
-                                        *      signal in the pipe?
+                                        *      FIXME: Maybe just drop
+                                        *      the packet on the floor?
                                         */
-                                       sig_hup_block = TRUE;
-
-                                       if( (total_active_threads() == 0) ||
-                                           (max_wait >= 5) ) {
-                                               sig_hup_block = FALSE;
-                                               break;
-                                       }
-                                       sleep(1);
-                                       max_wait++;
+                                       request_reject(request);
+                                       request->finished = TRUE;
                                }
+                       } else
 #endif
+                         {
+                                 rad_respond(request, fun);
+
+                                 /*
+                                  *    Requests that care about child
+                                  *    process exit codes have already
+                                  *    either called rad_waitpid(), or
+                                  *    they've given up.
+                                  */
+                                 wait(NULL);
+                         }
+               } /* loop over listening sockets*/
 
 #ifdef WITH_SNMP
-                               if (mainconfig.do_snmp) {
-                                       rad_snmp.smux_failures = 0;
-                                       rad_snmp.smux_event = SMUX_CONNECT;
-                               }
-#endif
-                               if (read_mainconfig(TRUE) < 0) {
-                                       exit(1);
-                               }
-
-                               goto restart;
+               if (mainconfig.do_snmp) {
+                       /*
+                        *  After handling all authentication/accounting
+                        *  requests, THEN process any pending SMUX/SNMP
+                        *  queries.
+                        *
+                        *  Note that the handling is done in the main server,
+                        *  which probably isn't a Good Thing.  It really
+                        *  should be wrapped, and handled in a thread pool.
+                        */
+                       if ((rad_snmp.smux_fd >= 0) &&
+                           FD_ISSET(rad_snmp.smux_fd, &readfds) &&
+                           (rad_snmp.smux_event == SMUX_READ)) {
+                               smux_read();
                        }
 
                        /*
-                        *      Check if we can read from the detail file
+                        *  If we've got to re-connect, then do so now,
+                        *  before calling select again.
                         */
-                       if (has_detail_listener &&
-                           (buffer[0] & RADIUS_SIGNAL_SELF_DETAIL) != 0) {
-                               DEBUG3("Can now read from detail file(s)");
-                               read_from_detail = TRUE;
+                       if (rad_snmp.smux_event == SMUX_CONNECT) {
+                               smux_connect();
                        }
-               } /* else the self pipe didn't have data ready */
+               }
+#endif
 
                /*
-                *      Loop over the open socket FD's, reading any data.
+                *  After processing all new requests,
+                *  check if we've got to delete old requests
+                *  from the request list.
                 */
-               for (listener = mainconfig.listen;
-                    listener != NULL;
-                    listener = listener->next) {
-                       RAD_REQUEST_FUNP fun;
+               tv = rl_clean_list(time_now);
+#ifdef HAVE_PTHREAD_H
 
-                       if ((listener->fd >= 0) &&
-                           !FD_ISSET(listener->fd, &readfds))
-                               continue;
+               /*
+                *      Only clean the thread pool if we're spawning
+                *      child threads. 
+                */
+               if (spawn_flag) {
+                       thread_pool_clean(time_now);
+               }
+#endif
+
+
+       } /* loop forever */
+}
+
+
+/*
+ * FIXME:  The next two functions should all
+ * be in a module.  But not until we have
+ * more control over module execution.
+ * -jcarneal
+ */
+
+/*
+ *  Lowercase the string value of a pair.
+ */
+static int rad_lowerpair(REQUEST *request UNUSED, VALUE_PAIR *vp) {
+       if (vp == NULL) {
+               return -1;
+       }
+
+       rad_lowercase((char *)vp->strvalue);
+       DEBUG2("rad_lowerpair:  %s now '%s'", vp->name, vp->strvalue);
+       return 0;
+}
+
+/*
+ *  Remove spaces in a pair.
+ */
+static int rad_rmspace_pair(REQUEST *request UNUSED, VALUE_PAIR *vp) {
+       if (vp == NULL) {
+               return -1;
+       }
+
+       rad_rmspace((char *)vp->strvalue);
+       vp->length = strlen((char *)vp->strvalue);
+       DEBUG2("rad_rmspace_pair:  %s now '%s'", vp->name, vp->strvalue);
+
+       return 0;
+}
+
+/*
+ *  Respond to a request packet.
+ *
+ *  Maybe we reply, maybe we don't.
+ *  Maybe we proxy the request to another server, or else maybe
+ *  we replicate it to another server.
+ */
+int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
+{
+       RADIUS_PACKET *packet, *original;
+       const char *secret;
+       int finished = FALSE;
+       int reprocess = 0;
+
+       rad_assert(request->magic == REQUEST_MAGIC);
+
+       /*
+        *      Don't decode the packet if it's an internal "fake"
+        *      request.  Instead, just skip ahead to processing it.
+        */
+       if ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) {
+               goto skip_decode;
+       }
+
+       /*
+        *  Put the decoded packet into it's proper place.
+        */
+       if (request->proxy_reply != NULL) {
+               packet = request->proxy_reply;
+               secret = request->proxysecret;
+               original = request->proxy;
+       } else {
+               packet = request->packet;
+               secret = request->secret;
+               original = NULL;
+       }
+
+       /*
+        *  Decode the packet, verifying it's signature,
+        *  and parsing the attributes into structures.
+        *
+        *  Note that we do this CPU-intensive work in
+        *  a child thread, not the master.  This helps to
+        *  spread the load a little bit.
+        *
+        *  Internal requests (ones that never go on the
+        *  wire) have ->data==NULL (data is the wire
+        *  format) and don't need to be "decoded"
+        */
+       if (packet->data) {
+               if (rad_verify(packet, original, secret) < 0) {
+                       radlog(L_ERR, "%s Dropping packet without response.", librad_errstr);
+                       /* Since accounting packets get this set in
+                        * request_reject but no response is sent...
+                        */
+                       request->options |= RAD_REQUEST_OPTION_REJECTED;
+                       goto finished_request;
+               }
+
+               if (rad_decode(packet, original, secret) < 0) {
+                       radlog(L_ERR, "%s", librad_errstr);
+                       request_reject(request);
+                       goto finished_request;
+               }
+       }
+
+       /*
+        *  For proxy replies, remove non-allowed
+        *  attributes from the list of VP's.
+        */
+       if (request->proxy) {
+               int rcode;
+               rcode = proxy_receive(request);
+               switch (rcode) {
+                default:  /* Don't Do Anything */
+                       break;
+                case RLM_MODULE_FAIL:
+                       /* on error just continue with next request */
+                       goto next_request;
+                case RLM_MODULE_HANDLED:
+                       /* if this was a replicated request, mark it as
+                        * finished first, because it was postponed
+                        */
+                       goto finished_request;
+               }
+
+       } else {
+               /*
+                *      This is the initial incoming request which
+                *      we're processing.
+                *
+                *      Some requests do NOT get cached, as they
+                *      CANNOT possibly have duplicates.  Set the
+                *      magic option here.
+                *
+                *      Status-Server messages are easy to generate,
+                *      so we toss them as soon as we see a reply.
+                *
+                *      Accounting-Request packets WITHOUT an
+                *      Acct-Delay-Time attribute are NEVER
+                *      duplicated, as RFC 2866 Section 4.1 says that
+                *      the Acct-Delay-Time MUST be updated when the
+                *      packet is re-sent, which means the packet
+                *      changes, so it MUST have a new identifier and
+                *      Request Authenticator.  */
+               if ((request->packet->code == PW_STATUS_SERVER) ||
+                   ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
+                    (pairfind(request->packet->vps, PW_ACCT_DELAY_TIME) == NULL))) {
+                       request->options |= RAD_REQUEST_OPTION_DONT_CACHE;
+               }
+       }
+
+ skip_decode:
+       /*
+        *      We should have a User-Name attribute now.
+        */
+       if (request->username == NULL) {
+               request->username = pairfind(request->packet->vps,
+                               PW_USER_NAME);
+       }
+
+       /*
+        *  FIXME:  All this lowercase/nospace junk will be moved
+        *  into a module after module failover is fully in place
+        *
+        *  See if we have to lower user/pass before processing
+        */
+       if(strcmp(mainconfig.do_lower_user, "before") == 0)
+               rad_lowerpair(request, request->username);
+       if(strcmp(mainconfig.do_lower_pass, "before") == 0)
+               rad_lowerpair(request,
+                             pairfind(request->packet->vps, PW_PASSWORD));
+
+       if(strcmp(mainconfig.do_nospace_user, "before") == 0)
+               rad_rmspace_pair(request, request->username);
+       if(strcmp(mainconfig.do_nospace_pass, "before") == 0)
+               rad_rmspace_pair(request,
+                                pairfind(request->packet->vps, PW_PASSWORD));
+
+       (*fun)(request);
+
+       /*
+        *      If the request took too long to process, don't do
+        *      anything else.
+        */
+       if (request->options & RAD_REQUEST_OPTION_REJECTED) {
+               finished = TRUE;
+               goto postpone_request;
+       }
+
+       /*
+        *      Reprocess if we rejected last time
+        */
+       if ((fun == rad_authenticate) &&
+           (request->reply->code == PW_AUTHENTICATION_REJECT)) {
+         /* See if we have to lower user/pass after processing */
+         if (strcmp(mainconfig.do_lower_user, "after") == 0) {
+                 rad_lowerpair(request, request->username);
+                 reprocess = 1;
+         }
+         if (strcmp(mainconfig.do_lower_pass, "after") == 0) {
+               rad_lowerpair(request,
+                             pairfind(request->packet->vps, PW_PASSWORD));
+               reprocess = 1;
+         }
+         if (strcmp(mainconfig.do_nospace_user, "after") == 0) {
+                 rad_rmspace_pair(request, request->username);
+                 reprocess = 1;
+         }
+         if (strcmp(mainconfig.do_nospace_pass, "after") == 0) {
+                 rad_rmspace_pair(request,
+                                  pairfind(request->packet->vps, PW_PASSWORD));
+                 reprocess = 1;
+         }
+
+         /*
+          *    If we're re-processing the request, re-set it.
+          */
+         if (reprocess) {
+                 pairfree(&request->config_items);
+                 pairfree(&request->reply->vps);
+                 request->reply->code = 0;
+                 (*fun)(request);
+         }
+       }
+
+       /*
+        *      Status-Server requests NEVER get proxied.
+        */
+       if (mainconfig.proxy_requests) {
+               if ((request->packet->code != PW_STATUS_SERVER) &&
+                   ((request->options & RAD_REQUEST_OPTION_PROXIED) == 0)) {
+                       int rcode;
 
                        /*
-                        *  Receive the packet.
+                        *      Try to proxy this request.
                         */
-                       if (sig_hup_block != FALSE) {
-                               continue;
-                       }
+                       rcode = proxy_send(request);
+
+                       switch (rcode) {
+                       default:
+                               break;
 
                        /*
-                        *      Do per-socket receive processing of
-                        *      the packet.  This also takes care of
-                        *      inserting the request into the event
-                        *      tree, and adding it to the queue for
-                        *      threads.
+                        *  There was an error trying to proxy the request.
+                        *  Drop it on the floor.
                         */
-                       if (!listener->recv(listener, &fun, &request)) {
-                               continue;
-                       }
+                       case RLM_MODULE_FAIL:
+                               DEBUG2("Error trying to proxy request %d: Rejecting it", request->number);
+                               request_reject(request);
+                               goto finished_request;
+                               break;
 
                        /*
-                        *      Drop the request into the thread pool,
-                        *      and let the thread pool take care of
-                        *      doing something with it.
+                        *  The pre-proxy module has decided to reject
+                        *  the request.  Do so.
                         */
-                       if (!thread_pool_addrequest(request, fun)) {
-                               request->child_state = REQUEST_DONE;
-                       }
+                       case RLM_MODULE_REJECT:
+                               DEBUG2("Request %d rejected in proxy_send.", request->number);
+                               request_reject(request);
+                               goto finished_request;
+                               break;
 
                        /*
-                        *      If we've read a packet from a socket
-                        *      OTHER than the detail file, we start
-                        *      ignoring the detail file.
-                        *
-                        *      When the child thread pulls the
-                        *      request off of the queues, it will
-                        *      check if the queues are empty.  Once
-                        *      all queues are empty, it will signal
-                        *      us to read the detail file again.
-                        */
-                       if (spawn_flag &&
-                           (listener->type != RAD_LISTEN_DETAIL)) {
-                               read_from_detail = FALSE;
+                        *  If the proxy code has handled the request,
+                        *  then postpone more processing, until we get
+                        *  the reply packet from the home server.
+                        */
+                       case RLM_MODULE_HANDLED:
+                               goto postpone_request;
+                               break;
                        }
-               } /* loop over listening sockets*/
 
-               ptv = &tv;
-               radius_event_process(&ptv);
+                       /*
+                        *  Else rcode==RLM_MODULE_NOOP
+                        *  and the proxy code didn't do anything, so
+                        *  we continue handling the request here.
+                        */
+               }
+       } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
+                  (request->reply->code == 0)) {
+               /*
+                *  We're not configured to reply to the packet,
+                *  and we're not proxying, so the DEFAULT behaviour
+                *  is to REJECT the user.
+                */
+               DEBUG2("There was no response configured: rejecting request %d", request->number);
+               request_reject(request);
+               goto finished_request;
+       }
+
+       /*
+        *  If we have a reply to send, copy the Proxy-State
+        *  attributes from the request to the tail of the reply,
+        *  and send the packet.
+        */
+       rad_assert(request->magic == REQUEST_MAGIC);
+       if (request->reply->code != 0) {
+               VALUE_PAIR *vp = NULL;
 
-#ifdef HAVE_PTHREAD_H
+               /*
+                *      Perform RFC limitations on outgoing replies.
+                */
+               rfc_clean(request->reply);
 
                /*
-                *      Only clean the thread pool if we're spawning
-                *      child threads.
+                *      Need to copy Proxy-State from request->packet->vps
+                */
+               vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
+               if (vp) pairadd(&(request->reply->vps), vp);
+
+               /*
+                *  If the request isn't an authentication reject, OR
+                *  it's a reject, but the reject_delay is zero, then
+                *  send it immediately.
                 *
-                *      FIXME: Move this to the event handler!
+                *  Otherwise, delay the authentication reject to shut
+                *  up DoS attacks.
                 */
-               if (spawn_flag) {
-                       thread_pool_clean(time_now);
+               if ((request->reply->code != PW_AUTHENTICATION_REJECT) ||
+                   (mainconfig.reject_delay == 0)) {
+                       /*
+                        *      Send the response. IF it's a real request.
+                        */
+                       if ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0) {
+                               rad_send(request->reply, request->packet,
+                                        request->secret);
+                       }
+                       /*
+                        *      Otherwise, it's a tunneled request.
+                        *      Don't do anything.
+                        */
+               } else {
+                       DEBUG2("Delaying request %d for %d seconds",
+                              request->number, mainconfig.reject_delay);
+                       request->options |= RAD_REQUEST_OPTION_DELAYED_REJECT;
+               }
+       }
+
+       /*
+        *  We're done processing the request, set the
+        *  request to be finished, clean up as necessary,
+        *  and forget about the request.
+        */
+
+finished_request:
+
+       /*
+        *      Don't decode the packet if it's an internal "fake"
+        *      request.  Instead, just skip ahead to processing it.
+        */
+       if ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) {
+               goto skip_free;
+       }
+
+       /*
+        *  We're done handling the request.  Free up the linked
+        *  lists of value pairs.  This might take a long time,
+        *  so it's more efficient to do it in a child thread,
+        *  instead of in the main handler when it eventually
+        *  gets around to deleting the request.
+        *
+        *  Also, no one should be using these items after the
+        *  request is finished, and the reply is sent.  Cleaning
+        *  them up here ensures that they're not being used again.
+        *
+        *  Hmm... cleaning them up in the child thread also seems
+        *  to make the server run more efficiently!
+        *
+        *  If we've delayed the REJECT, then do NOT clean up the request,
+        *  as we haven't created the REJECT message yet.
+        */
+       if ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) == 0) {
+               if (request->packet) {
+                       pairfree(&request->packet->vps);
+                       request->username = NULL;
+                       request->password = NULL;
+               }
+
+               /*
+                *  If we've sent a reply to the NAS, then this request is
+                *  pretty much finished, and we have no more need for any
+                *  of the value-pair's in it, including the proxy stuff.
+                */
+               if (request->reply->code != 0) {
+                       pairfree(&request->reply->vps);
                }
+       }
+
+       pairfree(&request->config_items);
+       if (request->proxy) {
+               pairfree(&request->proxy->vps);
+       }
+       if (request->proxy_reply) {
+               pairfree(&request->proxy_reply->vps);
+       }
+
+ skip_free:
+       DEBUG2("Finished request %d", request->number);
+       finished = TRUE;
+
+       /*
+        *  Go to the next request, without marking
+        *  the current one as finished.
+        *
+        *  Hmm... this may not be the brightest thing to do.
+        */
+next_request:
+       DEBUG2("Going to the next request");
+
+postpone_request:
+#ifdef HAVE_PTHREAD_H
+       /*
+        *  We are finished with the child thread.  The thread is detached,
+        *  so that when it exits, there's nothing more for the server
+        *  to do.
+        *
+        *  If we're running with thread pools, then this frees up the
+        *  thread in the pool for another request.
+        */
+       request->child_pid = NO_SUCH_CHILD_PID;
 #endif
-       } /* loop forever */
+       request->finished = finished; /* do as the LAST thing before exiting */
+       return 0;
 }
 
 
@@ -755,21 +1922,23 @@ static void NEVER_RETURNS usage(int status)
        FILE *output = status?stderr:stdout;
 
        fprintf(output,
-                       "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-AcfnsSvXxyz]\n", progname);
+                       "Usage: %s [-a acct_dir] [-d db_dir] [-l log_dir] [-i address] [-p port] [-AcfnsSvXxyz]\n", progname);
        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, "  -d raddb_dir    Configuration files are in \"raddbdir/*\".\n");
+       fprintf(output, "  -d db_dir       Use database directory 'db_dir'.\n");
        fprintf(output, "  -f              Run as a foreground process, not a daemon.\n");
        fprintf(output, "  -h              Print this help message.\n");
-       fprintf(output, "  -i ipaddr       Listen on ipaddr ONLY\n");
-       fprintf(output, "  -l log_dir      Log file is \"log_dir/radius.log\" (not used in debug mode)\n");
-       fprintf(output, "  -p port         Listen on port ONLY\n");
+       fprintf(output, "  -i address      Listen only in the given IP address.\n");
+       fprintf(output, "  -l log_dir      Log messages to 'log_dir'.  Special values are:\n");
+       fprintf(output, "                  stdout == log all messages to standard output.\n");
+       fprintf(output, "                  syslog == log all messages to the system logger.\n");
+       fprintf(output, "  -p port         Bind to 'port', and not to the radius/udp, or 1646/udp.\n");
        fprintf(output, "  -s              Do not spawn child processes to handle requests.\n");
        fprintf(output, "  -S              Log stripped names.\n");
        fprintf(output, "  -v              Print server version information.\n");
-       fprintf(output, "  -X              Turn on full debugging.\n");
-       fprintf(output, "  -x              Turn on additional debugging. (-xx gives more debugging).\n");
+       fprintf(output, "  -X              Turn on full debugging. (Means: -sfxxyz -l stdout)\n");
+       fprintf(output, "  -x              Turn on partial debugging. (-xx gives more debugging).\n");
        fprintf(output, "  -y              Log authentication failures, with password.\n");
        fprintf(output, "  -z              Log authentication successes, with password.\n");
        exit(status);
@@ -782,27 +1951,18 @@ static void NEVER_RETURNS usage(int status)
 static void sig_fatal(int sig)
 {
        switch(sig) {
-               case SIGSEGV:
-                       /*
-                        *      We can't really do anything
-                        *      intelligent here so just die
-                        */
-                       _exit(1);
-
                case SIGTERM:
-                       radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
+                       do_exit = 1;
                        break;
-
                case SIGINT:
                case SIGQUIT:
                        if (debug_memory) {
-                               radius_signal_self(RADIUS_SIGNAL_SELF_TERM);
+                               do_exit = 1;
                                break;
                        }
-                       /* FALL-THROUGH */
 
                default:
-                       radius_signal_self(RADIUS_SIGNAL_SELF_EXIT);
+                       do_exit = 2;
                        break;
        }
 }
@@ -812,51 +1972,51 @@ static void sig_fatal(int sig)
  *  We got the hangup signal.
  *  Re-read the configuration files.
  */
+/*ARGSUSED*/
 static void sig_hup(int sig)
 {
        sig = sig; /* -Wunused */
-
        reset_signal(SIGHUP, sig_hup);
 
-       write(STDOUT_FILENO, "STUFF\n", 6);
-
-       radius_signal_self(RADIUS_SIGNAL_SELF_HUP);
-}
-
-void radius_signal_self(int flag)
-{
-       ssize_t rcode;
-       uint8_t buffer[16];
-
        /*
-        *      The caller is telling us it's OK to read from the
-        *      detail files.  However, we're not even listening on
-        *      the detail files.  Therefore, suppress the flag to
-        *      avoid bothering the mail worker thread.
+        *  Only do the reload if we're the main server, both
+        *  for processes, and for threads.
         */
-       if ((flag == RADIUS_SIGNAL_SELF_DETAIL) &&
-           !has_detail_listener) {
-               return;
+       if (getpid() == radius_pid) {
+               need_reload = TRUE;
        }
-
-       /*
-        *      The read MUST be non-blocking for this to work.
-        */
-       rcode = read(radius_self_pipe[0], buffer, sizeof(buffer));
-       if (rcode > 0) {
-               ssize_t i;
-
-               for (i = 1; i < rcode; i++) {
-                       buffer[0] |= buffer[i];
-               }
+#ifdef WITH_SNMP
+       if (mainconfig.do_snmp) {
+               rad_snmp.smux_failures = 0;
+               rad_snmp.smux_event = SMUX_CONNECT;
        }
-
-#ifndef NDEBUG
-       memset(buffer + 1, 0, sizeof(buffer) - 1);
 #endif
+}
+
 
-       buffer[0] |= flag;
+/*
+ *     Process and reply to a server-status request.
+ *     Like rad_authenticate and rad_accounting this should
+ *     live in it's own file but it's so small we don't bother.
+ */
+static int rad_status_server(REQUEST *request)
+{
+       char            reply_msg[64];
+       time_t          t;
+       VALUE_PAIR      *vp;
+
+       /*
+        *      Reply with an ACK. We might want to add some more
+        *      interesting reply attributes, such as server uptime.
+        */
+       t = request->timestamp - start_time;
+       sprintf(reply_msg, "FreeRADIUS up %d day%s, %02d:%02d",
+               (int)(t / 86400), (t / 86400) == 1 ? "" : "s",
+               (int)((t / 3600) % 24), (int)(t / 60) % 60);
+       request->reply->code = PW_AUTHENTICATION_ACK;
 
+       vp = pairmake("Reply-Message", reply_msg, T_OP_SET);
+       pairadd(&request->reply->vps, vp); /* don't need to check if !vp */
 
-       write(radius_self_pipe[1], buffer, 1);
+       return 0;
 }
diff --git a/src/main/radrelay.c b/src/main/radrelay.c
new file mode 100644 (file)
index 0000000..04adece
--- /dev/null
@@ -0,0 +1,1089 @@
+/*
+ * radrelay.c  This program tails a detail logfile, reads the log
+ *             entries, forwards them to a remote radius server,
+ *             and moves the processed records to another file.
+ *
+ *             Used to replicate accounting records to one (central)
+ *             server - works even if remote server has extended
+ *             downtime, and/or if this program is restarted.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2001 Cistron Internet Services B.V.
+ * Copyright 2002 Simon Ekstrand <simon@routemeister.net>
+ *
+ */
+char radrelay_rcsid[] =
+"$Id$";
+
+#include "autoconf.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "conf.h"
+#include "radpaths.h"
+#include "missing.h"
+#include "conffile.h"
+
+const char *progname;
+
+int debug_flag = 0;
+const char *radlog_dir = NULL;
+radlog_dest_t radlog_dest = RADLOG_FILES;
+
+const char *radius_dir = NULL;
+const char *radacct_dir = NULL;
+const char *radlib_dir = NULL;
+uint32_t myip = INADDR_ANY;
+int log_stripped_names;
+struct main_config_t mainconfig;
+
+/*
+ *     Possible states for request->state
+ */
+#define                STATE_EMPTY     0
+#define                STATE_BUSY1     1
+#define                STATE_BUSY2     2
+#define                STATE_FULL      3
+
+/*
+ *     Possible states for the loop() function.
+ */
+#define                STATE_RUN       0
+#define                STATE_BACKLOG   1
+#define                STATE_WAIT      2
+#define                STATE_SHUTDOWN  3
+#define                STATE_CLOSE     4
+
+#define                NR_SLOTS                64
+#define                DEFAULT_SLEEP           50
+#define                DEFAULT_SLEEP_EVERY     1
+
+/*
+ *     A relay request.
+ */
+struct relay_request {
+       int             state;                          /* REQ_* state */
+       time_t          retrans;                        /* when to retrans */
+       unsigned int    retrans_num;                    /* Number of retransmissions */
+       time_t          timestamp;                      /* orig recv time */
+       uint32_t        client_ip;                      /* Client-IP-Addr */
+       RADIUS_PACKET   *req;                           /* Radius request */
+};
+
+struct relay_misc {
+       int             sockfd;                         /* Main socket descriptor */
+       uint32_t        dst_addr;                       /* Destination address */
+       short           dst_port;                       /* Destination port */
+       uint32_t        src_addr;                       /* Source address */
+       char            detail[1024];                   /* Detail file */
+       char            *secret;                        /* Secret */
+       char            f_secret[256];                  /* File secret */
+       int             sleep_time;                     /* Time to sleep between sending packets */
+       int             sleep_every;                    /* Sleep every so many packets */
+       int             records_print;                  /* Print statistics after so many records */
+};
+
+struct relay_stats {
+       time_t          startup;
+       uint32_t        records_read;                   /* Records read */
+       uint32_t        packets_sent;                   /* Packets sent */
+       uint32_t        last_print_records;             /* Records on last statistics printout */
+};
+
+/*
+ * Used for reading the client configurations from the config files.
+ */
+char *c_secret = NULL;
+char *c_shortname = NULL;
+
+struct relay_request slots[NR_SLOTS];
+char id_map[256];
+int request_head = 0;
+int got_sigterm = 0;
+int debug = 0;
+
+
+int get_radius_id(void);
+void sigterm_handler(int sig);
+void ms_sleep(int msec);
+int isdateline(char *d);
+int read_one(FILE *fp, struct relay_request *req);
+int do_recv(struct relay_misc *r_args);
+int do_send(struct relay_request *r, char *secret);
+int detail_move(char *from, char *to);
+void loop(struct relay_misc *r_args);
+int find_shortname(char *shortname, char **host, char **secret);
+void usage(void);
+
+
+/*
+ * Get a radius id which is not
+ * currently being used (outstanding request)
+ * Since NR_SLOTS < 256 we can't
+ * have more outstanding requests than radius ids
+ */
+int get_radius_id()
+{
+       unsigned int id = 0;
+
+       for(id = 0; id < 256; id++){
+               if (id_map[id] == 0)
+                       break;
+       }
+       if (id == 256 || id_map[id] != 0){
+               fprintf(stdout, "get_radius_id(): No IDs available. Something is very wrong\n");
+               return -1;
+       }
+       id_map[id] = 1;
+       fprintf(stdout, "get_radius_id(): Assign RADIUS ID = %d\n",id);
+
+       return id;
+}
+
+void sigterm_handler(int sig)
+{
+       signal(sig, sigterm_handler);
+       got_sigterm = 1;
+}
+
+
+/*
+ *     Sleep a number of milli seconds
+ */
+inline void ms_sleep(int msec)
+{
+       struct timeval tv;
+
+       tv.tv_sec  = (msec / 1000);
+       tv.tv_usec = (msec % 1000) * 1000;
+       select(0, NULL, NULL, NULL, &tv);
+}
+
+/*
+ *     Does this (remotely) look like "Tue Jan 23 06:55:48 2001" ?
+ */
+inline int isdateline(char *d)
+{
+       int y;
+
+       return sscanf(d, "%*s %*s %*d %*d:%*d:%*d %d", &y);
+}
+
+
+/*
+ *     Read one request from the detail file.
+ *     Note that the file is locked during the read, and that
+ *     we return *with the file locked* if we reach end-of-file.
+ *
+ *     STATE_EMPTY:    Slot is empty.
+ *     STATE_BUSY1:    Looking for start of a detail record (timestamp)
+ *     STATE_BUSY2:    Reading the A/V pairs of a detail record.
+ *     STATE_FULL:     Read the complete record.
+ *
+ */
+int read_one(FILE *fp, struct relay_request *r_req)
+{
+       VALUE_PAIR *vp;
+       char *s;
+       char buf[2048];
+       char key[32], val[32];
+       int skip;
+       long fpos;
+       int x;
+       unsigned int i = 0;
+
+       /* Never happens */
+       if (r_req->state == STATE_FULL)
+               return 0;
+
+       if (r_req->state == STATE_EMPTY) {
+               r_req->state = STATE_BUSY1;
+       }
+
+       /*
+        * Try to lock the detail-file.
+        * If lockf is used we want to lock the _whole_ file, hence the
+        * fseek to the start of the file.
+        */
+       fpos = ftell(fp);
+       fseek(fp, 0L, SEEK_SET);
+       do {
+               x = rad_lockfd_nonblock(fileno(fp), 0);
+               if (x == -1)
+                       ms_sleep(100);
+       } while (x == -1 && i++ < 20);
+
+       if (x == -1)
+               return 0;
+
+redo:
+       s = NULL;
+       fseek(fp, fpos, SEEK_SET);
+       fpos = ftell(fp);
+       while ((s = fgets(buf, sizeof(buf), fp)) != NULL) {
+               /*
+                * Eek! We've just read a broken attribute.
+                * This does seem to happen every once in a long while
+                * due to some quirk involving threading, multiple processes
+                * going for the detail file lock at once and writes not
+                * being flushed properly. Things should be ok next time
+                * around.
+                */
+               if (!strlen(buf)) {
+                       fprintf(stdout, "read_one: ZERO BYTE\n");
+                       fseek(fp, fpos + 1, SEEK_SET);
+                       break;
+               } else if (buf[strlen(buf) - 1] != '\n') {
+                       fprintf(stdout, "read_one: BROKEN ATTRIBUTE\n");
+                       fseek(fp, fpos + strlen(buf), SEEK_SET);
+                       break;
+               }
+               if (r_req->state == STATE_BUSY1) {
+                       if (isdateline(buf)) {
+                               r_req->state = STATE_BUSY2;
+                       }
+               } else if (r_req->state == STATE_BUSY2) {
+                       if (buf[0] != ' ' && buf[0] != '\t') {
+                               r_req->state = STATE_FULL;
+                               break;
+                       }
+                       /*
+                        *      Found A/V pair, but we skip non-protocol
+                        *      values.
+                        */
+                       skip = 0;
+                       if (sscanf(buf, "%31s = %31s", key, val) == 2) {
+                               if (!strcasecmp(key, "Timestamp")) {
+                                       r_req->timestamp = atoi(val);
+                                       skip++;
+                               } else
+                               if (!strcasecmp(key, "Client-IP-Address")) {
+                                       r_req->client_ip = ip_getaddr(val);
+                                       skip++;
+                               } else
+                               if (!strcasecmp(key, "Request-Authenticator"))
+                                       skip++;
+                       }
+                       if (!skip) {
+                               vp = NULL;
+                               if (userparse(buf, &vp) > 0 &&
+                                   (vp != NULL) &&
+                                   (vp->attribute < 256 ||
+                                    vp->attribute > 65535) &&
+                                   vp->attribute != PW_VENDOR_SPECIFIC) {
+                                       pairadd(&(r_req->req->vps), vp);
+                               } else {
+                                 pairfree(&vp);
+                               }
+                       }
+               }
+               fpos = ftell(fp);
+       }
+       clearerr(fp);
+
+       if (r_req->state == STATE_FULL) {
+               /*
+                *      w00 - we just completed reading a record in full.
+                */
+
+               /*
+                * Check that we have an Acct-Status-Type attribute. If not
+                * reject the record
+                */
+               if (pairfind(r_req->req->vps, PW_ACCT_STATUS_TYPE) == NULL){
+                       fprintf(stdout, "read_one: No Acct-Status-Type attribute present. Rejecting record.\n");
+                       r_req->state = STATE_BUSY1;
+                       if (r_req->req->vps != NULL) {
+                               pairfree(&r_req->req->vps);
+                               r_req->req->vps = NULL;
+                       }
+                       if (r_req->req->data != NULL) {
+                               free (r_req->req->data);
+                               r_req->req->data = NULL;
+                       }
+                       r_req->retrans = 0;
+                       r_req->retrans_num = 0;
+                       r_req->timestamp = 0;
+                       r_req->client_ip = 0;
+                       goto redo;
+               }
+               if (r_req->timestamp == 0)
+                       r_req->timestamp = time(NULL);
+               if ((vp = pairfind(r_req->req->vps, PW_ACCT_DELAY_TIME)) != NULL) {
+                       r_req->timestamp -= vp->lvalue;
+                       vp->lvalue = 0;
+               }
+               r_req->req->id = get_radius_id();
+       }
+
+       if (s == NULL) {
+               /*
+                *      Apparently we reached end of file. If we didn't
+                *      partially read a record, we let the caller know
+                *      we're at end of file.
+                */
+               if (r_req->state == STATE_BUSY1) {
+                       r_req->state = STATE_EMPTY;
+               }
+               if (r_req->state == STATE_EMPTY || r_req->state == STATE_FULL)
+                       return EOF;
+       }
+
+       fpos = ftell(fp);
+       fseek(fp, 0L, SEEK_SET);
+       rad_unlockfd(fileno(fp), 0);
+       fseek(fp, fpos, SEEK_SET);
+
+       return 0;
+}
+
+/*
+ *     Receive answers from the remote server.
+ */
+int do_recv(struct relay_misc *r_args)
+{
+       RADIUS_PACKET *rep;
+       struct relay_request *r;
+       int i;
+
+       /*
+        *      Receive packet and validate it's length.
+        */
+       rep = rad_recv(r_args->sockfd);
+       if (rep == NULL) {
+               librad_perror("radrelay:");
+               return -1;
+       }
+
+       /*
+        *      Must be an accounting response.
+        *      FIXME: check if this is the right server!
+        */
+       if (rep->code != PW_ACCOUNTING_RESPONSE) {
+               rad_free(&rep);
+               return -1;
+       }
+
+       /*
+        *      Decode packet into radius attributes.
+        */
+
+       /*
+        *      Now find it in the outstanding requests.
+        */
+       for (i = 0; i < NR_SLOTS; i++) {
+               r = slots + i;
+               if (r->state == STATE_FULL && r->req->id == rep->id) {
+                       if (rad_verify(rep, r->req, r_args->secret) != 0) {
+                               librad_perror("rad_verify");
+                               rad_free(&rep);
+                               return -1;
+                       }
+                       if (rad_decode(rep, r->req, r_args->secret) != 0) {
+                               librad_perror("rad_decode");
+                               rad_free(&rep);
+                               return -1;
+                       }
+                       /*
+                        *      Got it. Clear slot.
+                        *      FIXME: check reponse digest ?
+                        */
+                       id_map[r->req->id] = 0;
+                       fprintf(stdout, "do_recv: Free RADIUS ID = %d\n",r->req->id);
+                       if (r->req->vps != NULL) {
+                               pairfree(&r->req->vps);
+                               r->req->vps = NULL;
+                       }
+                       if (r->req->data != NULL) {
+                               free (r->req->data);
+                               r->req->data = NULL;
+                       }
+                       r->state = STATE_EMPTY;
+                       r->retrans = 0;
+                       r->retrans_num = 0;
+                       r->timestamp = 0;
+                       r->client_ip = 0;
+                       break;
+               }
+       }
+
+       rad_free(&rep);
+
+       return 0;
+}
+
+/*
+ *     Send accounting packet to remote server.
+ */
+int do_send(struct relay_request *r, char *secret)
+{
+       VALUE_PAIR *vp;
+       time_t now;
+
+       /*
+        *      Prevent loops.
+        */
+       if (r->client_ip == r->req->dst_ipaddr) {
+               fprintf(stdout, "do_send: Client-IP == Dest-IP. Droping packet.\n");
+               fprintf(stdout, "do_send: Free RADIUS ID = %d\n",r->req->id);
+               id_map[r->req->id] = 0;
+               if (r->req->vps != NULL) {
+                       pairfree(&r->req->vps);
+                       r->req->vps = NULL;
+               }
+               if (r->req->data != NULL) {
+                       free (r->req->data);
+                       r->req->data = NULL;
+               }
+               r->state = STATE_EMPTY;
+               r->retrans = 0;
+               r->retrans_num = 0;
+               r->timestamp = 0;
+               r->client_ip = 0;
+               return 0;
+       }
+
+       /*
+        *      Has the time come for this packet ?
+        */
+       now = time(NULL);
+       if (r->retrans > now)
+               return 0;
+       /*
+        * If we are resending a packet we *need* to
+        * change the radius packet id since the request
+        * authenticator is different (due to different
+        * Acct-Delay-Time value).
+        * Otherwise the radius server may consider the
+        * packet a duplicate and we 'll get caught in a
+        * loop.
+        */
+       if (r->retrans > 0){
+               id_map[r->req->id] = 0;
+               r->req->id = get_radius_id();
+               if (r->req->data != NULL){
+                       free(r->req->data);
+                       r->req->data = NULL;
+               }
+               r->retrans_num++;
+       }
+       if (r->retrans_num > 20)
+               r->retrans = now + 70;
+       else
+               r->retrans = now + 3 + (3 * r->retrans_num);
+
+       /*
+        *      Find the Acct-Delay-Time attribute. If it's
+        *      not there, add one.
+        */
+       if ((vp = pairfind(r->req->vps, PW_ACCT_DELAY_TIME)) == NULL) {
+               vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
+               pairadd(&(r->req->vps), vp);
+       }
+       vp->lvalue = (now - r->timestamp);
+
+       /*
+        *      Rebuild the entire packet every time from
+        *      scratch - the signature changed because
+        *      Acct-Delay-Time changed.
+        */
+       rad_send(r->req, NULL, secret);
+
+       return 1;
+}
+
+/*
+ *     Rename a file, then recreate the old file with the
+ *     same permissions and zero size.
+ */
+int detail_move(char *from, char *to)
+{
+       struct stat st;
+       int n;
+       int oldmask;
+
+       if (stat(from, &st) < 0)
+               return -1;
+       if (rename(from, to) < 0)
+               return -1;
+
+       oldmask = umask(0);
+       if ((n = open(from, O_CREAT|O_RDWR, st.st_mode)) >= 0)
+               close(n);
+       umask(oldmask);
+
+       return 0;
+}
+
+
+/*
+ *     Open detail file, collect records, send them to the
+ *     remote accounting server, yadda yadda yadda.
+ *
+ *     STATE_RUN:      Reading from detail file, sending to server.
+ *     STATE_BACKLOG:  Reading from the detail.work file, for example
+ *                     after a crash or restart. Sending to server.
+ *     STATE_WAIT:     Waiting for all outstanding requests to be handled.
+ *     STATE_CLOSE:    Reached end of detail.work file, waiting for
+ *                     outstanding requests, and removing the file.
+ *     STATE_SHUTDOWN: Got SIG_TERM, waiting for outstanding requests
+ *                     and exiting program.
+ */
+void loop(struct relay_misc *r_args)
+{
+       FILE *fp = NULL;
+       struct relay_request *r;
+       struct timeval tv;
+       struct relay_stats stats;
+       fd_set readfds;
+       char work[1030];
+       time_t now, uptime, last_rename = 0;
+       int i, n;
+       int state = STATE_RUN;
+       int id;
+       long fpos;
+
+       strNcpy(work, r_args->detail, sizeof(work) - 6);
+       strcat(work, ".work");
+
+       id = ((int)getpid() & 0xff);
+
+       memset(&stats,0,sizeof(struct relay_stats));
+       stats.startup = time(NULL);
+
+       /*
+        * Initialize all our slots, might as well do this right away.
+        */
+       for (i = 0; i < NR_SLOTS; i++) {
+               if ((slots[i].req = rad_alloc(1)) == NULL) {
+                       librad_perror("radrelay");
+                       exit(1);
+               }
+               slots[i].state = STATE_EMPTY;
+               slots[i].retrans = 0;
+               slots[i].retrans_num = 0;
+               slots[i].timestamp = 0;
+               slots[i].client_ip = 0;
+               slots[i].req->sockfd = r_args->sockfd;
+               slots[i].req->dst_ipaddr = r_args->dst_addr;
+               slots[i].req->dst_port = r_args->dst_port;
+               slots[i].req->src_ipaddr = r_args->src_addr;
+               slots[i].req->code = PW_ACCOUNTING_REQUEST;
+               slots[i].req->vps = NULL;
+               slots[i].req->data = NULL;
+       }
+
+       while(1) {
+               if (got_sigterm) state = STATE_SHUTDOWN;
+
+               /*
+                *      Open detail file - if needed, and if we can.
+                */
+               if (state == STATE_RUN && fp == NULL) {
+                       if ((fp = fopen(work, "r+")) != NULL)
+                               state = STATE_BACKLOG;
+                       else
+                               fp = fopen(r_args->detail, "r+");
+                       if (fp == NULL) {
+                               fprintf(stderr, "%s: Unable to open detail file - %s\n", progname, r_args->detail);
+                               perror("fopen");
+                               return;
+                       }
+
+               }
+
+               /*
+                *      If "request_head" points to a free or not-completely-
+                *      filled slot, we can read from the detail file.
+                */
+               r = &slots[request_head];
+               if (fp && (state == STATE_RUN || state == STATE_BACKLOG) &&
+                   r->state != STATE_FULL) {
+                       if (read_one(fp, r) == EOF) do {
+
+                               /*
+                                *      We've reached end of the <detail>.work
+                                *      It's going to be closed as soon as all
+                                *      outstanting requests are handled
+                                */
+                               if (state == STATE_BACKLOG) {
+                                       state = STATE_CLOSE;
+                                       break;
+                               }
+
+                               /*
+                                *      End of file. See if the file has
+                                *      any size, and if we renamed less
+                                *      than 10 seconds ago or not.
+                                */
+                               now = time(NULL);
+                               if (ftell(fp) == 0 || now < last_rename + 10) {
+                                       fpos = ftell(fp);
+                                       fseek(fp, 0L, SEEK_SET);
+                                       rad_unlockfd(fileno(fp), 0);
+                                       fseek(fp, fpos, SEEK_SET);
+                                       break;
+                               }
+                               last_rename = now;
+
+                               /*
+                                *      We rename the file to <file>.work
+                                *      and create an empty new file.
+                                */
+                               if (detail_move(r_args->detail, work) == 0) {
+                                       if (debug_flag > 0)
+                                               fprintf(stderr, "Moving %s to %s\n",
+                                                       r_args->detail, work);
+                                       /*
+                                        *      rlm_detail might still write
+                                        *      something to <detail>.work if
+                                        *      it opens <detail> before it is
+                                        *      renamed (race condition)
+                                        */
+                                       ms_sleep(1000);
+                                       state = STATE_BACKLOG;
+                               }
+                               fpos = ftell(fp);
+                               fseek(fp, 0L, SEEK_SET);
+                               rad_unlockfd(fileno(fp), 0);
+                               fseek(fp, fpos, SEEK_SET);
+                       } while(0);
+                       if (r_args->records_print && state == STATE_RUN){
+                               stats.records_read++;
+                               if (stats.last_print_records - stats.records_read >= r_args->records_print){
+                                       now = time(NULL);
+                                       uptime = (stats.startup == now) ? 1 : now - stats.startup;
+                                       fprintf(stderr, "%s: Running and Processing Records.\n",progname);
+                                       fprintf(stderr, "Seconds since startup: %ld\n",uptime);
+                                       fprintf(stderr, "Records Read: %d\n",stats.records_read);
+                                       fprintf(stderr, "Packets Sent: %d\n",stats.packets_sent);
+                                       fprintf(stderr, "Record Rate since startup: %.2f\n",
+                                               (double)stats.records_read / uptime);
+                                       fprintf(stderr, "Packet Rate since startup: %.2f\n",
+                                               (double)stats.packets_sent / uptime);
+                                       stats.last_print_records = stats.records_read;
+                               }
+                       }
+                       if (r->state == STATE_FULL)
+                               request_head = (request_head + 1) % NR_SLOTS;
+               }
+
+               /*
+                *      Perhaps we can receive something.
+                */
+               tv.tv_sec = 0;
+               tv.tv_usec = 25000;
+               FD_ZERO(&readfds);
+               FD_SET(r_args->sockfd, &readfds);
+               n = 0;
+               while (select(r_args->sockfd + 1, &readfds, NULL, NULL, &tv) > 0) {
+                       do_recv(r_args);
+                       if (n++ >= NR_SLOTS) break;
+               }
+
+               /*
+                *      If we're in STATE_WAIT and all slots are
+                *      finally empty, we can remove the <detail>.work
+                */
+               if (state == STATE_WAIT || state == STATE_CLOSE || state == STATE_SHUTDOWN) {
+                       for (i = 0; i < NR_SLOTS; i++)
+                               if (slots[i].state != STATE_EMPTY)
+                                       break;
+                       if (i == NR_SLOTS) {
+                               if (state == STATE_CLOSE) {
+                                       if (fp) fclose(fp);
+                                       fp = NULL;
+                                       if (debug_flag > 0)
+                                               fprintf(stderr, "Unlink file %s\n", work);
+                                       unlink(work);
+                               }
+                               else if (state == STATE_SHUTDOWN) {
+                                       for (i = 0; i < NR_SLOTS; i++) {
+                                               rad_free(&slots[i].req);
+                                       }
+                                       exit(0);
+                               }
+                               state = STATE_RUN;
+                       }
+               }
+
+               /*
+                *      See if there's anything to send.
+                */
+               n=0;
+               for (i = 0; i < NR_SLOTS; i++) {
+                       if (slots[i].state == STATE_FULL) {
+                               n += do_send(&slots[i], r_args->secret);
+                               if ((n % r_args->sleep_every) == 0)
+                                       ms_sleep(r_args->sleep_time);
+                               if (n > NR_SLOTS / 2)
+                                       break;
+                       }
+               }
+               if (r_args->records_print)
+                       stats.packets_sent += n;
+       }
+}
+
+/*
+ * Search through the "client" config sections (usually in clients.conf).
+ * This is an easy way to find a secret and an host.
+ */
+int find_shortname(char *shortname, char **host, char **secret)
+{
+       CONF_SECTION *maincs, *cs;
+       char buffer[256];
+
+       /* Lets go look for the new configuration files */
+       memset(&mainconfig, 0, sizeof(mainconfig)); /* for radlog() */
+       snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", radius_dir);
+       if ((maincs = conf_read(NULL, 0, buffer, NULL)) == NULL) {
+               return -1;
+       }
+
+       /*
+        * Find the first 'client' section.
+        */
+       cs = cf_section_sub_find(maincs, "client");
+       if (cs) {
+               c_shortname = cf_section_value_find(cs, "shortname");
+               c_secret = cf_section_value_find(cs, "secret");
+               /*
+                * Keep searching for 'client' sections until they run out
+                * or we find one that matches.
+                */
+               while (cs && strcmp(shortname, c_shortname)) {
+                       cs = cf_subsection_find_next(cs, cs, "client");
+                       if (cs) {
+                               c_shortname = cf_section_value_find(cs, "shortname");
+                               c_secret = cf_section_value_find(cs, "secret");
+                       }
+               };
+       };
+
+       if (cs) {
+               *host = cf_section_name2(cs);
+               *secret = c_secret;
+               if (host && secret)
+                       return 0;
+       }
+
+       return -1;
+}
+
+void usage(void)
+{
+       fprintf(stderr, "Usage: radrelay [-a accounting_dir] [-d radius_dir] [-i local_ip] [-s secret]\n");
+       fprintf(stderr, "[-e sleep_every packets] [-t sleep_time (ms)] [-S secret_file] [-fx]\n");
+       fprintf(stderr, "[-R records_print] <[-n shortname] [-r remote-server[:port]]> detailfile\n");
+       fprintf(stderr, " -a accounting_dir     Base accounting directory.\n");
+       fprintf(stderr, " -d radius_dir         Base radius (raddb) directory.\n");
+       fprintf(stderr, " -f                    Stay in the foreground (don't fork).\n");
+       fprintf(stderr, " -h                    This help.\n");
+       fprintf(stderr, " -i local_ip           Use local_ip as source address.\n");
+       fprintf(stderr, " -n shortname          Use the [shortname] entry from clients.conf for\n");
+       fprintf(stderr, "                       ip-adress and secret.\n");
+       fprintf(stderr, " -t sleep_time         Sleep so much time (in ms) between sending packets. Default: %dms.\n",
+                                               DEFAULT_SLEEP);
+       fprintf(stderr, " -e sleep_every        Sleep after sending so many packets. Default: %d\n",
+                                               DEFAULT_SLEEP_EVERY);
+       fprintf(stderr, " -R records_print      If in foreground mode, print statistics after so many records read.\n");
+       fprintf(stderr, " -r remote-server      The destination address/hostname.\n");
+       fprintf(stderr, " -s secret             Server secret.\n");
+       fprintf(stderr, " -S secret_file        Read server secret from file.\n");
+       fprintf(stderr, " -x                    Debug mode (-xx gives more debugging).\n");
+
+       exit(1);
+}
+
+int main(int argc, char **argv)
+{
+       struct servent *svp;
+       char *server_name;
+       char *shortname;
+       char *p;
+       int c;
+       int i;
+       int dontfork = 0;
+       struct relay_misc r_args;
+       FILE *sfile_fp;
+
+       progname = argv[0];
+
+       r_args.sockfd = -1;
+       r_args.dst_addr = 0;
+       r_args.dst_port = 0;
+       r_args.src_addr = 0;
+       memset((char *) r_args.detail, 0, 1024);
+       memset((char *) r_args.f_secret, 0, 256);
+       r_args.secret = NULL;
+       r_args.sleep_time = DEFAULT_SLEEP;
+       r_args.sleep_every = DEFAULT_SLEEP_EVERY;
+
+       shortname = NULL;
+       server_name = NULL;
+
+       radius_dir = strdup(RADIUS_DIR);
+
+       librad_debug = 0;
+
+       /*
+        *      Make sure there are stdin/stdout/stderr fds.
+        */
+       while ((c = open("/dev/null", O_RDWR)) < 3 && c >= 0);
+       if (c >= 3) close(c);
+
+       /*
+        *      Process the options.
+        */
+       while ((c = getopt(argc, argv, "a:d:fhi:t:e:n:r:R:s:S:x")) != EOF) switch(c) {
+               case 'a':
+                       if (strlen(optarg) > 1021) {
+                               fprintf(stderr, "%s: acct_dir to long\n", progname);
+                               exit(1);
+                       }
+                       strncpy(r_args.detail, optarg, 1021);
+                       break;
+               case 'd':
+                       if (radius_dir)
+                               free(radius_dir);
+                       radius_dir = strdup(optarg);
+                       break;
+               case 'f':
+                       dontfork = 1;
+                       break;
+               case 'n':
+                       shortname = optarg;
+                       break;
+               case 't':
+                       r_args.sleep_time = atoi(optarg);
+                       break;
+               case 'e':
+                       r_args.sleep_every = atoi(optarg);
+                       break;
+               case 'R':
+                       if (!dontfork){
+                               fprintf(stderr, "%s: Not in foreground mode. Can't print statistics.\n",progname);
+                               usage();
+                       }
+                       r_args.records_print = atoi(optarg);
+                       break;
+               case 'r':
+                       server_name = optarg;
+                       break;
+               case 's':
+                       r_args.secret = optarg;
+                       break;
+               case 'x':
+                       /*
+                        * If -x is called once we enable internal radrelay
+                        * debugging, if it's called twice we also active
+                        * lib_rad debugging (fairly verbose).
+                        */
+                       if (debug == 1)
+                               librad_debug = 1;
+                       debug = 1;
+                       dontfork = 1;
+                       break;
+               case 'S':
+                       sfile_fp = fopen(optarg, "r");
+                       if (sfile_fp == NULL) {
+                               fprintf(stderr, "Error opening %s: %s\n",
+                                       optarg, strerror(errno));
+                               exit(1);
+                       }
+
+                       if (fgets(r_args.f_secret, 256, sfile_fp) == NULL) {
+                               fprintf(stderr, "Error reading from %s: %s\n",
+                                       optarg, strerror(errno));
+                               fclose(sfile_fp);
+                               exit(1);
+                       }
+                       fclose(sfile_fp);
+
+                       for (c = 0; c < strlen(r_args.f_secret); c++)
+                               if (r_args.f_secret[c] == ' ' ||
+                                   r_args.f_secret[c] == '\n')
+                                       r_args.f_secret[c] = '\0';
+
+                       if (strlen(r_args.f_secret) < 2) {
+                               fprintf(stderr, "Secret in %s is to short\n",
+                                       optarg);
+                               exit(1);
+                       }
+
+                       r_args.secret = r_args.f_secret;
+                       break;
+               case 'i':
+                       if ((r_args.src_addr = ip_getaddr(optarg)) == 0) {
+                               fprintf(stderr, "%s: unknown host %s\n",
+                                       progname, optarg);
+                               exit(1);
+                       }
+                       break;
+               case 'h':
+               default:
+                       usage();
+                       break;
+       }
+
+       /*
+        *      No detail file: die.
+        */
+       if (argc == optind) {
+               usage();
+       }
+
+       argc -= (optind - 1);
+       argv += (optind - 1);
+       if (shortname && server_name)
+               usage();
+       if (!shortname && !server_name)
+               usage();
+       if (r_args.secret != NULL && shortname != NULL)
+               usage();
+
+       /*
+        * If we've been given a shortname, try to fetch the secret and
+        * adress from the config files.
+        */
+       if (shortname != NULL) {
+               if (find_shortname(shortname, &server_name, &r_args.secret) == -1) {
+                       fprintf(stderr, "Couldn't find %s in configuration files.\n", shortname);
+                       exit(1);
+               }
+       }
+
+       /*
+        * server_name should already be set either by the -r or the -s
+        * commandline argument.
+        */
+       if ((p = strrchr(server_name, ':')) != NULL) {
+               *p = 0;
+               p++;
+               r_args.dst_port = ntohs(atoi(p));
+       }
+       if (r_args.dst_port == 0) {
+               svp = getservbyname ("radacct", "udp");
+               r_args.dst_port = svp ? ntohs(svp->s_port) : PW_ACCT_UDP_PORT;
+       } else {
+               r_args.dst_port = ntohs(r_args.dst_port);
+       }
+       r_args.dst_addr = ip_getaddr(server_name);
+       if (r_args.dst_addr == 0) {
+               fprintf(stderr, "%s: unknown host\n",
+                       server_name);
+               exit(1);
+       }
+
+       if (r_args.secret == NULL || r_args.secret[0] == 0) {
+               fprintf(stderr, "No secret available for server %s\n",
+                       server_name);
+               exit(1);
+       }
+
+       /*
+        * Find what detail file to read from.
+        *
+        * FIXME: We should be able to expand dates etc. based on the pathname,
+        * just like the detail module does.
+        */
+       if (r_args.detail[0] == '\0') {
+               if (strlen(RADIR) > 1021) {
+                       fprintf(stderr, "acct_dir to long\n");
+                       exit(1);
+               }
+               strncpy(r_args.detail, RADIR, 1021);
+       }
+       if (chdir(r_args.detail) == -1) {
+               perror("chdir");
+               exit(1);
+       }
+
+       if (strlen(argv[1]) + strlen(r_args.detail) > 1023) {
+               fprintf(stderr, "Detail file path to long");
+               exit(1);
+       } else {
+               if (r_args.detail[strlen(r_args.detail) - 1] != '/')
+                       r_args.detail[strlen(r_args.detail)] = '/';
+               strncat (r_args.detail, argv[1], 1023 - strlen(r_args.detail));
+       }
+
+       /*
+        *      Initialize dictionary.
+        */
+       if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
+               librad_perror("radrelay");
+               exit(1);
+       }
+
+       /*
+        *      Open a socket to the remote server.
+        */
+       if ((r_args.sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               fprintf(stderr, "Error opening socket: %s", strerror(errno));
+               exit(1);
+       }
+
+       signal(SIGTERM, sigterm_handler);
+
+       if (!dontfork) {
+               if (fork() != 0)
+                       exit(0);
+               close(0);
+               close(1);
+               close(2);
+               (void)open("/dev/null", O_RDWR);
+               dup(0);
+               dup(0);
+               signal(SIGHUP,  SIG_IGN);
+               signal(SIGINT,  SIG_IGN);
+               signal(SIGQUIT, SIG_IGN);
+#ifdef HAVE_SETSID
+               setsid();
+#endif
+       }
+
+       /*
+        * Initialize the radius id map
+        */
+       for(i=0;i<256;i++)
+               id_map[i] = 0;
+
+       /*
+        *      Call main processing loop.
+        */
+       loop(&r_args);
+
+       return 0;
+}
diff --git a/src/main/radsniff.c b/src/main/radsniff.c
deleted file mode 100644 (file)
index 989a2aa..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- *  radsniff.c Display the RADIUS traffic on the network.
- *
- *  Version:    $Id$
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *  Copyright 2006  The FreeRADIUS server project
- *  Copyright 2006  Nicolas Baradakis <nicolas.baradakis@cegetel.net>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#define _LIBRADIUS 1
-#include <freeradius-devel/libradius.h>
-
-#include <pcap.h>
-
-#include <freeradius-devel/radpaths.h>
-#include <freeradius-devel/conf.h>
-#include <freeradius-devel/radsniff.h>
-
-static const char *radius_secret = "testing123";
-static VALUE_PAIR *filter_vps = NULL;
-
-static const char *packet_codes[] = {
-  "",
-  "Access-Request",
-  "Access-Accept",
-  "Access-Reject",
-  "Accounting-Request",
-  "Accounting-Response",
-  "Accounting-Status",
-  "Password-Request",
-  "Password-Accept",
-  "Password-Reject",
-  "Accounting-Message",
-  "Access-Challenge",
-  "Status-Server",
-  "Status-Client",
-  "14",
-  "15",
-  "16",
-  "17",
-  "18",
-  "19",
-  "20",
-  "Resource-Free-Request",
-  "Resource-Free-Response",
-  "Resource-Query-Request",
-  "Resource-Query-Response",
-  "Alternate-Resource-Reclaim-Request",
-  "NAS-Reboot-Request",
-  "NAS-Reboot-Response",
-  "28",
-  "Next-Passcode",
-  "New-Pin",
-  "Terminate-Session",
-  "Password-Expired",
-  "Event-Request",
-  "Event-Response",
-  "35",
-  "36",
-  "37",
-  "38",
-  "39",
-  "Disconnect-Request",
-  "Disconnect-ACK",
-  "Disconnect-NAK",
-  "CoF-Request",
-  "CoF-ACK",
-  "CoF-NAK",
-  "46",
-  "47",
-  "48",
-  "49",
-  "IP-Address-Allocate",
-  "IP-Address-Release"
-};
-
-/*
- *     Stolen from rad_recv() in ../lib/radius.c
- */
-static RADIUS_PACKET *init_packet(const uint8_t *data, size_t data_len)
-{
-       RADIUS_PACKET           *packet;
-
-       /*
-        *      Allocate the new request data structure
-        */
-       if ((packet = malloc(sizeof(*packet))) == NULL) {
-               librad_log("out of memory");
-               return NULL;
-       }
-       memset(packet, 0, sizeof(*packet));
-
-       packet->data = data;
-       packet->data_len = data_len;
-
-       if (!rad_packet_ok(packet)) {
-               rad_free(&packet);
-               return NULL;
-       }
-
-       /*
-        *      Explicitely set the VP list to empty.
-        */
-       packet->vps = NULL;
-
-       return packet;
-}
-
-static int filter_packet(RADIUS_PACKET *packet)
-{
-       VALUE_PAIR *check_item;
-       VALUE_PAIR *vp;
-       unsigned int pass, fail;
-       int compare;
-
-       pass = fail = 0;
-       for (vp = packet->vps; vp != NULL; vp = vp->next) {
-               for (check_item = filter_vps;
-                    check_item != NULL;
-                    check_item = check_item->next)
-                       if ((check_item->attribute == vp->attribute)
-                        && (check_item->operator != T_OP_SET)) {
-                               compare = paircmp(check_item, vp);
-                               if (compare == 1)
-                                       pass++;
-                               else
-                                       fail++;
-                       }
-       }
-       if (fail == 0 && pass != 0) {
-               return 0;
-       }
-
-       return 1;
-}
-
-static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const uint8_t *packet)
-{
-       /* Just a counter of how many packets we've had */
-       static int count = 1;
-       /* Define pointers for packet's attributes */
-       const struct ethernet_header *ethernet;  /* The ethernet header */
-       const struct ip_header *ip;              /* The IP header */
-       const struct udp_header *udp;            /* The UDP header */
-       const uint8_t *payload;                     /* Packet payload */
-       /* And define the size of the structures we're using */
-       int size_ethernet = sizeof(struct ethernet_header);
-       int size_ip = sizeof(struct ip_header);
-       int size_udp = sizeof(struct udp_header);
-       /* For FreeRADIUS */
-       RADIUS_PACKET *request;
-
-       args = args;            /* -Wunused */
-
-       /* Define our packet's attributes */
-       ethernet = (const struct ethernet_header*)(packet);
-       ip = (const struct ip_header*)(packet + size_ethernet);
-       udp = (const struct udp_header*)(packet + size_ethernet + size_ip);
-       payload = (const uint8_t *)(packet + size_ethernet + size_ip + size_udp);
-
-       /* Read the RADIUS packet structure */
-       request = init_packet(payload, header->len - size_ethernet - size_ip - size_udp);
-       if (request == NULL) {
-               librad_perror("check");
-               return;
-       }
-       request->src_ipaddr.ipaddr.ip4addr.s_addr = ip->ip_src.s_addr;
-       request->src_port = ntohs(udp->udp_sport);
-       request->dst_ipaddr.ipaddr.ip4addr.s_addr = ip->ip_dst.s_addr;
-       request->dst_port = ntohs(udp->udp_dport);
-
-       /*
-        *      Decode the data without bothering to check the signatures.
-        */
-       if (rad_decode(request, NULL, radius_secret) != 0) {
-               librad_perror("decode");
-               return;
-       }
-       if (filter_vps && filter_packet(request)) {
-               /* printf("Packet number %d doesn't match\n", count++); */
-               return;
-       }
-
-       /* Print the RADIUS packet */
-       printf("Packet number %d has just been sniffed\n", count++);
-       printf("\tFrom:    %s:%d\n", inet_ntoa(ip->ip_src), ntohs(udp->udp_sport));
-       printf("\tTo:      %s:%d\n", inet_ntoa(ip->ip_dst), ntohs(udp->udp_dport));
-       printf("\tType:    %s\n", packet_codes[request->code]);
-       if (request->vps != NULL) {
-               vp_printlist(stdout, request->vps);
-               pairfree(&request->vps);
-       }
-       free(request);
-}
-
-static void NEVER_RETURNS usage(int status)
-{
-       FILE *output = status ? stderr : stdout;
-       fprintf(output, "usage: radsniff [options]\n");
-       fprintf(output, "options:\n");
-       fprintf(output, "\t-c count\tNumber of packets to capture.\n");
-       fprintf(output, "\t-d directory\tDirectory where the dictionaries are found\n");
-       fprintf(output, "\t-f filter\tPCAP filter. (default is udp port 1812 or 1813 or 1814)\n");
-       fprintf(output, "\t-h\t\tPrint this help message.\n");
-       fprintf(output, "\t-i interface\tInterface to capture.\n");
-       fprintf(output, "\t-p port\tList for packets on port.\n");
-       fprintf(output, "\t-r filter\tRADIUS attribute filter.\n");
-       fprintf(output, "\t-s secret\tRADIUS secret.\n");
-       exit(status);
-}
-
-int main(int argc, char *argv[])
-{
-       char *dev;                      /* sniffing device */
-       char errbuf[PCAP_ERRBUF_SIZE];  /* error buffer */
-       pcap_t *descr;                  /* sniff handler */
-       struct bpf_program fp;          /* hold compiled program */
-       bpf_u_int32 maskp;              /* subnet mask */
-       bpf_u_int32 netp;               /* ip */
-       char buffer[1024];
-       char *pcap_filter = NULL;
-       char *radius_filter = NULL;
-       int packet_count = -1;          /* how many packets to sniff */
-       int opt;
-       LRAD_TOKEN parsecode;
-       const char *radius_dir = RADIUS_DIR;
-       int port = 1812;
-
-       /* Default device */
-       dev = pcap_lookupdev(errbuf);
-
-       /* Get options */
-       while ((opt = getopt(argc, argv, "c:d:f:hi:p:r:s:")) != EOF) {
-               switch (opt)
-               {
-               case 'c':
-                       packet_count = atoi(optarg);
-                       if (packet_count <= 0) {
-                               fprintf(stderr, "radsniff: Invalid number of packets \"%s\"\n", optarg);
-                               exit(1);
-                       }
-                       break;
-               case 'd':
-                       radius_dir = optarg;
-                       break;
-               case 'f':
-                       pcap_filter = optarg;
-                       break;
-               case 'h':
-                       usage(0);
-                       break;
-               case 'i':
-                       dev = optarg;
-                       break;
-               case 'p':
-                       port = atoi(optarg);
-                       break;
-               case 'r':
-                       radius_filter = optarg;
-                       parsecode = userparse(radius_filter, &filter_vps);
-                       if (parsecode == T_OP_INVALID || filter_vps == NULL) {
-                               fprintf(stderr, "radsniff: Invalid RADIUS filter \"%s\"\n", optarg);
-                               exit(1);
-                       }
-                       break;
-               case 's':
-                       radius_secret = optarg;
-                       break;
-               default:
-                       usage(1);
-               }
-       }
-
-       if (!pcap_filter) {
-               pcap_filter = buffer;
-               snprintf(buffer, sizeof(buffer), "udp port %d or %d or %d",
-                        port, port + 1, port + 2);
-       }
-
-        if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
-                librad_perror("radsniff");
-                return 1;
-        }
-       /* Set our device */
-       pcap_lookupnet(dev, &netp, &maskp, errbuf);
-
-       /* Print device to the user */
-       printf("Device: [%s]\n", dev);
-       if (packet_count > 0) {
-               printf("Num of packets: [%d]\n", packet_count);
-       }
-       printf("PCAP filter: [%s]\n", pcap_filter);
-       if (filter_vps != NULL) {
-               printf("RADIUS filter:\n");
-               vp_printlist(stdout, filter_vps);
-       }
-       printf("RADIUS secret: [%s]\n", radius_secret);
-
-       /* Open the device so we can spy */
-       descr = pcap_open_live(dev, SNAPLEN, 1, 0, errbuf);
-       if (descr == NULL)
-       {
-               printf("radsniff: pcap_open_live failed (%s)\n", errbuf);
-               exit(1);
-       }
-
-       /* Apply the rules */
-       if( pcap_compile(descr, &fp, pcap_filter, 0, netp) == -1)
-       {
-               printf("radsniff: pcap_compile failed\n");
-               exit(1);
-       }
-       if (pcap_setfilter(descr, &fp) == -1)
-       {
-               printf("radsniff: pcap_setfilter failed\n");
-               exit(1);
-       }
-
-       /* Now we can set our callback function */
-       pcap_loop(descr, packet_count, got_packet, NULL);
-       pcap_close(descr);
-
-       printf("Done sniffing\n");
-       return 0;
-}
index 3b8549d..d940698 100644 (file)
@@ -1,4 +1,3 @@
-/*@-skipposixheaders@*/
 /*
  * radwho.c    Show who is logged in on the terminal servers.
  *             Can also be installed as fingerd on the UNIX
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] =
+"$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/sysutmp.h>
-#include <freeradius-devel/radutmp.h>
+#include "autoconf.h"
+#include "libradius.h"
 
-#ifdef HAVE_PWD_H
+#include <stdlib.h>
+#include <string.h>
 #include <pwd.h>
-#endif
-
 #include <sys/stat.h>
-
+#include <sys/utsname.h>
 #include <ctype.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "sysutmp.h"
+#include "radutmp.h"
+#include "radiusd.h"
+#include "conffile.h"
 
 /*
  *     FIXME: put in header file.
@@ -50,13 +55,13 @@ RCSID("$Id$")
  */
 static const char *hdr1 =
 "Login      Name              What  TTY  When      From      Location";
-static const char *rfmt1 = "%-10.10s %-17.17s %-5.5s %s%-3u %-9.9s %-9.9s %-.19s%s";
+static const char *rfmt1 = "%-10.10s %-17.17s %-5.5s %s%-3d %-9.9s %-9.9s %-.19s%s";
 static const char *rfmt1r = "%s,%s,%s,%s%u,%s,%s,%s%s";
 
 static const char *hdr2 =
 "Login      Port    What      When          From       Location";
-static const char *rfmt2 = "%-10.10s %s%-5u  %-6.6s %-13.13s %-10.10s %-.28s%s";
-static const char *rfmt2r = "%s,%s%u,%s,%s,%s,%s%s";
+static const char *rfmt2 = "%-10.10s %s%-5d  %-6.6s %-13.13s %-10.10s %-.28s%s";
+static const char *rfmt2r = "%s,%s%d,%s,%s,%s,%s%s";
 
 static const char *eol = "\n";
 static int showname = -1;
@@ -73,6 +78,8 @@ const char *radlib_dir = NULL;
 uint32_t myip = INADDR_ANY;
 int log_stripped_names;
 
+radlog_dest_t radlog_dest = RADLOG_STDOUT;
+
 /*
  *     Global, for log.c to use.
  */
@@ -98,7 +105,7 @@ static FILE *safe_popen(const char *cmd, const char *mode)
        /*
         *      Change all suspect characters into a space.
         */
-       strlcpy(buf, cmd, sizeof(buf));
+       strncpy(buf, cmd, sizeof(buf));
        buf[sizeof(buf) - 1] = 0;
        for (p = buf; *p; p++) {
                if (isalnum((int) *p))
@@ -178,7 +185,6 @@ static void sys_finger(const char *l)
  */
 static char *fullname(char *username)
 {
-#ifdef HAVE_PWD_Hx
        struct passwd *pwd;
        char *s;
 
@@ -186,8 +192,6 @@ static char *fullname(char *username)
                if ((s = strchr(pwd->pw_gecos, ',')) != NULL) *s = 0;
                return pwd->pw_gecos;
        }
-#endif
-
        return username;
 }
 
@@ -222,10 +226,10 @@ static char *dotime(time_t t)
        char *s = ctime(&t);
 
        if (showname) {
-               strlcpy(s + 4, s + 11, 5);
+               strncpy(s + 4, s + 11, 5);
                s[9] = 0;
        } else {
-               strlcpy(s + 4, s + 8, 8);
+               strncpy(s + 4, s + 8, 8);
                s[12] = 0;
        }
 
@@ -238,14 +242,9 @@ static char *dotime(time_t t)
  */
 static const char *hostname(char *buf, size_t buflen, uint32_t ipaddr)
 {
-       /*
-        *      WTF is this code for?
-        */
        if (ipaddr == 0 || ipaddr == (uint32_t)-1 || ipaddr == (uint32_t)-2)
                return "";
-
-       return inet_ntop(AF_INET, &ipaddr, buf, buflen);
-
+       return ip_hostname(buf, buflen, ipaddr);
 }
 
 
@@ -327,7 +326,8 @@ int main(int argc, char **argv)
                        showname = 0;
                        break;
                case 'N':
-                       if (inet_pton(AF_INET, optarg, &nas_ip_address) < 0) {
+                       nas_ip_address = ip_addr(optarg);
+                       if (nas_ip_address == INADDR_NONE) {
                                usage(1);
                        }
                        break;
@@ -386,20 +386,19 @@ int main(int argc, char **argv)
 
                printf("Acct-Status-Type = Accounting-Off\n");
                printf("NAS-IP-Address = %s\n",
-                      hostname(buffer, sizeof(buffer), nas_ip_address));
+                      ip_hostname(buffer, sizeof(buffer), nas_ip_address));
                printf("Acct-Delay-Time = 0\n");
                exit(0);        /* don't bother printing anything else */
        }
-
+       
        /*
         *      Initialize mainconfig
         */
        memset(&mainconfig, 0, sizeof(mainconfig));
-       mainconfig.radlog_dest = RADLOG_STDOUT;
 
         /* Read radiusd.conf */
        snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", radius_dir);
-       maincs = cf_file_read(buffer);
+       maincs = conf_read(NULL, 0, buffer, NULL);
        if (!maincs) {
                fprintf(stderr, "%s: Error reading radiusd.conf.\n", argv[0]);
                exit(1);
@@ -503,10 +502,10 @@ int main(int argc, char **argv)
                if (nas_ip_address != INADDR_NONE) {
                        if (rt.nas_address != nas_ip_address) continue;
                }
-
+               
                memcpy(session_id, rt.session_id, sizeof(rt.session_id));
                session_id[sizeof(rt.session_id)] = 0;
-
+               
                if (!rawoutput && rt.nas_port > (showname ? 999 : 99999)) {
                        portind = ">";
                        portno = (showname ? 999 : 99999);
@@ -533,8 +532,8 @@ int main(int argc, char **argv)
                        if (zap) printf("Acct-Status-Type = Stop\n");
 
                        printf("NAS-IP-Address = %s\n",
-                              hostname(buffer, sizeof(buffer),
-                                       rt.nas_address));
+                              ip_hostname(buffer, sizeof(buffer),
+                                          rt.nas_address));
                        printf("NAS-Port = %u\n", rt.nas_port);
 
                        switch (rt.proto) {
@@ -552,10 +551,10 @@ int main(int argc, char **argv)
                        }
                        if (rt.framed_address != INADDR_NONE) {
                                printf("Framed-IP-Address = %s\n",
-                                      hostname(buffer, sizeof(buffer),
-                                               rt.framed_address));
+                                      ip_hostname(buffer, sizeof(buffer),
+                                                  rt.framed_address));
                        }
-
+                       
                        /*
                         *      Some sanity checks on the time
                         */
@@ -569,7 +568,7 @@ int main(int argc, char **argv)
                                memcpy(nasname, rt.caller_id,
                                       sizeof(rt.caller_id));
                                nasname[sizeof(rt.caller_id)] = '\0';
-
+                               
                                librad_safeprint(nasname, -1, buffer,
                                                 sizeof(buffer));
                                printf("Calling-Station-Id = \"%s\"\n", buffer);
@@ -590,7 +589,7 @@ int main(int argc, char **argv)
                               proto(rt.proto, rt.porttype),
                               portind, portno,
                               dotime(rt.time),
-                              hostname(nasname, sizeof(nasname), rt.nas_address),
+                              ip_hostname(nasname, sizeof(nasname), rt.nas_address),
                               hostname(othername, sizeof(othername), rt.framed_address), eol);
                } else {
                        printf((rawoutput == 0? rfmt2: rfmt2r),
@@ -598,7 +597,7 @@ int main(int argc, char **argv)
                               portind, portno,
                               proto(rt.proto, rt.porttype),
                               dotime(rt.time),
-                              hostname(nasname, sizeof(nasname), rt.nas_address),
+                              ip_hostname(nasname, sizeof(nasname), rt.nas_address),
                               hostname(othername, sizeof(othername), rt.framed_address),
                               eol);
                }
diff --git a/src/main/radzap b/src/main/radzap
deleted file mode 100755 (executable)
index d3d8450..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/sh
-#
-#      $Id$
-#
-
-usage() {
-       echo "Usage: radzap [options] server[:port] secret" >&2
-        echo "       -d raddb_directory: directory where radiusd.conf is located"
-        echo "       -N nas_ip_address: IP address of the NAS to zap."
-       echo "       -P nas_port: NAS port that the user is logged into."
-       echo "       -u username: Name of user to zap (case insensitive)."
-       echo "       -U username: like -u, but case-sensitive."
-       echo "       -x : more debugging output"
-       exit ${1:-0}
-}
-
-while test "$#" != "0"
-do
-  case $1 in
-      -h) usage;;
-
-      -d) RADDB="-d $2";shift;shift;;
-
-      -N) NAS_IP_ADDR="-N $2";shift;shift;;
-
-      -P) NAS_PORT="-P $2";shift;shift;;
-
-      -u) USER_NAME="-u $2";shift;shift;;
-
-      -U) USER_NAME="-U $2";shift;shift;;
-
-      -x) DEBUG="-x";shift;;
-
-      *) break;;
-
-  esac
-done
-
-if test "$#" != "2"; then
-    usage 1 >&2
-fi
-
-
-SERVER=$1
-SECRET=$2
-
-#
-#  Radzap is now a wrapper around radwho & radclient.
-#
-radwho -ZR $RADDB $NAS_IP_ADDR $NAS_PORT $USER_NAME | radclient $DEBUG $RADDB -f - $SERVER acct $SECRET
diff --git a/src/main/radzap.c b/src/main/radzap.c
new file mode 100644 (file)
index 0000000..74860fb
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * radzap.c    Zap a user from the radutmp and radwtmp file.
+ *
+ * Version:    $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000  Alan DeKok <aland@ox.org>
+ */
+
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <sys/file.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+
+#include "radiusd.h"
+#include "radutmp.h"
+#include "conffile.h"
+
+const char *progname;
+const char *radlog_dir = NULL;
+const char *radius_dir = NULL;
+const char *radacct_dir = NULL;
+const char *radlib_dir = NULL;
+radlog_dest_t radlog_dest = RADLOG_FILES;
+int debug_flag = 0;
+int acct_port;
+int log_stripped_names;
+struct main_config_t mainconfig;
+uint32_t radiusip = INADDR_NONE;
+static void usage(void);
+
+struct radutmp_config_t {
+  char *radutmp_fn;
+} radutmpconfig;
+
+static CONF_PARSER module_config[] = {
+  { "filename", PW_TYPE_STRING_PTR, 0, &radutmpconfig.radutmp_fn,  RADUTMP },
+  { NULL, -1, 0, NULL, NULL }
+};
+
+#define LOCK_LEN sizeof(struct radutmp)
+
+static int radutmp_lookup(struct radutmp *u, uint32_t nasaddr,
+               uint32_t port, const char *user)
+{
+       int fd;
+
+       if ((fd = open(radutmpconfig.radutmp_fn, O_RDONLY|O_CREAT, 0644)) >= 0) {
+               /*
+                *      Lock the utmp file.
+                */
+               rad_lockfd(fd, LOCK_LEN);
+
+               /*
+                *      Find the entry for this NAS / portno combination.
+                */
+               while (read(fd, u, sizeof(*u)) == sizeof(*u)) {
+                       if ((nasaddr != 0 && nasaddr != u->nas_address) ||
+                                       (port != u->nas_port) ||
+                                       (user != NULL &&
+                                       strncmp(u->login, user, sizeof u->login) != 0) ||
+                                       u->type != P_LOGIN)
+                               continue;
+                       /*
+                        *      Match. Zap it.
+                        */
+                       close(fd);
+                       return 1;
+               }
+               close(fd);
+       }
+       return 0;
+}
+static int do_accton_packet(uint32_t nasaddr);
+static int do_stop_packet(const struct radutmp *u);
+
+/*
+ *  Display the syntax for starting this program.
+ */
+static void usage(void)
+{
+        fprintf(stderr,
+                        "Usage: %s [-d raddb] [-p acct_port] [-r servername|serverip] termserver [port] [user]\n", progname);
+        fprintf(stderr, "Options:\n\n");
+       fprintf(stderr, "  -d raddb        Set the raddb directory (default is %s)\n", RADIUS_DIR);
+        fprintf(stderr, "  -p acct_port    Accounting port on radius server\n");
+        fprintf(stderr, "  -r radserver    Radius server name or IP address\n");
+        fprintf(stderr, "  termserver      Terminal Server (NAS) name or IP address to match, can be '' for any\n");
+        fprintf(stderr, "  [port]          Terminal Server port to match\n");
+        fprintf(stderr, "  [user]          Login account to match\n");
+        exit(1);
+}
+
+
+/*
+ *     Zap a user from the radutmp and radwtmp file.
+ */
+int main(int argc, char **argv)
+{
+       CONF_SECTION *cs;
+       NAS *nas;
+       uint32_t ip = 0;
+       uint32_t nas_port = ~0;
+       char *user = NULL;
+       char *s;
+       char buf[256];
+       struct radutmp u;
+       int argval;
+
+       progname = argv[0];
+
+       radius_dir = strdup(RADIUS_DIR);
+
+        /*  Process the options.  */
+        while ((argval = getopt(argc, argv, "d:p:r:")) != EOF) {
+
+                switch(argval) {
+
+                       case 'd':
+                               if (radius_dir) free(radius_dir);
+                               radius_dir = strdup(optarg);
+                               break;
+                        case 'p':
+                               acct_port = atoi(optarg);
+                                break;
+
+                        case 'r':
+                                if ((radiusip = ip_getaddr(optarg)) == INADDR_NONE) {
+                                        fprintf(stderr, "%s: %s: radius server unknown\n",
+                                                progname, optarg);
+                                        exit(1);
+                               }
+                                break;
+
+                        default:
+                                usage();
+                                exit(1);
+                }
+        }
+
+
+       if (argc == optind) {   /* no terminal server specified */
+               usage();
+                exit(1);
+       }
+
+       if (argc > optind + 1) {        /* NAS port given */
+               s = argv[optind+1];
+               if (*s == 's' || *s == 'S') s++;
+               nas_port = strtoul(s, NULL, 10);
+       }
+
+       if (argc > optind + 2) {        /* username (login) given */
+               user = argv[optind+2];
+       }
+
+       /*
+        *      Find the IP address of the terminal server.
+        */
+       if ((nas = nas_findbyname(argv[optind])) == NULL && argv[optind][0] != 0) {
+               if ((ip = ip_getaddr(argv[optind])) == INADDR_NONE) {
+                       fprintf(stderr, "%s: host not found.\n", argv[optind]);
+                       exit(1);
+               }
+       }
+       if (nas != NULL)
+               ip = nas->ipaddr;
+
+       /*
+        *      Ensure that the configuration is initialized.
+        */
+       memset(&mainconfig, 0, sizeof(mainconfig));
+
+        /* Read radiusd.conf */
+       if (read_mainconfig(0) < 0) {
+               fprintf(stderr, "%s: Error reading radiusd.conf.\n", argv[0]);
+               exit(1);
+       }
+
+        /* Read the radutmp section of radiusd.conf */
+        cs = cf_section_sub_find(cf_section_find("modules"), "radutmp");
+        if(!cs) {
+                fprintf(stderr, "%s: No configuration information in radutmp section of radiusd.conf!\n",
+                        argv[0]);
+                exit(1);
+        }
+
+        cf_section_parse(cs, NULL, module_config);
+
+       printf("%s: zapping termserver %s, port %u",
+               progname, ip_hostname(buf, sizeof(buf), ip), nas_port);
+       if (user != NULL)
+               printf(", user %s", user);
+       printf("\n");
+
+       if (nas_port == ~0) {
+               return do_accton_packet(ip);
+       }
+
+       if (!radutmp_lookup(&u, ip, nas_port, user)) {
+               fprintf(stderr, "Entry not found\n");
+               return 1;
+       }
+
+       return do_stop_packet(&u);
+}
+
+static int getport(const char *name)
+{
+       struct servent *svp;
+
+       svp = getservbyname(name, "udp");
+       if (svp == NULL) {
+               return 0;
+       }
+
+       return ntohs(svp->s_port);
+}
+
+static const char *getsecret(uint32_t server)
+{
+       RADCLIENT *cl;
+
+       cl = client_find(server);
+       if (cl == NULL) {
+               char buf[32];
+               radlog(L_ERR|L_CONS, "No clients entry for %s",
+                      ip_ntoa(buf,server));
+               exit(1);
+       }
+       return (const char *)cl->secret;
+}
+
+/* Packet-fabrication macros. Don't stare directly at them without protective
+ * eye gear */
+#define PAIR(n,v,t,e) do { \
+  if(!(vp=paircreate(n, t))) { \
+    radlog(L_ERR|L_CONS, "no memory"); \
+    pairfree(&req->vps); \
+    return 1; \
+  } \
+  vp->e=v; \
+  pairadd(&req->vps, vp); \
+} while(0)
+#define INTPAIR(n,v) PAIR(n,v,PW_TYPE_INTEGER,lvalue)
+#define IPPAIR(n,v) PAIR(n,v,PW_TYPE_IPADDR,lvalue)
+#define STRINGPAIR(n,v) do { \
+  if(!(vp=paircreate(n, PW_TYPE_STRING))) { \
+    radlog(L_ERR|L_CONS, "no memory"); \
+    pairfree(&req->vps); \
+    return 1; \
+  } \
+  strNcpy((char *)vp->strvalue, v, sizeof vp->strvalue); \
+  vp->length=strlen(v); \
+  pairadd(&req->vps, vp); \
+} while(0)
+
+static int do_packet(int allports, uint32_t nasaddr, const struct radutmp *u)
+{
+       int i, retries=5, timeout=3;
+       struct timeval tv;
+       RADIUS_PACKET *req, *rep = NULL;
+       VALUE_PAIR *vp;
+       const char *secret;
+
+       if ((req = rad_alloc(1)) == NULL) {
+               librad_perror("radzap");
+               exit(1);
+       }
+       req->id = getpid() & 0xFF;
+       req->code = PW_ACCOUNTING_REQUEST;
+       req->dst_port = acct_port;
+       if(req->dst_port == 0)
+               req->dst_port = getport("radacct");
+       if(req->dst_port == 0)
+               req->dst_port = PW_ACCT_UDP_PORT;
+       if (radiusip == INADDR_NONE) {
+               req->dst_ipaddr = ip_getaddr("localhost");
+       }
+       else {
+               req->dst_ipaddr = radiusip;
+       }
+       if(!req->dst_ipaddr)
+               req->dst_ipaddr = 0x7f000001;
+       req->vps = NULL;
+       secret = getsecret(req->dst_ipaddr);
+
+       if(allports != 0) {
+               INTPAIR(PW_ACCT_STATUS_TYPE, PW_STATUS_ACCOUNTING_OFF);
+               IPPAIR(PW_NAS_IP_ADDRESS, nasaddr);
+               INTPAIR(PW_ACCT_DELAY_TIME, 0);
+       } else {
+               char login[sizeof u->login+1];
+               char session_id[sizeof u->session_id+1];
+               strNcpy(login, u->login, sizeof login);
+               strNcpy(session_id, u->session_id, sizeof session_id);
+               INTPAIR(PW_ACCT_STATUS_TYPE, PW_STATUS_STOP);
+               IPPAIR(PW_NAS_IP_ADDRESS, u->nas_address);
+               INTPAIR(PW_ACCT_DELAY_TIME, 0);
+               STRINGPAIR(PW_USER_NAME, login);
+               INTPAIR(PW_NAS_PORT, u->nas_port);
+               STRINGPAIR(PW_ACCT_SESSION_ID, session_id);
+               if(u->proto=='P') {
+                       INTPAIR(PW_SERVICE_TYPE, PW_FRAMED_USER);
+                       INTPAIR(PW_FRAMED_PROTOCOL, PW_PPP);
+               } else if(u->proto=='S') {
+                       INTPAIR(PW_SERVICE_TYPE, PW_FRAMED_USER);
+                       INTPAIR(PW_FRAMED_PROTOCOL, PW_SLIP);
+               } else {
+                       INTPAIR(PW_SERVICE_TYPE, PW_LOGIN_USER); /* A guess, really */
+               }
+               IPPAIR(PW_FRAMED_IP_ADDRESS, u->framed_address);
+               INTPAIR(PW_ACCT_SESSION_TIME, 0);
+               INTPAIR(PW_ACCT_INPUT_OCTETS, 0);
+               INTPAIR(PW_ACCT_OUTPUT_OCTETS, 0);
+               INTPAIR(PW_ACCT_INPUT_PACKETS, 0);
+               INTPAIR(PW_ACCT_OUTPUT_PACKETS, 0);
+       }
+       if ((req->sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("radzap: socket: ");
+               exit(1);
+       }
+
+       for (i = 0; i < retries; i++) {
+               fd_set rdfdesc;
+
+               rad_send(req, NULL, secret);
+
+               /* And wait for reply, timing out as necessary */
+               FD_ZERO(&rdfdesc);
+               FD_SET(req->sockfd, &rdfdesc);
+
+               tv.tv_sec = (int)timeout;
+               tv.tv_usec = 1000000 * (timeout - (int)timeout);
+
+               /* Something's wrong if we don't get exactly one fd. */
+               if (select(req->sockfd + 1, &rdfdesc, NULL, NULL, &tv) != 1) {
+                       continue;
+               }
+
+               rep = rad_recv(req->sockfd);
+               if (rep != NULL) {
+                       break;
+               } else {        /* NULL: couldn't receive the packet */
+                       librad_perror("radzap:");
+                       exit(1);
+               }
+       }
+
+       /* No response or no data read (?) */
+       if (i == retries) {
+               fprintf(stderr, "%s: no response from server\n", progname);
+               exit(1);
+       }
+
+       if (rad_decode(rep, req, secret) != 0) {
+               librad_perror("rad_decode");
+               exit(1);
+       }
+
+       vp_printlist(stdout, rep->vps);
+       return 0;
+}
+
+static int do_accton_packet(uint32_t nasaddr)
+{
+       return do_packet(1, nasaddr, 0);
+}
+
+static int do_stop_packet(const struct radutmp *u)
+{
+       return do_packet(0, 0, u);
+}
diff --git a/src/main/realms.c b/src/main/realms.c
deleted file mode 100644 (file)
index baad544..0000000
+++ /dev/null
@@ -1,1298 +0,0 @@
-/*
- * realms.c    Realm handling code
- *
- * Version:     $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2007  The FreeRADIUS server project
- * Copyright 2007  Alan DeKok <aland@deployingradius.com>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
-
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <fcntl.h>
-
-static rbtree_t *realms_byname = NULL;
-
-static rbtree_t        *home_servers_byaddr = NULL;
-static rbtree_t        *home_servers_byname = NULL;
-
-static rbtree_t        *home_pools_byname = NULL;
-
-static int realm_name_cmp(const void *one, const void *two)
-{
-       const REALM *a = one;
-       const REALM *b = two;
-
-       return strcasecmp(a->name, b->name);
-}
-
-
-static int home_server_name_cmp(const void *one, const void *two)
-{
-       const home_server *a = one;
-       const home_server *b = two;
-
-       if (a->type < b->type) return -1;
-       if (a->type > b->type) return +1;
-
-       return strcasecmp(a->name, b->name);
-}
-
-static int home_server_addr_cmp(const void *one, const void *two)
-{
-       const home_server *a = one;
-       const home_server *b = two;
-
-       if (a->port < b->port) return -1;
-       if (a->port > b->port) return +1;
-
-       return lrad_ipaddr_cmp(&a->ipaddr, &b->ipaddr);
-}
-
-
-static int home_pool_name_cmp(const void *one, const void *two)
-{
-       const home_pool_t *a = one;
-       const home_pool_t *b = two;
-
-       if (a->server_type < b->server_type) return -1;
-       if (a->server_type > b->server_type) return +1;
-
-       return strcasecmp(a->name, b->name);
-}
-
-
-void realms_free(void)
-{
-       rbtree_free(home_servers_byname);
-       home_servers_byname = NULL;
-
-       rbtree_free(home_servers_byaddr);
-       home_servers_byaddr = NULL;
-
-       rbtree_free(home_pools_byname);
-       home_pools_byname = NULL;
-
-       rbtree_free(realms_byname);
-       realms_byname = NULL;
-}
-
-
-int realms_init(const char *filename)
-{
-       CONF_SECTION *cs;
-
-       if (realms_byname) return 1;
-
-       realms_byname = rbtree_create(realm_name_cmp, free, 0);
-       if (!realms_byname) {
-               realms_free();
-               return 0;
-       }
-
-       home_servers_byaddr = rbtree_create(home_server_addr_cmp, free, 0);
-       if (!home_servers_byaddr) {
-               realms_free();
-               return 0;
-       }
-
-       home_servers_byname = rbtree_create(home_server_name_cmp, NULL, 0);
-       if (!home_servers_byname) {
-               realms_free();
-               return 0;
-       }
-
-       home_pools_byname = rbtree_create(home_pool_name_cmp, free, 0);
-       if (!home_pools_byname) {
-               realms_free();
-               return 0;
-       }
-
-       for (cs = cf_subsection_find_next(mainconfig.config, NULL, "realm");
-            cs != NULL;
-            cs = cf_subsection_find_next(mainconfig.config, cs, "realm")) {
-               if (!realm_add(filename, cs)) {
-                       realms_free();
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-static struct in_addr hs_ip4addr;
-static struct in6_addr hs_ip6addr;
-static char *hs_type = NULL;
-static char *hs_check = NULL;
-
-static CONF_PARSER home_server_config[] = {
-       { "ipaddr",  PW_TYPE_IPADDR,
-         0, &hs_ip4addr,  NULL },
-       { "ipv6addr",  PW_TYPE_IPV6ADDR,
-         0, &hs_ip6addr, NULL },
-
-       { "hostname",  PW_TYPE_STRING_PTR,
-         offsetof(home_server,hostname), NULL,  NULL},
-       { "port", PW_TYPE_INTEGER,
-         offsetof(home_server,port), NULL,   "0" },
-
-       { "type",  PW_TYPE_STRING_PTR,
-         0, &hs_type, NULL },
-
-       { "secret",  PW_TYPE_STRING_PTR,
-         offsetof(home_server,secret), NULL,  NULL},
-
-       { "response_window", PW_TYPE_INTEGER,
-         offsetof(home_server,response_window), NULL,   "30" },
-       { "max_outstanding", PW_TYPE_INTEGER,
-         offsetof(home_server,max_outstanding), NULL,   "65536" },
-
-       { "zombie_period", PW_TYPE_INTEGER,
-         offsetof(home_server,zombie_period), NULL,   "40" },
-       { "status_check", PW_TYPE_STRING_PTR,
-         0, &hs_check,   "none" },
-       { "ping_check", PW_TYPE_STRING_PTR,
-         0, &hs_check,   "none" },
-
-       { "ping_interval", PW_TYPE_INTEGER,
-         offsetof(home_server,ping_interval), NULL,   "30" },
-       { "check_interval", PW_TYPE_INTEGER,
-         offsetof(home_server,ping_interval), NULL,   "30" },
-       { "num_answers_to_alive", PW_TYPE_INTEGER,
-         offsetof(home_server,num_pings_to_alive), NULL,   "3" },
-       { "num_pings_to_alive", PW_TYPE_INTEGER,
-         offsetof(home_server,num_pings_to_alive), NULL,   "3" },
-       { "revive_interval", PW_TYPE_INTEGER,
-         offsetof(home_server,revive_interval), NULL,   "300" },
-       { "status_check_timeout", PW_TYPE_INTEGER,
-         offsetof(home_server,ping_timeout), NULL,   "4" },
-
-       { "username",  PW_TYPE_STRING_PTR,
-         offsetof(home_server,ping_user_name), NULL,  NULL},
-       { "password",  PW_TYPE_STRING_PTR,
-         offsetof(home_server,ping_user_password), NULL,  NULL},
-
-       { NULL, -1, 0, NULL, NULL }             /* end the list */
-
-};
-
-
-static int home_server_add(const char *filename, CONF_SECTION *cs, int type)
-{
-       const char *name2;
-       home_server *home;
-       int dual = FALSE;
-
-       name2 = cf_section_name1(cs);
-       if (!name2 || (strcasecmp(name2, "home_server") != 0)) {
-               radlog(L_ERR, "%s[%d]: Section is not a home_server.",
-                      filename, cf_section_lineno(cs));
-               return 0;
-       }
-
-       name2 = cf_section_name2(cs);
-       if (!name2) {
-               radlog(L_ERR, "%s[%d]: Home server section is missing a name.",
-                      filename, cf_section_lineno(cs));
-               return 0;
-       }
-
-       home = rad_malloc(sizeof(*home));
-       memset(home, 0, sizeof(*home));
-
-       home->name = name2;
-
-       memset(&hs_ip4addr, 0, sizeof(hs_ip4addr));
-       memset(&hs_ip6addr, 0, sizeof(hs_ip6addr));
-       cf_section_parse(cs, home, home_server_config);
-
-       if (!home->hostname && (htonl(hs_ip4addr.s_addr) == INADDR_NONE) &&
-           IN6_IS_ADDR_UNSPECIFIED(&hs_ip6addr)) {
-               radlog(L_ERR, "%s[%d]: No hostname, IPv4 address, or IPv6 address defined for home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               free(hs_type);
-               hs_type = NULL;
-               free(hs_check);
-               hs_check = NULL;
-               return 0;
-       }
-
-       /*
-        *      FIXME: Parse home->hostname!
-        *
-        *      Right now, only ipaddr && ip6addr are used.
-        *      The old-style parsing still allows hostnames.
-        */
-       if (htonl(hs_ip4addr.s_addr) != INADDR_NONE) {
-               home->ipaddr.af = AF_INET;
-               home->ipaddr.ipaddr.ip4addr = hs_ip4addr;
-
-       } else if (!IN6_IS_ADDR_UNSPECIFIED(&hs_ip6addr)) {
-               home->ipaddr.af = AF_INET6;
-               home->ipaddr.ipaddr.ip6addr = hs_ip6addr;
-
-       } else {
-               radlog(L_ERR, "%s[%d]: FIXME: parse hostname for home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               free(hs_type);
-               hs_type = NULL;
-               free(hs_check);
-               hs_check = NULL;
-               return 0;
-       }
-
-       if (!home->port || (home->port > 65535)) {
-               radlog(L_ERR, "%s[%d]: No port, or invalid port defined for home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               free(hs_type);
-               hs_type = NULL;
-               free(hs_check);
-               hs_check = NULL;
-               return 0;
-       }
-
-       if (0) {
-               radlog(L_ERR, "%s[%d]: Fatal error!  Home server %s is ourselves!",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               free(hs_type);
-               hs_type = NULL;
-               free(hs_check);
-               hs_check = NULL;
-               return 0;
-       }
-
-       if (strcasecmp(hs_type, "auth") == 0) {
-               home->type = HOME_TYPE_AUTH;
-               if (type != home->type) {
-                       radlog(L_ERR, "%s[%d]: Server pool of \"acct\" servers cannot include home server %s of type \"auth\"",
-                              filename, cf_section_lineno(cs), name2);
-                       free(home);
-                       return 0;
-               }
-
-       } else if (strcasecmp(hs_type, "acct") == 0) {
-               home->type = HOME_TYPE_ACCT;
-               if (type != home->type) {
-                       radlog(L_ERR, "%s[%d]: Server pool of \"auth\" servers cannot include home server %s of type \"acct\"",
-                              filename, cf_section_lineno(cs), name2);
-                       free(home);
-                       return 0;
-               }
-
-       } else if (strcasecmp(hs_type, "auth+acct") == 0) {
-               home->type = HOME_TYPE_AUTH;
-               dual = TRUE;
-
-       } else {
-               radlog(L_ERR, "%s[%d]: Invalid type \"%s\" for home server %s.",
-                      filename, cf_section_lineno(cs), hs_type, name2);
-               free(home);
-               free(hs_type);
-               hs_type = NULL;
-               free(hs_check);
-               hs_check = NULL;
-               return 0;
-       }
-       free(hs_type);
-       hs_type = NULL;
-
-       if (!home->secret) {
-               radlog(L_ERR, "%s[%d]: No shared secret defined for home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               return 0;
-       }
-
-       if (strcasecmp(hs_check, "none") == 0) {
-               home->ping_check = HOME_PING_CHECK_NONE;
-
-       } else if (strcasecmp(hs_check, "status-server") == 0) {
-               home->ping_check = HOME_PING_CHECK_STATUS_SERVER;
-
-       } else if (strcasecmp(hs_check, "request") == 0) {
-               home->ping_check = HOME_PING_CHECK_REQUEST;
-
-       } else {
-               radlog(L_ERR, "%s[%d]: Invalid ping_check \"%s\" for home server %s.",
-                      filename, cf_section_lineno(cs), hs_check, name2);
-               free(home);
-               free(hs_check);
-               hs_check = NULL;
-               return 0;
-       }
-       free(hs_check);
-       hs_check = NULL;
-
-       if ((home->ping_check != HOME_PING_CHECK_NONE) &&
-           (home->ping_check != HOME_PING_CHECK_STATUS_SERVER)) {
-               if (!home->ping_user_name) {
-                       radlog(L_INFO, "%s[%d]: You must supply a user name to enable ping checks",
-                              filename, cf_section_lineno(cs));
-                       free(home);
-                       return 0;
-               }
-
-               if ((home->type == HOME_TYPE_AUTH) &&
-                   !home->ping_user_password) {
-                       radlog(L_INFO, "%s[%d]: You must supply a password to enable ping checks",
-                              filename, cf_section_lineno(cs));
-                       free(home);
-                       return 0;
-               }
-       }
-
-       if (rbtree_finddata(home_servers_byaddr, home)) {
-               radlog(L_INFO, "%s[%d]: Ignoring duplicate home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               return 1;
-       }
-
-       if (!rbtree_insert(home_servers_byname, home)) {
-               radlog(L_ERR, "%s[%d]: Internal error adding home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               return 0;
-       }
-
-       if (!rbtree_insert(home_servers_byaddr, home)) {
-               rbtree_deletebydata(home_servers_byname, home);
-               radlog(L_ERR, "%s[%d]: Internal error adding home server %s.",
-                      filename, cf_section_lineno(cs), name2);
-               free(home);
-               return 0;
-       }
-
-       if (home->response_window < 5) home->response_window = 5;
-       if (home->response_window > 60) home->response_window = 60;
-
-       if (home->max_outstanding < 8) home->max_outstanding = 8;
-       if (home->max_outstanding > 65536*16) home->max_outstanding = 65536*16;
-
-       if (home->ping_interval < 6) home->ping_interval = 6;
-       if (home->ping_interval > 120) home->ping_interval = 120;
-
-       if (home->zombie_period < 20) home->zombie_period = 20;
-       if (home->zombie_period > 120) home->zombie_period = 120;
-
-       if (home->zombie_period < home->response_window) {
-               home->zombie_period = home->response_window;
-       }
-
-       if (home->num_pings_to_alive < 3) home->num_pings_to_alive = 3;
-       if (home->num_pings_to_alive > 10) home->num_pings_to_alive = 10;
-
-       if (home->ping_timeout < 3) home->ping_timeout = 3;
-       if (home->ping_timeout > 10) home->ping_timeout = 10;
-
-       if (home->revive_interval < 60) home->revive_interval = 60;
-       if (home->revive_interval > 3600) home->revive_interval = 3600;
-
-       if (dual) {
-               home_server *home2 = rad_malloc(sizeof(*home2));
-
-               memcpy(home2, home, sizeof(*home2));
-
-               home2->type = HOME_TYPE_ACCT;
-               home2->port++;
-               home2->ping_user_password = NULL;
-
-               if (!rbtree_insert(home_servers_byname, home2)) {
-                       radlog(L_ERR, "%s[%d]: Internal error adding home server %s.",
-                              filename, cf_section_lineno(cs), name2);
-                       free(home2);
-                       return 0;
-               }
-               
-               if (!rbtree_insert(home_servers_byaddr, home2)) {
-                       rbtree_deletebydata(home_servers_byname, home2);
-                       radlog(L_ERR, "%s[%d]: Internal error adding home server %s.",
-                              filename, cf_section_lineno(cs), name2);
-                       free(home2);
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
-
-static int server_pool_add(const char *filename, CONF_SECTION *cs,
-                          int server_type)
-{
-       const char *name2;
-       home_pool_t *pool = NULL;
-       const char *value;
-       CONF_PAIR *cp;
-       int num_home_servers;
-
-       name2 = cf_section_name1(cs);
-       if (!name2 || (strcasecmp(name2, "server_pool") != 0)) {
-               radlog(L_ERR, "%s[%d]: Section is not a server_pool.",
-                      filename, cf_section_lineno(cs));
-               return 0;
-       }
-
-       name2 = cf_section_name2(cs);
-       if (!name2) {
-               radlog(L_ERR, "%s[%d]: Server pool section is missing a name.",
-                      filename, cf_section_lineno(cs));
-               return 0;
-       }
-
-       /*
-        *      Count the home servers and initalize them.
-        */
-       num_home_servers = 0;
-       for (cp = cf_pair_find(cs, "home_server");
-            cp != NULL;
-            cp = cf_pair_find_next(cs, cp, "home_server")) {
-               home_server myhome, *home;
-               CONF_SECTION *server_cs;
-
-               num_home_servers++;
-
-               value = cf_pair_value(cp);
-               if (!value) {
-                       radlog(L_ERR, "%s[%d]: No value given for home_server.",
-                              filename, cf_pair_lineno(cp));
-                       return 0;;
-               }
-
-               myhome.name = value;
-               myhome.type = server_type;
-               home = rbtree_finddata(home_servers_byname, &myhome);
-               if (home) continue;
-
-               server_cs = cf_section_sub_find_name2(NULL,
-                                                     "home_server",
-                                                     value);
-               if (!server_cs) {
-                       radlog(L_ERR, "%s[%d]: Unknown home_server \"%s\".",
-                              filename, cf_pair_lineno(cp), value);
-                       return 0;
-               }
-
-               if (!home_server_add(filename, server_cs, server_type)) {
-                       return 0;
-               }
-
-               home = rbtree_finddata(home_servers_byname, &myhome);
-               if (!home) {
-                       radlog(L_ERR, "Internal sanity check failed %d",
-                              __LINE__);
-                       return 0;
-               }
-       }
-
-       if (num_home_servers == 0) {
-               radlog(L_ERR, "%s[%d]: No home servers defined in pool %s",
-                      filename, cf_section_lineno(cs), name2);
-               goto error;
-       }
-
-       pool = rad_malloc(sizeof(*pool) + num_home_servers * sizeof(pool->servers[0]));
-       memset(pool, 0, sizeof(*pool) + num_home_servers * sizeof(pool->servers[0]));
-
-       pool->type = HOME_POOL_FAIL_OVER;
-       pool->name = name2;
-       pool->server_type = server_type;
-
-       DEBUG2(" server_pool %s {", name2);
-
-       cp = cf_pair_find(cs, "type");
-       if (cp) {
-               static LRAD_NAME_NUMBER pool_types[] = {
-                       { "load-balance", HOME_POOL_LOAD_BALANCE },
-                       { "fail-over", HOME_POOL_FAIL_OVER },
-                       { "round_robin", HOME_POOL_LOAD_BALANCE },
-                       { "fail_over", HOME_POOL_FAIL_OVER },
-                       { "client-balance", HOME_POOL_CLIENT_BALANCE },
-                       { "client-port-balance", HOME_POOL_CLIENT_PORT_BALANCE },
-                       { NULL, 0 }
-               };
-
-               value = cf_pair_value(cp);
-               if (!value) {
-                       radlog(L_ERR, "%s[%d]: No value given for type.",
-                              filename, cf_pair_lineno(cp));
-                       goto error;
-               }
-
-               pool->type = lrad_str2int(pool_types, value, 0);
-               if (!pool->type) {
-                       radlog(L_ERR, "%s[%d]: Unknown type \"%s\".",
-                              filename, cf_pair_lineno(cp), value);
-                       goto error;
-               }
-
-               DEBUG2("\ttype = %s", name2, value);
-       }
-
-       for (cp = cf_pair_find(cs, "home_server");
-            cp != NULL;
-            cp = cf_pair_find_next(cs, cp, "home_server")) {
-               home_server myhome, *home;
-
-               value = cf_pair_value(cp);
-               if (!value) {
-                       radlog(L_ERR, "%s[%d]: No value given for home_server.",
-                              filename, cf_pair_lineno(cp));
-                       goto error;
-               }
-
-               myhome.name = value;
-               myhome.type = server_type;
-
-               home = rbtree_finddata(home_servers_byname, &myhome);
-               if (!home) {
-                       DEBUG2("Internal sanity check failed");
-                       goto error;
-               }
-
-               if (0) {
-                       DEBUG2("Warning: Duplicate home server %s in server pool %s", home->name, pool->name);
-                       continue;
-               }
-
-               DEBUG2("\thome_server = %s", home->name);
-               pool->servers[pool->num_home_servers] = home;
-               pool->num_home_servers++;
-       } /* loop over home_server's */
-
-       if (!rbtree_insert(home_pools_byname, pool)) {
-               rad_assert("Internal sanity check failed");
-               goto error;
-       }
-
-       DEBUG2(" }");
-
-       rad_assert(pool->server_type != 0);
-
-       return 1;
-
- error:
-       DEBUG2(" }");
-       free(pool);
-       return 0;
-}
-
-
-static int old_server_add(const char *filename, int lineno, const char *realm,
-                         const char *name, const char *secret,
-                         home_pool_type_t ldflag, home_pool_t **pool_p,
-                         int type)
-{
-       int i, insert_point, num_home_servers;
-       home_server myhome, *home;
-       home_pool_t mypool, *pool;
-       CONF_SECTION *cs;
-
-       /*
-        *      LOCAL realms get sanity checked, and nothing else happens.
-        */
-       if (strcmp(name, "LOCAL") == 0) {
-               if (*pool_p) {
-                       radlog(L_ERR, "%s[%d]: Realm \"%s\" cannot be both LOCAL and remote", filename, lineno, name);
-                       return 0;
-               }
-               return 1;
-       }
-
-       mypool.name = realm;
-       mypool.server_type = type;
-       pool = rbtree_finddata(home_pools_byname, &mypool);
-       if (pool) {
-               if (pool->type != ldflag) {
-                       radlog(L_ERR, "%s[%d]: Inconsistent ldflag for server pool \"%s\"", filename, lineno, name);
-                       return 0;
-               }
-
-               if (pool->server_type != type) {
-                       radlog(L_ERR, "%s[%d]: Inconsistent home server type for server pool \"%s\"", filename, lineno, name);
-                       return 0;
-               }
-       }
-
-       myhome.name = name;
-       myhome.type = type;
-       home = rbtree_finddata(home_servers_byname, &myhome);
-       if (home) {
-               if (strcmp(home->secret, secret) != 0) {
-                       radlog(L_ERR, "%s[%d]: Inconsistent shared secret for home server \"%s\"", filename, lineno, name);
-                       return 0;
-               }
-
-               if (home->type != type) {
-                       radlog(L_ERR, "%s[%d]: Inconsistent type for home server \"%s\"", filename, lineno, name);
-                       return 0;
-               }
-
-               /*
-                *      See if the home server is already listed
-                *      in the pool.  If so, do nothing else.
-                */
-               if (pool) for (i = 0; i < pool->num_home_servers; i++) {
-                       if (pool->servers[i] == home) {
-                               return 1;
-                       }
-               }
-       }
-
-       /*
-        *      If we do have a pool, check that there is room to
-        *      insert the home server we've found, or the one that we
-        *      create here.
-        *
-        *      Note that we insert it into the LAST available
-        *      position, in order to maintain the same order as in
-        *      the configuration files.
-        */
-       insert_point = -1;
-       if (pool) {
-               for (i = pool->num_home_servers - 1; i >= 0; i--) {
-                       if (pool->servers[i]) break;
-
-                       if (!pool->servers[i]) {
-                               insert_point = i;
-                       }
-               }
-
-               if (insert_point < 0) {
-                       radlog(L_ERR, "%s[%d]: No room in pool to add home server \"%s\".  Please update the realm configuration to use the new-style home servers and server pools.", filename, lineno, name);
-                       return 0;
-               }
-       }
-
-       /*
-        *      No home server, allocate one.
-        */
-       if (!home) {
-               const char *p;
-               char *q;
-
-               home = rad_malloc(sizeof(*home));
-               memset(home, 0, sizeof(*home));
-
-               home->name = name;
-               home->hostname = name;
-               home->type = type;
-               home->secret = secret;
-
-               p = strchr(name, ':');
-               if (!p) {
-                       if (type == HOME_TYPE_AUTH) {
-                               home->port = PW_AUTH_UDP_PORT;
-                       } else {
-                               home->port = PW_ACCT_UDP_PORT;
-                       }
-
-                       p = name;
-                       q = NULL;
-
-               } else if (p == name) {
-                               radlog(L_ERR, "%s[%d]: Invalid hostname %s.",
-                                      filename, lineno, name);
-                               free(home);
-                               return 0;
-
-               } else {
-                       home->port = atoi(p + 1);
-                       if ((home->port == 0) || (home->port > 65535)) {
-                               radlog(L_ERR, "%s[%d]: Invalid port %s.",
-                                      filename, lineno, p + 1);
-                               free(home);
-                               return 0;
-                       }
-
-                       q = rad_malloc((p - name) + 1);
-                       memcpy(q, name, (p - name));
-                       q[p - name] = '\0';
-                       p = q;
-               }
-
-               if (ip_hton(p, AF_UNSPEC, &home->ipaddr) < 0) {
-                       radlog(L_ERR, "%s[%d]: Failed looking up hostname %s.",
-                              filename, lineno, p);
-                       free(home);
-                       free(q);
-                       return 0;
-               }
-               free(q);
-
-               /*
-                *      Use the old-style configuration.
-                */
-               home->max_outstanding = 65535*16;
-               home->zombie_period = mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count;
-               if (home->zombie_period == 0) home->zombie_period =30;
-               home->response_window = home->zombie_period - 1;
-
-               home->ping_check = HOME_PING_CHECK_NONE;
-
-               home->revive_interval = mainconfig.proxy_dead_time;
-
-               if (rbtree_finddata(home_servers_byaddr, home)) {
-                       radlog(L_ERR, "%s[%d]: Home server %s has the same IP address as another home server.",
-                              filename, lineno, name);
-                       free(home);
-                       return 0;
-               }
-
-               if (!rbtree_insert(home_servers_byname, home)) {
-                       radlog(L_ERR, "%s[%d]: Internal error adding home server %s.",
-                              filename, lineno, name);
-                       free(home);
-                       return 0;
-               }
-
-               if (!rbtree_insert(home_servers_byaddr, home)) {
-                       rbtree_deletebydata(home_servers_byname, home);
-                       radlog(L_ERR, "%s[%d]: Internal error adding home server %s.",
-                              filename, lineno, name);
-                       free(home);
-                       return 0;
-               }
-       }
-
-       /*
-        *      We now have a home server, see if we can insert it
-        *      into pre-existing pool.
-        */
-       if (insert_point >= 0) {
-               rad_assert(pool != NULL);
-               pool->servers[insert_point] = home;
-               return 1;
-       }
-
-       rad_assert(pool == NULL);
-       rad_assert(home != NULL);
-
-       /*
-        *      Count the old-style realms of this name.
-        */
-       num_home_servers = 0;
-       for (cs = cf_section_sub_find_name2(mainconfig.config, "realm", realm);
-            cs != NULL;
-            cs = cf_section_sub_find_name2(cs, "realm", realm)) {
-               num_home_servers++;
-       }
-
-       pool = rad_malloc(sizeof(*pool) + num_home_servers * sizeof(pool->servers[0]));
-       memset(pool, 0, sizeof(*pool) + num_home_servers * sizeof(pool->servers[0]));
-
-       pool->name = realm;
-       pool->type = ldflag;
-       pool->server_type = type;
-       pool->num_home_servers = num_home_servers;
-       pool->servers[0] = home;
-
-       if (!rbtree_insert(home_pools_byname, pool)) {
-               rad_assert("Internal sanity check failed");
-               return 0;
-       }
-
-       *pool_p = pool;
-
-       return 1;
-}
-
-static int old_realm_config(const char *filename, CONF_SECTION *cs, REALM *r)
-{
-       char *host;
-       const char *secret;
-       home_pool_type_t ldflag;
-
-       secret = cf_section_value_find(cs, "secret");
-
-       host = cf_section_value_find(cs, "ldflag");
-       if (!host ||
-           (strcasecmp(host, "fail_over") == 0)) {
-               ldflag = HOME_POOL_FAIL_OVER;
-               DEBUG2("\tldflag = fail_over");
-
-       } else if (strcasecmp(host, "round_robin") == 0) {
-               ldflag = HOME_POOL_LOAD_BALANCE;
-               DEBUG2("\tldflag = round_robin");
-
-       } else {
-               radlog(L_ERR, "%s[%d]: Unknown value \"%s\" for ldflag",
-                      filename, cf_section_lineno(cs), host);
-               return 0;
-       }
-
-       /*
-        *      Allow old-style if it doesn't exist, or if it exists and
-        *      it's LOCAL.
-        */
-       if (((host = cf_section_value_find(cs, "authhost")) != NULL) &&
-           (strcmp(host, "LOCAL") != 0)) {
-               if (!secret) {
-                       radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s",
-                              filename, cf_section_lineno(cs), r->name);
-                       return 0;
-               }
-
-               DEBUG2("\tauthhost = %s",  host);
-
-               if (!old_server_add(filename, cf_section_lineno(cs),
-                                   r->name, host, secret, ldflag,
-                                   &r->auth_pool, HOME_TYPE_AUTH)) {
-                       return 0;
-               }
-       }
-
-       if (((host = cf_section_value_find(cs, "accthost")) != NULL) &&
-           (strcmp(host, "LOCAL") != 0)) {
-               if (!secret) {
-                       radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s",
-                              filename, cf_section_lineno(cs), r->name);
-                       return 0;
-               }
-
-               DEBUG2("\taccthost = %s", host);
-
-               if (!old_server_add(filename, cf_section_lineno(cs),
-                                   r->name, host, secret, ldflag,
-                                   &r->acct_pool, HOME_TYPE_ACCT)) {
-                       return 0;
-               }
-       }
-
-       if (secret) DEBUG2("\tsecret = %s", secret);
-
-       return 1;
-
-}
-
-
-static int add_pool_to_realm(const char *filename, int lineno,
-                            const char *name, home_pool_t **dest,
-                            int server_type)
-{
-       home_pool_t mypool, *pool;
-
-       mypool.name = name;
-       mypool.server_type = server_type;
-
-       pool = rbtree_finddata(home_pools_byname, &mypool);
-       if (!pool) {
-               CONF_SECTION *pool_cs;
-
-               pool_cs = cf_section_sub_find_name2(NULL, "server_pool",
-                                                   name);
-               if (!pool_cs) {
-                       radlog(L_ERR, "%s[%d]: Failed to find server_pool \"%s\"",
-                              filename, lineno, name);
-                       return 0;
-               }
-
-               if (!server_pool_add(filename, pool_cs, server_type)) {
-                       return 0;
-               }
-
-               pool = rbtree_finddata(home_pools_byname, &mypool);
-               if (!pool) {
-                       radlog(L_ERR, "Internal sanity check failed in add_pool_to_realm");
-                       return 0;
-               }
-       }
-
-       if (pool->server_type != server_type) {
-               radlog(L_ERR, "%s[%d]: Incompatible server_pool \"%s\" (mixed auth_pool / acct_pool)",
-                      filename, lineno, name);
-               return 0;
-       }
-
-       *dest = pool;
-
-       return 1;
-}
-
-int realm_add(const char *filename, CONF_SECTION *cs)
-{
-       const char *name2;
-       REALM *r = NULL;
-       CONF_PAIR *cp;
-       home_pool_t *auth_pool, *acct_pool;
-       const char *auth_pool_name, *acct_pool_name;
-
-       name2 = cf_section_name1(cs);
-       if (!name2 || (strcasecmp(name2, "realm") != 0)) {
-               radlog(L_ERR, "%s[%d]: Section is not a realm.",
-                      filename, cf_section_lineno(cs));
-               return 0;
-       }
-
-       name2 = cf_section_name2(cs);
-       if (!name2) {
-               radlog(L_ERR, "%s[%d]: Realm section is missing the realm name.",
-                      filename, cf_section_lineno(cs));
-               return 0;
-       }
-
-       auth_pool = acct_pool = NULL;
-       auth_pool_name = acct_pool_name = NULL;
-
-       /*
-        *      Prefer new configuration to old one.
-        */
-       cp = cf_pair_find(cs, "pool");
-       if (cp) auth_pool_name = cf_pair_value(cp);
-       if (cp && auth_pool_name) {
-               acct_pool_name = auth_pool_name;
-               if (!add_pool_to_realm(filename, cf_pair_lineno(cp),
-                                      auth_pool_name, &auth_pool,
-                                      HOME_TYPE_AUTH)) {
-                       return 0;
-               }
-               if (!add_pool_to_realm(filename, cf_pair_lineno(cp),
-                                      auth_pool_name, &acct_pool,
-                                      HOME_TYPE_ACCT)) {
-                       return 0;
-               }
-       }
-
-       cp = cf_pair_find(cs, "auth_pool");
-       if (cp) auth_pool_name = cf_pair_value(cp);
-       if (cp && auth_pool_name) {
-               if (auth_pool) {
-                       radlog(L_ERR, "%s[%d]: Cannot use \"pool\" and \"auth_pool\" at the same time.",
-                              filename, cf_section_lineno(cs));
-                       return 0;
-               }
-               if (!add_pool_to_realm(filename, cf_pair_lineno(cp),
-                                      auth_pool_name, &auth_pool,
-                                      HOME_TYPE_AUTH)) {
-                       return 0;
-               }
-       }
-
-       cp = cf_pair_find(cs, "acct_pool");
-       if (cp) acct_pool_name = cf_pair_value(cp);
-       if (cp && acct_pool_name) {
-               if (acct_pool) {
-                       radlog(L_ERR, "%s[%d]: Cannot use \"pool\" and \"acct_pool\" at the same time.",
-                              filename, cf_section_lineno(cs));
-                       return 0;
-               }
-               if (!add_pool_to_realm(filename, cf_pair_lineno(cp),
-                                      acct_pool_name, &acct_pool,
-                                      HOME_TYPE_ACCT)) {
-                       return 0;
-               }
-       }
-
-       DEBUG2(" realm %s {", name2);
-
-       /*
-        *      The realm MAY already exist if it's an old-style realm.
-        *      In that case, merge the old-style realm with this one.
-        */
-       r = realm_find(name2);
-       if (r) {
-               if (cf_pair_find(cs, "auth_pool") ||
-                   cf_pair_find(cs, "acct_pool")) {
-                       radlog(L_ERR, "%s[%d]: Duplicate realm \"%s\"",
-                              filename, cf_section_lineno(cs), name2);
-                       goto error;
-               }
-
-               if (!old_realm_config(filename, cs, r)) {
-                       goto error;
-               }
-
-               DEBUG2(" } # realm %s", name2);
-               return 1;
-       }
-
-       r = rad_malloc(sizeof(*r));
-       memset(r, 0, sizeof(*r));
-
-       r->name = name2;
-       r->auth_pool = auth_pool;
-       r->acct_pool = acct_pool;
-       r->striprealm = 1;
-
-       if (auth_pool_name == acct_pool_name) { /* yes, ptr comparison */
-               DEBUG2("\tpool = %s", auth_pool_name);
-       } else {
-               if (auth_pool_name) DEBUG2("\tauth_pool = %s", auth_pool_name);
-               if (acct_pool_name) DEBUG2("\tacct_pool = %s", acct_pool_name);
-       }
-
-       if ((cf_section_value_find(cs, "nostrip")) != NULL) {
-               r->striprealm = 0;
-               DEBUG2("\tnostrip", name2);
-       }
-
-       /*
-        *      We're a new-style realm.  Complain if we see the old
-        *      directives.
-        */
-       if (r->auth_pool || r->acct_pool) {
-               if (((cp = cf_pair_find(cs, "authhost")) != NULL) ||
-                   ((cp = cf_pair_find(cs, "accthost")) != NULL) ||
-                   ((cp = cf_pair_find(cs, "secret")) != NULL) ||
-                   ((cp = cf_pair_find(cs, "ldflag")) != NULL)) {
-                       DEBUG2("WARNING: Ignoring old-style configuration entry \"%s\" in realm \"%s\"", cf_pair_attr(cp), r->name);
-               }
-
-
-               /*
-                *      The realm MAY be an old-style realm, as there
-                *      was no auth_pool or acct_pool.  Double-check
-                *      it, just to be safe.
-                */
-       } else if (!old_realm_config(filename, cs, r)) {
-               goto error;
-       }
-
-       if (!rbtree_insert(realms_byname, r)) {
-               rad_assert("Internal sanity check failed");
-               goto error;
-       }
-
-       DEBUG2(" }");
-
-       return 1;
-
- error:
-       DEBUG2(" } # realm %s", name2);
-       free(r);
-       return 0;
-}
-
-
-/*
- *     Find a realm in the REALM list.
- */
-REALM *realm_find(const char *name)
-{
-       REALM myrealm;
-
-       if (!name) name = "NULL";
-
-       myrealm.name = name;
-       return rbtree_finddata(realms_byname, &myrealm);
-}
-
-
-home_server *home_server_ldb(const char *realmname,
-                            home_pool_t *pool, REQUEST *request)
-{
-       int             start;
-       int             count;
-       home_server     *found = NULL;
-
-       start = 0;
-
-       /*
-        *      Determine how to pick choose the home server.
-        */
-       switch (pool->type) {
-               uint32_t hash;
-
-               /*
-                *      For load-balancing by client IP address, we
-                *      pick a home server by hashing the client IP.
-                *
-                *      This isn't as even a load distribution as
-                *      tracking the State attribute, but it's better
-                *      than nothing.
-                */
-       case HOME_POOL_CLIENT_BALANCE:
-               switch (request->packet->src_ipaddr.af) {
-               case AF_INET:
-                       hash = lrad_hash(&request->packet->src_ipaddr.ipaddr.ip4addr,
-                                        sizeof(request->packet->src_ipaddr.ipaddr.ip4addr));
-                       break;
-               case AF_INET6:
-                       hash = lrad_hash(&request->packet->src_ipaddr.ipaddr.ip6addr,
-                                        sizeof(request->packet->src_ipaddr.ipaddr.ip6addr));
-                       break;
-               default:
-                       hash = 0;
-                       break;
-               }
-               start = hash % pool->num_home_servers;
-               break;
-
-       case HOME_POOL_CLIENT_PORT_BALANCE:
-               switch (request->packet->src_ipaddr.af) {
-               case AF_INET:
-                       hash = lrad_hash(&request->packet->src_ipaddr.ipaddr.ip4addr,
-                                        sizeof(request->packet->src_ipaddr.ipaddr.ip4addr));
-                       break;
-               case AF_INET6:
-                       hash = lrad_hash(&request->packet->src_ipaddr.ipaddr.ip6addr,
-                                        sizeof(request->packet->src_ipaddr.ipaddr.ip6addr));
-                       break;
-               default:
-                       hash = 0;
-                       break;
-               }
-               lrad_hash_update(&request->packet->src_port,
-                                sizeof(request->packet->src_port), hash);
-               start = hash % pool->num_home_servers;
-               break;
-
-       case HOME_POOL_LOAD_BALANCE:
-               found = pool->servers[0];
-
-       default:
-               start = 0;
-               break;
-       }
-
-       /*
-        *      Starting with the home server we chose, loop through
-        *      all home servers.  If the current one is dead, skip
-        *      it.  If it is too busy, skip it.
-        *
-        *      Otherwise, use it.
-        */
-       for (count = 0; count < pool->num_home_servers; count++) {
-               home_server *home = pool->servers[(start + count) % pool->num_home_servers];
-
-               if (home->state == HOME_STATE_IS_DEAD) {
-                       continue;
-               }
-
-               /*
-                *      This home server is too busy.  Choose another one.
-                */
-               if (home->currently_outstanding >= home->max_outstanding) {
-                       continue;
-               }
-
-               if (pool->type != HOME_POOL_LOAD_BALANCE) {
-                       return home;
-               }
-
-               DEBUG3("PROXY %s %d\t%s %d",
-                      found->name, found->currently_outstanding,
-                      home->name, home->currently_outstanding);
-
-               /*
-                *      Prefer this server if it's less busy than the
-                *      one we previously found.
-                */
-               if (home->currently_outstanding < found->currently_outstanding) {
-                       DEBUG3("Choosing %s: It's less busy than %s",
-                              home->name, found->name);
-                       found = home;
-                       continue;
-               }
-
-               /*
-                *      Ignore servers which are busier than the one
-                *      we found.
-                */
-               if (home->currently_outstanding > found->currently_outstanding) {
-                       DEBUG3("Skipping %s: It's busier than %s",
-                              home->name, found->name);
-                       continue;
-               }
-
-               /*
-                *      From the list of servers which have the same
-                *      load, choose one at random.
-                */
-               if (((count + 1) * (lrad_rand() & 0xffff)) < (uint32_t) 0x10000) {
-                       found = home;
-               }
-
-       } /* loop over the home servers */
-
-       if (found) return found;
-
-       /*
-        *      No live match found, and no fallback to the "DEFAULT"
-        *      realm.  We fix this by blindly marking all servers as
-        *      "live".  But only do it for ones that don't support
-        *      "pings", as they will be marked live when they
-        *      actually are live.
-        */
-       if (!mainconfig.proxy_fallback &&
-           mainconfig.wake_all_if_all_dead) {
-               home_server *lb = NULL;
-
-               for (count = 0; count < pool->num_home_servers; count++) {
-                       home_server *home = pool->servers[count];
-
-                       if ((home->state == HOME_STATE_IS_DEAD) &&
-                           (home->ping_check == HOME_PING_CHECK_NONE)) {
-                               home->state = HOME_STATE_ALIVE;
-                               if (!lb) lb = home;
-                       }
-               }
-
-               if (lb) return lb;
-       }
-
-       /*
-        *      Still nothing.  Look up the DEFAULT realm, but only
-        *      if we weren't looking up the NULL or DEFAULT realms.
-        */
-       if (mainconfig.proxy_fallback &&
-           realmname &&
-           (strcmp(realmname, "NULL") != 0) &&
-           (strcmp(realmname, "DEFAULT") != 0)) {
-               REALM *rd = realm_find("DEFAULT");
-
-               if (!rd) return NULL;
-
-               pool = NULL;
-               if (request->packet->code == PW_AUTHENTICATION_REQUEST) {
-                       pool = rd->auth_pool;
-
-               } else if (request->packet->code == PW_ACCOUNTING_REQUEST) {
-                       pool = rd->acct_pool;
-               }
-               if (!pool) return NULL;
-
-               DEBUG2("  Realm %s has no live home servers.  Falling back to the DEFAULT realm.", realmname);
-               return home_server_ldb(rd->name, pool, request);
-       }
-
-       /*
-        *      Still haven't found anything.  Oh well.
-        */
-       return NULL;
-}
-
-
-home_server *home_server_find(lrad_ipaddr_t *ipaddr, int port)
-{
-       home_server myhome;
-
-       myhome.ipaddr = *ipaddr;
-       myhome.port = port;
-
-       return rbtree_finddata(home_servers_byaddr, &myhome);
-}
diff --git a/src/main/request_list.c b/src/main/request_list.c
new file mode 100644 (file)
index 0000000..0a1ca48
--- /dev/null
@@ -0,0 +1,1493 @@
+/*
+ * request_list.c      Hide the handling of the REQUEST list from
+ *                     the main server.
+ *
+ * Version:    $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2003-2004  The FreeRADIUS server project
+ */
+static const char rcsid[] = "$Id$";
+
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "request_list.h"
+#include "radius_snmp.h"
+
+
+/*
+ *     We keep the incoming requests in an array, indexed by ID.
+ *
+ *     Each array element contains a linked list of containers of
+ *     active requests, a count of the number of requests, and a time
+ *     at which the first request in the list must be serviced.
+ *
+ *     Note that we ALSO keep a tree view of the same data, below.
+ *     Both views are needed for the server to work optimally.
+ */
+typedef struct REQNODE {
+       struct REQNODE *prev, *next;
+       REQUEST *req;
+} REQNODE;
+
+typedef struct REQUESTINFO {
+       REQNODE *first_request;
+       REQNODE *last_request;
+       int request_count;
+       time_t last_cleaned_list;
+} REQUESTINFO;
+
+static REQUESTINFO     request_list[256];
+
+/*
+ *     Remember the next request at which we start walking
+ *     the list.
+ */
+static REQUEST *last_request = NULL;
+
+/*
+ *     It MAY make more sense here to key off of the packet ID, just
+ *     like the request_list.  Then again, saving another 8 lookups
+ *     (on average) isn't much of a problem.
+ *
+ *     The "request_cmp" function keys off of the packet ID first,
+ *     so the first 8 layers of the tree will be the fanned-out
+ *     tree for packet ID's.
+ */
+static rbtree_t                *request_tree;
+
+#ifdef HAVE_PTHREAD_H
+static pthread_mutex_t proxy_mutex;
+#else
+/*
+ *     This is easier than ifdef's throughout the code.
+ */
+#define pthread_mutex_lock(_x)
+#define pthread_mutex_unlock(_x)
+#endif
+
+/*
+ *     We keep track of packets we're proxying, keyed by
+ *     source socket, and destination ip/port, and Id.
+ */
+static rbtree_t                *proxy_tree;
+
+/*
+ *     We keep track of free/used Id's, by destination ip/port.
+ *
+ *     We need a different tree than above, because this one is NOT
+ *     keyed by Id.  Instead, we use this one to allocate Id's.
+ */
+static rbtree_t                *proxy_id_tree;
+
+/*
+ *     We keep the proxy FD's here.  The RADIUS Id's are marked
+ *     "allocated" per Id, via a bit per proxy FD.
+ */
+static int             proxy_fds[32];
+
+static uint32_t                proxy_ipaddr;
+
+/*
+ *     We can use 256 RADIUS Id's per dst ipaddr/port, per server
+ *     socket.  So, to allocate them, we key off of dst ipaddr/port,
+ *     and then search the RADIUS Id's, looking for an unused socket.
+ *
+ *     We do NOT key off of socket fd's, here, either.  Instead,
+ *     we look for a free Id from a sockfd, any sockfd.
+ */
+typedef struct proxy_id_t {
+       uint32_t        dst_ipaddr;
+       int             dst_port;
+
+       /*
+        *      FIXME: Allocate more proxy sockets when this gets full.
+        */
+       int             index;
+       uint32_t        mask;   /* of FD's we know about. */
+       uint32_t        id[1];  /* really id[256] */
+} proxy_id_t;
+
+
+/*
+ *     Find a matching entry in the proxy ID tree.
+ */
+static int proxy_id_cmp(const void *one, const void *two)
+{
+       const proxy_id_t *a = one;
+       const proxy_id_t *b = two;
+
+       /*
+        *      The following comparisons look weird, but it's
+        *      the only way to make the comparisons work.
+        */
+       if (a->dst_ipaddr < b->dst_ipaddr) return -1;
+       if (a->dst_ipaddr > b->dst_ipaddr) return +1;
+
+       if (a->dst_port < b->dst_port) return -1;
+       if (a->dst_port > b->dst_port) return +1;
+       
+       /*
+        *      Everything's equal.  Say so.
+        */
+       return 0;
+}
+
+
+/*
+ *     Compare two REQUEST data structures, based on a number
+ *     of criteria.
+ */
+static int request_cmp(const void *one, const void *two)
+{
+       const REQUEST *a = one;
+       const REQUEST *b = two;
+
+       /*
+        *      The following comparisons look weird, but it's
+        *      the only way to make the comparisons work.
+        */
+
+       /*
+        *      If the packets didn't arrive on the same socket,
+        *      they're not identical, no matter what their src/dst
+        *      ip/ports say.
+        */
+       if (a->packet->sockfd < b->packet->sockfd) return -1;
+       if (a->packet->sockfd > b->packet->sockfd) return +1;
+
+       if (a->packet->id < b->packet->id) return -1;
+       if (a->packet->id > b->packet->id) return +1;
+
+       if (a->packet->code < b->packet->code) return -1;
+       if (a->packet->code > b->packet->code) return +1;
+
+       if (a->packet->src_ipaddr < b->packet->src_ipaddr) return -1;
+       if (a->packet->src_ipaddr > b->packet->src_ipaddr) return +1;
+
+       if (a->packet->src_port < b->packet->src_port) return -1;
+       if (a->packet->src_port > b->packet->src_port) return +1;
+
+       /*
+        *      Hmm... we may be listening on IPADDR_ANY, in which case
+        *      the destination IP is important, too.
+        */
+       if (a->packet->dst_ipaddr < b->packet->dst_ipaddr) return -1;
+       if (a->packet->dst_ipaddr > b->packet->dst_ipaddr) return +1;
+
+       if (a->packet->dst_port < b->packet->dst_port) return -1;
+       if (a->packet->dst_port > b->packet->dst_port) return +1;
+
+       /*
+        *      Everything's equal.  Say so.
+        */
+       return 0;
+}
+
+/*
+ *     Compare two REQUEST data structures, based on a number
+ *     of criteria, for proxied packets.
+ */
+static int proxy_cmp(const void *one, const void *two)
+{
+       const REQUEST *a = one;
+       const REQUEST *b = two;
+
+       rad_assert(a->magic == REQUEST_MAGIC);
+       rad_assert(b->magic == REQUEST_MAGIC);
+
+       rad_assert(a->proxy != NULL);
+       rad_assert(b->proxy != NULL);
+
+       /*
+        *      The following code looks unreasonable, but it's
+        *      the only way to make the comparisons work.
+        */
+       if (a->proxy->sockfd < b->proxy->sockfd) return -1;
+       if (a->proxy->sockfd > b->proxy->sockfd) return +1;
+
+       if (a->proxy->id < b->proxy->id) return -1;
+       if (a->proxy->id > b->proxy->id) return +1;
+
+       /*
+        *      We've got to check packet codes, too.  But
+        *      this should be done later, by someone else...
+        */
+
+       if (a->proxy->dst_ipaddr < b->proxy->dst_ipaddr) return -1;
+       if (a->proxy->dst_ipaddr > b->proxy->dst_ipaddr) return +1;
+
+       if (a->proxy->dst_port < b->proxy->dst_port) return -1;
+       if (a->proxy->dst_port > b->proxy->dst_port) return +1;
+
+       /*
+        *      FIXME: Check the Proxy-State attribute, too.
+        *      This will help cut down on duplicates.
+        */
+
+       /*
+        *      Everything's equal.  Say so.
+        */
+       return 0;
+}
+
+
+void rl_free(void)
+{
+       int i;
+
+       for (i = 0; i < 256; i++) {
+               while (request_list[i].first_request) {
+                       rl_delete(request_list[i].first_request->req);
+               }
+       }
+
+       rbtree_free(request_tree);
+       rbtree_free(proxy_id_tree);
+       rbtree_free(proxy_tree);
+}
+
+
+/*
+ *     Initialize the request list.
+ */
+int rl_init(void)
+{
+       /*
+        *      Initialize the request_list[] array.
+        */
+       memset(request_list, 0, sizeof(request_list));
+
+       request_tree = rbtree_create(request_cmp, NULL, 0);
+       if (!request_tree) {
+               rad_assert("FAIL" == NULL);
+       }
+
+       /*
+        *      Create the tree for managing proxied requests and
+        *      responses.
+        */
+       proxy_tree = rbtree_create(proxy_cmp, NULL, 1);
+       if (!proxy_tree) {
+               rad_assert("FAIL" == NULL);
+       }
+
+       /*
+        *      Create the tree for allocating proxy ID's.
+        */
+       proxy_id_tree = rbtree_create(proxy_id_cmp, NULL, 0);
+       if (!proxy_id_tree) {
+               rad_assert("FAIL" == NULL);
+       }
+
+#ifdef HAVE_PTHREAD_H
+       /*
+        *      For now, always create the mutex.
+        *
+        *      Later, we can only create it if there are multiple threads.
+        */
+       if (pthread_mutex_init(&proxy_mutex, NULL) != 0) {
+               radlog(L_ERR, "FATAL: Failed to initialize proxy mutex: %s",
+                      strerror(errno));
+               exit(1);
+       }
+#endif
+
+       /*
+        *      The Id allocation table is done by bits, so we have
+        *      32 bits per Id.  These bits indicate which entry
+        *      in the proxy_fds array is used for that Id.
+        *
+        *      This design allows 256*32 = 8k requests to be
+        *      outstanding to a home server, before something goes
+        *      wrong.
+        */
+       {
+               int i;
+               rad_listen_t *listener;
+
+               /*
+                *      Mark the Fd's as unused.
+                */
+               for (i = 0; i < 32; i++) proxy_fds[i] = -1;
+
+               for (listener = mainconfig.listen;
+                    listener != NULL;
+                    listener = listener->next) {
+                       if (listener->type == RAD_LISTEN_PROXY) {
+                               proxy_ipaddr = listener->ipaddr;
+                               proxy_fds[listener->fd & 0x1f] = listener->fd;
+                               break;
+                       }
+               }
+       }
+
+       return 1;
+}
+
+
+/*
+ *     Delete a request from the proxy trees.
+ */
+static void rl_delete_proxy(REQUEST *request, rbnode_t *node)
+{
+       proxy_id_t      myid, *entry;
+
+       rad_assert(node != NULL);
+
+       rbtree_delete(proxy_tree, node);
+       
+       myid.dst_ipaddr = request->proxy->dst_ipaddr;
+       myid.dst_port = request->proxy->dst_port;
+
+       /*
+        *      Find the Id in the array of allocated Id's,
+        *      and delete it.
+        */
+       entry = rbtree_finddata(proxy_id_tree, &myid);
+       if (entry) {
+               int i;
+
+               DEBUG3(" proxy: de-allocating %08x:%d %d",
+                      entry->dst_ipaddr,
+                      entry->dst_port,
+                      request->proxy->id);
+
+               /*
+                *      Find the proxy socket associated with this
+                *      Id.  We loop over all 32 proxy fd's, but we
+                *      partially index by proxy fd's, which means
+                *      that we almost always break out of the loop
+                *      quickly.
+                */
+               for (i = 0; i < 32; i++) {
+                       int offset;
+
+                       offset = (request->proxy->sockfd + i) & 0x1f;
+                 
+                       if (proxy_fds[offset] == request->proxy->sockfd) {
+                               
+                               entry->id[request->proxy->id] &= ~(1 << offset);
+                               break;
+                       }
+               } /* else die horribly? */
+       } else {
+               /*
+                *      Hmm... not sure what to do here.
+                */
+               DEBUG3(" proxy: FAILED TO FIND %08x:%d %d",
+                      myid.dst_ipaddr,
+                      myid.dst_port,
+                      request->proxy->id);
+       }
+}
+
+
+/*
+ *     Delete a particular request.
+ */
+void rl_delete(REQUEST *request)
+{
+       int id;
+       REQNODE *prev, *next;
+
+       prev = ((REQNODE *) request->container)->prev;
+       next = ((REQNODE *) request->container)->next;
+
+       id = request->packet->id;
+
+       /*
+        *      Update the last request we touched.
+        *
+        *      This is so the periodic "walk & clean list"
+        *      function, below, doesn't walk over all requests
+        *      all of the time.  Rather, it tries to amortize
+        *      the cost...
+        */
+       if (last_request == request) {
+               last_request = rl_next(last_request);
+       }
+
+
+       if (prev == NULL) {
+               request_list[id].first_request = next;
+       } else {
+               prev->next = next;
+       }
+
+       if (next == NULL) {
+               request_list[id].last_request = prev;
+       } else {
+               next->prev = prev;
+       }
+
+       free(request->container);
+
+#ifdef WITH_SNMP
+       /*
+        *      Update the SNMP statistics.
+        *
+        *      Note that we do NOT do this in rad_respond(),
+        *      as that function is called from child threads.
+        *      Instead, we update the stats when a request is
+        *      deleted, because only the main server thread calls
+        *      this function...
+        */
+       if (mainconfig.do_snmp) {
+               switch (request->reply->code) {
+               case PW_AUTHENTICATION_ACK:
+                 rad_snmp.auth.total_responses++;
+                 rad_snmp.auth.total_access_accepts++;
+                 break;
+
+               case PW_AUTHENTICATION_REJECT:
+                 rad_snmp.auth.total_responses++;
+                 rad_snmp.auth.total_access_rejects++;
+                 break;
+
+               case PW_ACCESS_CHALLENGE:
+                 rad_snmp.auth.total_responses++;
+                 rad_snmp.auth.total_access_challenges++;
+                 break;
+
+               case PW_ACCOUNTING_RESPONSE:
+                 rad_snmp.acct.total_responses++;
+                 break;
+
+               default:
+                       break;
+               }
+       }
+#endif
+
+       /*
+        *      Delete the request from the tree.
+        */
+       {
+               rbnode_t *node;
+
+               node = rbtree_find(request_tree, request);
+               rad_assert(node != NULL);
+               rbtree_delete(request_tree, node);
+
+
+               /*
+                *      If there's a proxied packet, and we're still
+                *      waiting for a reply, then delete the packet
+                *      from the list of outstanding proxied requests.
+                */
+               if (request->proxy &&
+                   (request->proxy_outstanding > 0)) {
+                       pthread_mutex_lock(&proxy_mutex);
+                       node = rbtree_find(proxy_tree, request);
+                       rl_delete_proxy(request, node);
+                       pthread_mutex_unlock(&proxy_mutex);
+               }
+       }
+
+       request_free(&request);
+       request_list[id].request_count--;
+}
+
+/*
+ *     Add a request to the request list.
+ */
+void rl_add(REQUEST *request)
+{
+       int id = request->packet->id;
+       REQNODE *node;
+
+       rad_assert(request->container == NULL);
+
+       request->container = rad_malloc(sizeof(REQNODE));
+       node = (REQNODE *) request->container;
+       node->req = request;
+
+       node->prev = NULL;
+       node->next = NULL;
+
+       if (!request_list[id].first_request) {
+               rad_assert(request_list[id].request_count == 0);
+
+               request_list[id].first_request = node;
+               request_list[id].last_request = node;
+       } else {
+               rad_assert(request_list[id].request_count != 0);
+
+               node->prev = request_list[id].last_request;
+               request_list[id].last_request->next = node;
+               request_list[id].last_request = node;
+       }
+
+       /*
+        *      Insert the request into the tree.
+        */
+       if (rbtree_insert(request_tree, request) == 0) {
+               rad_assert("FAIL" == NULL);
+       }
+
+       request_list[id].request_count++;
+}
+
+/*
+ *     Look up a particular request, using:
+ *
+ *     Request ID, request code, source IP, source port,
+ *
+ *     Note that we do NOT use the request vector to look up requests.
+ *
+ *     We MUST NOT have two requests with identical (id/code/IP/port), and
+ *     different vectors.  This is a serious error!
+ */
+REQUEST *rl_find(RADIUS_PACKET *packet)
+{
+       REQUEST myrequest;
+
+       myrequest.packet = packet;
+
+       return rbtree_finddata(request_tree, &myrequest);
+}
+
+/*
+ *     See mainconfig.c
+ */
+extern int proxy_new_listener(void);
+
+/*
+ *     Add an entry to the proxy tree.
+ *
+ *     This is the ONLY function in this source file which may be called
+ *     from a child thread.  It therefore needs mutexes...
+ */
+int rl_add_proxy(REQUEST *request)
+{
+       int             i, found, proxy;
+       uint32_t        mask;
+       proxy_id_t      myid, *entry;
+
+       myid.dst_ipaddr = request->proxy->dst_ipaddr;
+       myid.dst_port = request->proxy->dst_port;
+
+       /*
+        *      Proxied requests get sent out the proxy FD ONLY.
+        *
+        *      FIXME: Once we allocate multiple proxy FD's, move this
+        *      code to below, so we can have more than 256 requests
+        *      outstanding.
+        */
+       request->proxy_outstanding = 1;
+
+       pthread_mutex_lock(&proxy_mutex);
+
+       /*
+        *      Assign a proxy ID.
+        */
+       entry = rbtree_finddata(proxy_id_tree, &myid);
+       if (!entry) {   /* allocate it */
+               entry = rad_malloc(sizeof(*entry) + sizeof(entry->id) * 255);
+               
+               entry->dst_ipaddr = request->proxy->dst_ipaddr;
+               entry->dst_port = request->proxy->dst_port;
+               entry->index = 0;
+
+               DEBUG3(" proxy: creating %08x:%d",
+                      entry->dst_ipaddr,
+                      entry->dst_port);
+               
+               /*
+                *      Insert the new home server entry into
+                *      the tree.
+                *
+                *      FIXME: We don't (currently) delete the
+                *      entries, so this is technically a
+                *      memory leak.
+                */
+               if (rbtree_insert(proxy_id_tree, entry) == 0) {
+                       DEBUG2("ERROR: Failed to insert entry into proxy Id tree");
+                       free(entry);
+                       return 0;
+               }
+
+               /*
+                *      Clear out bits in the array which DO have
+                *      proxy Fd's associated with them.  We do this
+                *      by getting the mask of bits which have proxy
+                *      fd's...  */
+               mask = 0;
+               for (i = 0; i < 32; i++) {
+                       if (proxy_fds[i] != -1) {
+                               mask |= (1 << i);
+                       }
+               }
+               rad_assert(mask != 0);
+
+               /*
+                *      Set bits here indicate that the Fd is in use.
+                */
+               entry->mask = mask;
+
+               mask = ~mask;
+
+               /*
+                *      Set the bits which are unused (and therefore
+                *      allocated).  The clear bits indicate that the Id
+                *      for that FD is unused.
+                */
+               for (i = 0; i < 256; i++) {
+                       entry->id[i] = mask;
+               }
+       } /* else the entry already existed in the proxy Id tree */
+       
+ retry:
+       /*
+        *      Try to find a free Id.
+        */
+       found = -1;
+       for (i = 0; i < 256; i++) {
+               /*
+                *      Some bits are still zero..
+                */
+               if (entry->id[(i + entry->index) & 0xff] != (uint32_t) ~0) {
+                       found = (i + entry->index) & 0xff;
+                       break;
+               }
+
+               /*
+                *      Hmm... do we want to re-use Id's, when we
+                *      haven't seen all of the responses?
+                */
+       }
+       
+       /*
+        *      No free Id, try to get a new FD.
+        */
+       if (found < 0) {
+               /*
+                *      First, see if there were FD's recently allocated,
+                *      which we don't know about.
+                */
+               mask = 0;
+               for (i = 0; i < 32; i++) {
+                       if (proxy_fds[i] < 0) continue;
+
+                       mask |= (1 << i);
+               }
+
+               /*
+                *      There ARE more FD's than we know about.
+                *      Update the masks for Id's, and re-try.
+                */
+               if (entry->mask != mask) {
+                       /*
+                        *      New mask always has more bits than
+                        *      the old one, but never fewer bits.
+                        */
+                       rad_assert((entry->mask & mask) == entry->mask);
+
+                       /*
+                        *      Clear the bits we already know about,
+                        *      and then or in those bits into the
+                        *      global mask.
+                        */
+                       mask ^= entry->mask;
+                       entry->mask |= mask;
+                       mask = ~mask;
+                       
+                       /*
+                        *      Clear the bits in the Id's for the new
+                        *      FD's.
+                        */
+                       for (i = 0; i < 256; i++) {
+                               entry->id[i] &= mask;
+                       }
+                       
+                       /*
+                        *      And try again to allocate an Id.
+                        */
+                       goto retry;
+               } /* else no new Fd's were allocated. */
+
+               /*
+                *      If all Fd's are allocated, die.
+                */
+               if (~mask == 0) {
+                       radlog(L_ERR|L_CONS, "ERROR: More than 8000 proxied requests outstanding for home server %08x:%d",
+                              ntohs(entry->dst_ipaddr), entry->dst_port);
+                       return 0;
+               }
+               
+               /*
+                *      Allocate a new proxy Fd.  This function adds it
+                *      into the list of listeners.
+                */
+               proxy = proxy_new_listener();
+               if (proxy < 0) {
+                       DEBUG2("ERROR: Failed to create a new socket for proxying requests.");
+                       return 0;
+               }
+
+               /*
+                *
+                */
+               found = -1;
+               for (i = 0; i < 32; i++) {
+                       /*
+                        *      Found a free entry.  Save the socket,
+                        *      and remember where we saved it.
+                        */
+                       if (proxy_fds[(proxy + i) & 0x1f] == -1) {
+                               proxy_fds[(proxy + i) & 0x1f] = proxy;
+                               found = (proxy + i) & 0x1f;
+                               break;
+                       }
+               }
+               rad_assert(found >= 0); /* i.e. the mask had free bits. */
+
+               mask = 1 << found;
+               entry->mask |= mask;
+               mask = ~mask;
+
+               /*
+                *      Clear the relevant bits in the mask.
+                */
+               for (i = 0; i < 256; i++) {
+                       entry->id[i] &= mask;
+               }
+
+               /*
+                *      Pick a random Id to start from, as we've
+                *      just guaranteed that it's free.
+                */
+               found = lrad_rand() & 0xff;
+       }
+       
+       /*
+        *      Mark next (hopefully unused) entry.
+        */
+       entry->index = (found + 1) & 0xff;
+       
+       /*
+        *      We now have to find WHICH proxy fd to use.
+        */
+       proxy = -1;
+       for (i = 0; i < 32; i++) {
+               /*
+                *      FIXME: pick a random socket to use?
+                */
+               if ((entry->id[found] & (1 << i)) == 0) {
+                       proxy = i;
+                       break;
+               }
+       }
+
+       /*
+        *      There was no bit clear, which we had just checked above...
+        */
+       if (proxy < 0) {
+               pthread_mutex_unlock(&proxy_mutex);
+               return 0;
+       }
+
+       /*
+        *      Mark the Id as allocated, for thei Fd.
+        */
+       entry->id[found] |= (1 << proxy);
+       request->proxy->id = found;
+       request->proxy->src_ipaddr = proxy_ipaddr;
+
+       rad_assert(proxy_fds[proxy] != -1);
+       request->proxy->sockfd = proxy_fds[proxy];
+
+       DEBUG3(" proxy: allocating %08x:%d %d",
+              entry->dst_ipaddr,
+              entry->dst_port,
+              request->proxy->id);
+       
+       if (!rbtree_insert(proxy_tree, request)) {
+               DEBUG2("ERROR: Failed to insert entry into proxy tree");
+               return 0;
+       }
+       
+       pthread_mutex_unlock(&proxy_mutex);
+
+       return 1;
+}
+
+
+/*
+ *     Look up a particular request, using:
+ *
+ *     Request Id, request code, source IP, source port,
+ *
+ *     Note that we do NOT use the request vector to look up requests.
+ *
+ *     We MUST NOT have two requests with identical (id/code/IP/port), and
+ *     different vectors.  This is a serious error!
+ */
+REQUEST *rl_find_proxy(RADIUS_PACKET *packet)
+{
+       rbnode_t        *node;
+       REQUEST         myrequest, *maybe = NULL;
+       RADIUS_PACKET   myproxy;
+
+       /*
+        *      If we use the socket FD as an indicator,
+        *      then that implicitely contains information
+        *      as to our src ipaddr/port, so we don't need
+        *      to use that in the comparisons.
+        */
+       myproxy.sockfd = packet->sockfd;
+       myproxy.id = packet->id;
+       myproxy.dst_ipaddr = packet->src_ipaddr;
+       myproxy.dst_port = packet->src_port;
+
+#ifndef NDEBUG
+       myrequest.magic = REQUEST_MAGIC;
+#endif
+       myrequest.proxy = &myproxy;
+
+       pthread_mutex_lock(&proxy_mutex);
+        node = rbtree_find(proxy_tree, &myrequest);
+
+       if (node) {
+               maybe = rbtree_node2data(proxy_tree, node);
+               rad_assert(maybe->proxy_outstanding > 0);
+               maybe->proxy_outstanding--;
+               
+               /*
+                *      Received all of the replies we expect.
+                *      delete it from both trees.
+                */
+               if (maybe->proxy_outstanding == 0) {
+                       rl_delete_proxy(&myrequest, node);
+               }
+       }
+       pthread_mutex_unlock(&proxy_mutex);
+
+       return maybe;
+}
+
+
+/*
+ *     Walk over all requests, performing a callback for each request.
+ */
+int rl_walk(RL_WALK_FUNC walker, void *data)
+{
+       int id, rcode;
+       REQNODE *curreq, *next;
+
+       /*
+        *      Walk over all 256 ID's.
+        */
+       for (id = 0; id < 256; id++) {
+
+               /*
+                *      Walk over the request list for each ID.
+                */
+               for (curreq = request_list[id].first_request;
+                               curreq != NULL ;
+                               curreq = next) {
+                       /*
+                        *      The callback MIGHT delete the current
+                        *      request, so we CANNOT depend on curreq->next
+                        *      to be there, when going to the next element
+                        *      in the 'for' loop.
+                        */
+                       next = curreq->next;
+
+                       rcode = walker(curreq->req, data);
+                       if (rcode != RL_WALK_CONTINUE) {
+                               return rcode;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+
+/*
+ *     Walk from one request to the next.
+ */
+REQUEST *rl_next(REQUEST *request)
+{
+       int id, start_id;
+       int count;
+
+       /*
+        *      If we were passed a request, then go to the "next" one.
+        */
+       if (request != NULL) {
+               rad_assert(request->magic == REQUEST_MAGIC);
+
+               /*
+                *      It has a "next", return it.
+                */
+               if (((REQNODE *)request->container)->next != NULL) {
+                       return ((REQNODE *)request->container)->next->req;
+               } else {
+                       /*
+                        *      No "next", increment the ID, and look
+                        *      at that one.
+                        */
+                       start_id = request->packet->id + 1;
+                       start_id &= 0xff;
+                       count = 255;
+               }
+       } else {
+               /*
+                *      No input request, start looking at ID 0.
+                */
+               start_id = 0;
+               count = 256;
+       }
+
+       /*
+        *      Check all ID's, wrapping around at 255.
+        */
+       for (id = start_id; id < (start_id + count); id++) {
+
+               /*
+                *      This ID has a request, return it.
+                */
+               if (request_list[id & 0xff].first_request != NULL) {
+                       rad_assert(request_list[id&0xff].first_request->req != request);
+
+                       return request_list[id & 0xff].first_request->req;
+               }
+       }
+
+       /*
+        *      No requests at all in the list. Nothing to do.
+        */
+       DEBUG3("rl_next:  returning NULL");
+       return NULL;
+}
+
+
+/*
+ *     Return the number of requests in the request list.
+ */
+int rl_num_requests(void)
+{
+       int id;
+       int request_count = 0;
+
+       for (id = 0; id < 256; id++) {
+               request_count += request_list[id].request_count;
+       }
+
+       return request_count;
+}
+
+
+typedef struct rl_walk_t {
+       time_t  now;
+       time_t  smallest;
+} rl_walk_t;
+
+
+/*
+ *  Refresh a request, by using proxy_retry_delay, cleanup_delay,
+ *  max_request_time, etc.
+ *
+ *  When walking over the request list, all of the per-request
+ *  magic is done here.
+ */
+static int refresh_request(REQUEST *request, void *data)
+{
+       rl_walk_t *info = (rl_walk_t *) data;
+       time_t difference;
+       child_pid_t child_pid;
+
+       rad_assert(request->magic == REQUEST_MAGIC);
+
+       /*
+        *  If the request is marked as a delayed reject, AND it's
+        *  time to send the reject, then do so now.
+        */
+       if (request->finished &&
+           ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) != 0)) {
+               rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
+
+               difference = info->now - request->timestamp;
+               if (difference >= (time_t) mainconfig.reject_delay) {
+
+                       /*
+                        *  Clear the 'delayed reject' bit, so that we
+                        *  don't do this again.
+                        */
+                       request->options &= ~RAD_REQUEST_OPTION_DELAYED_REJECT;
+                       rad_send(request->reply, request->packet,
+                                request->secret);
+               }
+       }
+
+       /*
+        *  If the request has finished processing, AND it's child has
+        *  been cleaned up, AND it's time to clean up the request,
+        *  OR, it's an accounting request.  THEN, go delete it.
+        *
+        *  If this is a request which had the "don't cache" option
+        *  set, then delete it immediately, as it CANNOT have a
+        *  duplicate.
+        */
+       if (request->finished &&
+           ((request->timestamp + mainconfig.cleanup_delay <= info->now) ||
+            ((request->options & RAD_REQUEST_OPTION_DONT_CACHE) != 0))) {
+               rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
+
+               /*
+                *  Request completed, delete it, and unlink it
+                *  from the currently 'alive' list of requests.
+                */
+               DEBUG2("Cleaning up request %d ID %d with timestamp %08lx",
+                               request->number, request->packet->id,
+                               (unsigned long) request->timestamp);
+
+               /*
+                *  Delete the request.
+                */
+               rl_delete(request);
+               return RL_WALK_CONTINUE;
+       }
+
+       /*
+        *  Maybe the child process handling the request has hung:
+        *  kill it, and continue.
+        */
+       if ((request->timestamp + mainconfig.max_request_time) <= info->now) {
+               int number;
+
+               child_pid = request->child_pid;
+               number = request->number;
+
+               /*
+                *      There MUST be a RAD_PACKET reply.
+                */
+               rad_assert(request->reply != NULL);
+
+               /*
+                *      If we've tried to proxy the request, and
+                *      the proxy server hasn't responded, then
+                *      we send a REJECT back to the caller.
+                *
+                *      For safety, we assert that there is no child
+                *      handling the request.  If the assertion fails,
+                *      it means that we've sent a proxied request to
+                *      the home server, and the child thread is still
+                *      sitting on the request!
+                */
+               if (request->proxy && !request->proxy_reply) {
+                       rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
+
+                       radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s:%d",
+                              request->number,
+                              client_name(request->packet->src_ipaddr),
+                              request->packet->src_port);
+                       request_reject(request);
+                       request->finished = TRUE;
+                       return RL_WALK_CONTINUE;
+               }
+
+               if (mainconfig.kill_unresponsive_children) {
+                       if (child_pid != NO_SUCH_CHILD_PID) {
+                               /*
+                                *  This request seems to have hung
+                                *   - kill it
+                                */
+#ifdef HAVE_PTHREAD_H
+                               radlog(L_ERR, "Killing unresponsive thread for request %d",
+                                      request->number);
+                               pthread_cancel(child_pid);
+#endif
+                       } /* else no proxy reply, quietly fail */
+
+                       /*
+                        *      Maybe we haven't killed it.  In that
+                        *      case, print a warning.
+                        */
+               } else if ((child_pid != NO_SUCH_CHILD_PID) &&
+                          ((request->options & RAD_REQUEST_OPTION_LOGGED_CHILD) == 0)) {
+                       radlog(L_ERR, "WARNING: Unresponsive child (id %lu) for request %d",
+                              (unsigned long)child_pid, number);
+
+                       /*
+                        *  Set the option that we've sent a log message,
+                        *  so that we don't send more than one message
+                        *  per request.
+                        */
+                       request->options |= RAD_REQUEST_OPTION_LOGGED_CHILD;
+               }
+
+               /*
+                *  Send a reject message for the request, mark it
+                *  finished, and forget about the child.
+                */
+               request_reject(request);
+               request->child_pid = NO_SUCH_CHILD_PID;
+               if (mainconfig.kill_unresponsive_children)
+                       request->finished = TRUE;
+               return RL_WALK_CONTINUE;
+       } /* the request has been in the queue for too long */
+
+       /*
+        *  If the request is still being processed, then due to the
+        *  above check, it's still within it's time limit.  In that
+        *  case, don't do anything.
+        */
+       if (request->child_pid != NO_SUCH_CHILD_PID) {
+               return RL_WALK_CONTINUE;
+       }
+
+       /*
+        *  The request is finished.
+        */
+       if (request->finished) goto setup_timeout;
+
+       /*
+        *  We're not proxying requests at all.
+        */
+       if (!mainconfig.proxy_requests) goto setup_timeout;
+
+       /*
+        *  We're proxying synchronously, so we don't retry it here.
+        *  Some other code takes care of retrying the proxy requests.
+        */
+       if (mainconfig.proxy_synchronous) goto setup_timeout;
+
+       /*
+        *  The proxy retry delay is zero, meaning don't retry.
+        */
+       if (mainconfig.proxy_retry_delay == 0) goto setup_timeout;
+
+       /*
+        *  There is no proxied request for this packet, so there's
+        *  no proxy retries.
+        */
+       if (!request->proxy) goto setup_timeout;
+
+       /*
+        *  We've already seen the proxy reply, so we don't need
+        *  to send another proxy request.
+        */
+       if (request->proxy_reply) goto setup_timeout;
+
+       /*
+        *  It's not yet time to re-send this proxied request.
+        */
+       if (request->proxy_next_try > info->now) goto setup_timeout;
+
+       /*
+        *  If the proxy retry count is zero, then
+        *  we've sent the last try, and have NOT received
+        *  a reply from the end server.  In that case,
+        *  we don't bother trying again, but just mark
+        *  the request as finished, and go to the next one.
+        */
+       if (request->proxy_try_count == 0) {
+               rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
+               request_reject(request);
+               realm_disable(request->proxy->dst_ipaddr,request->proxy->dst_port);
+               request->finished = TRUE;
+               goto setup_timeout;
+       }
+
+       /*
+        *  We're trying one more time, so count down
+        *  the tries, and set the next try time.
+        */
+       request->proxy_try_count--;
+       request->proxy_next_try = info->now + mainconfig.proxy_retry_delay;
+
+       /*
+        *      Don't restransmit accounting requests.
+        *      Only the originating NAS should do this.
+        */
+       if (request->proxy->code == PW_ACCOUNTING_REQUEST) {
+               goto setup_timeout;
+       }
+
+       /*
+        *  Assert that we have NOT seen the proxy reply yet.
+        *
+        *  If we HAVE seen it, then we SHOULD NOT be bugging the
+        *  home server!
+        */
+       rad_assert(request->proxy_reply == NULL);
+
+       /*
+        *  Send the proxy packet.
+        */
+       request->proxy_outstanding++;
+       rad_send(request->proxy, NULL, request->proxysecret);
+
+setup_timeout:
+       /*
+        *  Don't do more long-term checks, if we've got to wake
+        *  up now.
+        */
+       if (info->smallest == 0) {
+               return RL_WALK_CONTINUE;
+       }
+
+       /*
+        *  The request is finished.  Wake up when it's time to
+        *  clean it up.
+        */
+       if (request->finished) {
+               difference = (request->timestamp + mainconfig.cleanup_delay) - info->now;
+
+               /*
+                *  If the request is marked up to be rejected later,
+                *  then wake up later.
+                */
+               if ((request->options & RAD_REQUEST_OPTION_DELAYED_REJECT) != 0) {
+                       if (difference >= (time_t) mainconfig.reject_delay) {
+                               difference = (time_t) mainconfig.reject_delay;
+                       }
+               }
+
+       } else if (request->proxy && !request->proxy_reply) {
+               /*
+                *  The request is NOT finished, but there is an
+                *  outstanding proxy request, with no matching
+                *  proxy reply.
+                *
+                *  Wake up when it's time to re-send
+                *  the proxy request.
+                *
+                *  But in synchronous proxy, we don't retry but we update
+                *  the next retry time as NAS has not resent the request
+                *  in the given retry window.
+                */
+               if (mainconfig.proxy_synchronous) {
+                       /*
+                        *      If the retry_delay * count has passed,
+                        *      then mark the realm dead.
+                        */
+                       if (info->now > (request->timestamp + (mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count))) {
+                               rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
+                               request_reject(request);
+                               
+                               realm_disable(request->proxy->dst_ipaddr,
+                                             request->proxy->dst_port);
+                               request->finished = TRUE;
+                               goto setup_timeout;
+                       }
+                       request->proxy_next_try = info->now + mainconfig.proxy_retry_delay;
+               }
+               difference = request->proxy_next_try - info->now;
+       } else {
+               /*
+                *  The request is NOT finished.
+                *
+                *  Wake up when it's time to kill the errant
+                *  thread/process.
+                */
+               difference = (request->timestamp + mainconfig.max_request_time) - info->now;
+       }
+
+       /*
+        *  If the server is CPU starved, then we CAN miss a time
+        *  for servicing requests.  In which case the 'difference'
+        *  value will be negative.  select() doesn't like that,
+        *  so we fix it.
+        */
+       if (difference < 0) {
+               difference = 0;
+       }
+
+       /*
+        *  Update the 'smallest' time.
+        */
+       if ((info->smallest < 0) ||
+               (difference < info->smallest)) {
+               info->smallest = difference;
+       }
+
+       return RL_WALK_CONTINUE;
+}
+
+
+/*
+ *  Clean up the request list, every so often.
+ *
+ *  This is done by walking through ALL of the list, and
+ *  - marking any requests which are finished, and expired
+ *  - killing any processes which are NOT finished after a delay
+ *  - deleting any marked requests.
+ */
+struct timeval *rl_clean_list(time_t now)
+{
+       /*
+        *  Static variables, so that we don't do all of this work
+        *  more than once per second.
+        *
+        *  Note that we have 'tv' and 'last_tv'.  'last_tv' is
+        *  pointed to by 'last_tv_ptr', and depending on the
+        *  system implementation of select(), it MAY be modified.
+        *
+        *  In that was, we want to use the ORIGINAL value, from
+        *  'tv', and wipe out the (possibly modified) last_tv.
+        */
+       static time_t last_cleaned_list = 0;
+       static struct timeval tv, *last_tv_ptr = NULL;
+       static struct timeval last_tv;
+
+       rl_walk_t info;
+
+       info.now = now;
+       info.smallest = -1;
+
+       /*
+        *  If we've already set up the timeout or cleaned the
+        *  request list this second, then don't do it again.  We
+        *  simply return the sleep delay from last time.
+        *
+        *  Note that if we returned NULL last time, there was nothing
+        *  to do.  BUT we've been woken up since then, which can only
+        *  happen if we received a packet.  And if we've received a
+        *  packet, then there's some work to do in the future.
+        *
+        *  FIXME: We can probably use gettimeofday() for finer clock
+        *  resolution, as the current method will cause it to sleep
+        *  too long...
+        */
+       if ((last_tv_ptr != NULL) &&
+           (last_cleaned_list == now) &&
+           (tv.tv_sec != 0)) {
+               int i;
+
+               /*
+                *  If we're NOT walking the entire request list,
+                *  then we want to iteratively check the request
+                *  list.
+                *
+                *  If there is NO previous request, go look for one.
+                */
+               if (!last_request)
+                       last_request = rl_next(last_request);
+
+               /*
+                *  On average, there will be one request per
+                *  'cleanup_delay' requests, which needs to be
+                *  serviced.
+                *
+                *  And only do this servicing, if we have a request
+                *  to service.
+                */
+               if (last_request)
+                       for (i = 0; i < mainconfig.cleanup_delay; i++) {
+                               REQUEST *next;
+
+                               /*
+                                *  This function call MAY delete the
+                                *  request pointed to by 'last_request'.
+                                */
+                               next = rl_next(last_request);
+                               refresh_request(last_request, &info);
+                               last_request = next;
+
+                               /*
+                                *  Nothing to do any more, exit.
+                                */
+                               if (!last_request)
+                                       break;
+                       }
+
+               last_tv = tv;
+               DEBUG2("Waking up in %d seconds...",
+                               (int) last_tv_ptr->tv_sec);
+               return last_tv_ptr;
+       }
+       last_cleaned_list = now;
+       last_request = NULL;
+       DEBUG2("--- Walking the entire request list ---");
+
+       /*
+        *  Hmmm... this is Big Magic.  We make it seem like
+        *  there's an additional second to wait, for a whole
+        *  host of reasons which I can't explain adequately,
+        *  but which cause the code to Just Work Right.
+        */
+       info.now--;
+
+       rl_walk(refresh_request, &info);
+
+       /*
+        *  We haven't found a time at which we need to wake up.
+        *  Return NULL, so that the select() call will sleep forever.
+        */
+       if (info.smallest < 0) {
+               /*
+                *  If we're not proxying, then there really isn't anything
+                *  to do.
+                *
+                *  If we ARE proxying, then we can safely sleep
+                *  forever if we're told to NEVER send proxy retries
+                *  ourselves, until the NAS kicks us again.
+                *
+                *  Otherwise, there are no outstanding requests, then
+                *  we can sleep forever.  This happens when we get
+                *  woken up with a bad packet.  It's discarded, so if
+                *  there are no live requests, we can safely sleep
+                *  forever.
+                */
+               if ((!mainconfig.proxy_requests) ||
+                   mainconfig.proxy_synchronous ||
+                   (rl_num_requests() == 0)) {
+                       DEBUG2("Nothing to do.  Sleeping until we see a request.");
+                       last_tv_ptr = NULL;
+                       return NULL;
+               }
+
+               /*
+                *  We ARE proxying.  In that case, we avoid a race condition
+                *  where a child thread handling a request proxies the
+                *  packet, and sets the retry delay.  In that case, we're
+                *  supposed to wake up in N seconds, but we can't, as
+                *  we're sleeping forever.
+                *
+                *  Instead, we prevent the problem by waking up anyhow
+                *  at the 'proxy_retry_delay' time, even if there's
+                *  nothing to do.  In the worst case, this will cause
+                *  the server to wake up every N seconds, to do a small
+                *  amount of unnecessary work.
+                */
+               info.smallest = mainconfig.proxy_retry_delay;
+       }
+       /*
+        *  Set the time (in seconds) for how long we're
+        *  supposed to sleep.
+        */
+       tv.tv_sec = info.smallest;
+       tv.tv_usec = 0;
+       DEBUG2("Waking up in %d seconds...", (int) info.smallest);
+
+       /*
+        *  Remember how long we should sleep for.
+        */
+       last_tv = tv;
+       last_tv_ptr = &last_tv;
+       return last_tv_ptr;
+}
index e2e4040..c7741a8 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       "autoconf.h"
 
-#ifdef HAVE_SYS_WAIT_H
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include       <unistd.h>
+#endif
+
+#include       <signal.h>
+#include       <errno.h>
 #include       <sys/wait.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include       <netinet/in.h>
 #endif
 
-/*
- *     End a session by faking a Stop packet to all accounting modules.
- */
+#include       "radiusd.h"
+#include       "rad_assert.h"
+#include       "modules.h"
+
+/* End a session by faking a Stop packet to all accounting modules */
 int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
                const char *user,
-               const char *sessionid, uint32_t cliaddr, char proto,
-               int session_time)
+               const char *sessionid, uint32_t cliaddr, char proto)
 {
        REQUEST *stopreq;
        VALUE_PAIR *vp, *userpair;
@@ -57,8 +67,8 @@ int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
                vp->e = v; \
                pairadd(&(stopreq->packet->vps), vp); \
        } while(0)
-#define INTPAIR(n,v) PAIR(n,v,PW_TYPE_INTEGER,vp_integer)
-#define IPPAIR(n,v) PAIR(n,v,PW_TYPE_IPADDR,vp_ipaddr)
+#define INTPAIR(n,v) PAIR(n,v,PW_TYPE_INTEGER,lvalue)
+#define IPPAIR(n,v) PAIR(n,v,PW_TYPE_IPADDR,lvalue)
 #define STRINGPAIR(n,v) do { \
        if(!(vp = paircreate(n, PW_TYPE_STRING))) { \
                request_free(&stopreq); \
@@ -66,7 +76,7 @@ int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
                pairfree(&(stopreq->packet->vps)); \
                return 0; \
        } \
-       strlcpy((char *)vp->vp_strvalue, v, sizeof vp->vp_strvalue); \
+       strNcpy((char *)vp->strvalue, v, sizeof vp->strvalue); \
        vp->length = strlen(v); \
        pairadd(&(stopreq->packet->vps), vp); \
        } while(0)
@@ -89,7 +99,7 @@ int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
        }
        if(cliaddr != 0)
                IPPAIR(PW_FRAMED_IP_ADDRESS, cliaddr);
-       INTPAIR(PW_ACCT_SESSION_TIME, session_time);
+       INTPAIR(PW_ACCT_SESSION_TIME, 0);
        INTPAIR(PW_ACCT_INPUT_OCTETS, 0);
        INTPAIR(PW_ACCT_OUTPUT_OCTETS, 0);
        INTPAIR(PW_ACCT_INPUT_PACKETS, 0);
@@ -111,11 +121,6 @@ int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
 
 /*
  *     Check one terminal server to see if a user is logged in.
- *
- *     Return values:
- *             0 The user is off-line.
- *             1 The user is logged in.
- *             2 Some error occured.
  */
 int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
                 const char *session_id)
@@ -126,15 +131,11 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
        char    address[16];
        char    port[11];
        RADCLIENT *cl;
-       lrad_ipaddr_t ipaddr;
-
-       ipaddr.af = AF_INET;
-       ipaddr.ipaddr.ip4addr.s_addr = nasaddr;
 
        /*
         *      Find NAS type.
         */
-       cl = client_find_old(&ipaddr);
+       cl = client_find(nasaddr);
        if (!cl) {
                /*
                 *  Unknown NAS, so trusting radutmp.
@@ -147,7 +148,7 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
        /*
         *  No nastype, or nas type 'other', trust radutmp.
         */
-       if (!cl->nastype || (cl->nastype[0] == '\0') ||
+       if ((cl->nastype[0] == '\0') ||
            (strcmp(cl->nastype, "other") == 0)) {
                DEBUG2("checkrad: No NAS type, or type \"other\" not checking");
                return 1;
@@ -158,7 +159,7 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
         */
        if ((pid = rad_fork()) < 0) { /* do wait for the fork'd result */
                radlog(L_ERR, "Accounting: Failed in fork(): Cannot run checkrad\n");
-               return 2;
+               return -1;
        }
 
        if (pid > 0) {
@@ -183,6 +184,8 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
                return WEXITSTATUS(status);
        }
 
+       closefrom(3);
+
        /*
         *  We don't close fd's 0, 1, and 2.  If we're in debugging mode,
         *  then they should go to stdout (etc), along with the other
@@ -191,7 +194,6 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
         *  If we're not in debugging mode, then the code in radiusd.c
         *  takes care of connecting fd's 0, 1, and 2 to /dev/null.
         */
-       closefrom(3);
 
        ip_ntoa(address, nasaddr);
        snprintf(port, 11, "%u", portnum);
@@ -212,5 +214,5 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
         *      Exit - 2 means "some error occured".
         */
        exit(2);
-       return 2;
+       return -1;
 }
index df8043e..78c4c1f 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 1999  Jochen Friedrich <jochen@scram.de>
  * Copyright 1999  Kunihiro Ishiguro <kunihiro@zebra.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] =
+"$Id$";
 
-#include <freeradius-devel/radiusd.h>
+#include "autoconf.h"
 
 #ifdef WITH_SNMP
 
-#include <freeradius-devel/radius_snmp.h>
-#include <freeradius-devel/smux.h>
+#include "libradius.h"
 
+#include <sys/socket.h>
 #include <sys/file.h>
 
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
 #include <fcntl.h>
 #include <ctype.h>
 
+#include "radiusd.h"
+#include "radius_snmp.h"
+#include "smux.h"
+
 #define min(A,B) ((A) < (B) ? (A) : (B))
 
 
@@ -138,7 +150,7 @@ smux_oid_dump(const char *prefix, oid *my_oid, size_t oid_len)
                        sprintf (buf + strlen (buf), "%s%d", first ? "" : ".", (int) my_oid[i]);
                        first = 0;
        }
-       DEBUG2 ("SMUX %s: %s", prefix, buf);
+       DEBUG2 ("%s: %s", prefix, buf);
 }
 
 static int
@@ -237,8 +249,8 @@ smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat,
        len = BUFSIZ;
        length = len;
 
-       DEBUG3("SMUX GETRSP send");
-       DEBUG3("SMUX GETRSP reqid: %ld", reqid);
+       DEBUG2("SMUX GETRSP send");
+       DEBUG2("SMUX GETRSP reqid: %ld", reqid);
 
        h1 = ptr;
        /* Place holder h1 for complete sequence */
@@ -249,12 +261,12 @@ smux_getresp_send (oid objid[], size_t objid_len, long reqid, long errstat,
                        (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                        &reqid, sizeof (reqid));
 
-       DEBUG3("SMUX GETRSP errstat: %ld", errstat);
+       DEBUG2("SMUX GETRSP errstat: %ld", errstat);
 
        ptr = asn_build_int (ptr, &len,
                        (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
                        &errstat, sizeof (errstat));
-       DEBUG3("SMUX GETRSP errindex: %ld", errindex);
+       DEBUG2("SMUX GETRSP errindex: %ld", errindex);
 
        ptr = asn_build_int (ptr, &len,
                        (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
@@ -292,13 +304,13 @@ smux_var (char *ptr, int len, oid objid[], size_t *objid_len,
        size_t val_len;
        u_char *val;
 
-       DEBUG3("SMUX var parse: len %d", len);
+       DEBUG2("SMUX var parse: len %d", len);
 
        /* Parse header. */
        ptr = asn_parse_header (ptr, &len, &type);
 
-       DEBUG3("SMUX var parse: type %d len %d", type, len);
-       DEBUG3("SMUX var parse: type must be %d", (ASN_SEQUENCE | ASN_CONSTRUCTOR));
+       DEBUG2("SMUX var parse: type %d len %d", type, len);
+       DEBUG2("SMUX var parse: type must be %d", (ASN_SEQUENCE | ASN_CONSTRUCTOR));
 
        /* Parse var option. */
        *objid_len = MAX_OID_LEN;
@@ -317,53 +329,53 @@ smux_var (char *ptr, int len, oid objid[], size_t *objid_len,
        /* Requested object id length is objid_len. */
        smux_oid_dump ("Request OID", objid, *objid_len);
 
-       DEBUG3 ("SMUX val_type: %d", val_type);
+       DEBUG2 ("SMUX val_type: %d", val_type);
 
        /* Check request value type. */
        switch (val_type) {
                case ASN_NULL:
                        /* In case of SMUX_GET or SMUX_GET_NEXT val_type is set to
                                 ASN_NULL. */
-                       DEBUG3 ("ASN_NULL");
+                       DEBUG2 ("ASN_NULL");
                        break;
 
                case ASN_INTEGER:
-                       DEBUG3 ("ASN_INTEGER");
+                       DEBUG2 ("ASN_INTEGER");
                        break;
                case ASN_COUNTER:
                case ASN_GAUGE:
                case ASN_TIMETICKS:
                case ASN_UINTEGER:
-                       DEBUG3 ("ASN_COUNTER");
+                       DEBUG2 ("ASN_COUNTER");
                        break;
                case ASN_COUNTER64:
-                       DEBUG3 ("ASN_COUNTER64");
+                       DEBUG2 ("ASN_COUNTER64");
                        break;
                case ASN_IPADDRESS:
-                       DEBUG3 ("ASN_IPADDRESS");
+                       DEBUG2 ("ASN_IPADDRESS");
                        break;
                case ASN_OCTET_STR:
-                       DEBUG3 ("ASN_OCTET_STR");
+                       DEBUG2 ("ASN_OCTET_STR");
                        break;
                case ASN_OPAQUE:
                case ASN_NSAP:
                case ASN_OBJECT_ID:
-                       DEBUG3 ("ASN_OPAQUE");
+                       DEBUG2 ("ASN_OPAQUE");
                        break;
                case SNMP_NOSUCHOBJECT:
-                       DEBUG3 ("SNMP_NOSUCHOBJECT");
+                       DEBUG2 ("SNMP_NOSUCHOBJECT");
                        break;
                case SNMP_NOSUCHINSTANCE:
-                       DEBUG3 ("SNMP_NOSUCHINSTANCE");
+                       DEBUG2 ("SNMP_NOSUCHINSTANCE");
                        break;
                case SNMP_ENDOFMIBVIEW:
-                       DEBUG3 ("SNMP_ENDOFMIBVIEW");
+                       DEBUG2 ("SNMP_ENDOFMIBVIEW");
                        break;
                case ASN_BIT_STR:
-                       DEBUG3 ("ASN_BIT_STR");
+                       DEBUG2 ("ASN_BIT_STR");
                        break;
                default:
-                       DEBUG3 ("Unknown type");
+                       DEBUG2 ("Unknown type");
                        break;
        }
        return ptr;
@@ -414,7 +426,7 @@ smux_set (oid *reqid, size_t *reqid_len,
 
                                /* This is exact match so result must be zero. */
                                if (result == 0) {
-                                       DEBUG3 ("SMUX function call index is %d", v->magic);
+                                       DEBUG2 ("SMUX function call index is %d", v->magic);
 
                                        statP = (*v->findVar) (v, suffix, &suffix_len, 1,
                                        &val_len, &write_method);
@@ -474,10 +486,11 @@ smux_get (oid *reqid, size_t *reqid_len, int exact,
 
                                /* This is exact match so result must be zero. */
                                if (result == 0) {
-                                       DEBUG3 ("SMUX function call index is %d", v->magic);
+                                       DEBUG2 ("SMUX function call index is %d", v->magic);
 
                                        *val = (*v->findVar) (v, suffix, &suffix_len, exact,
                                                        val_len, &write_method);
+
                                        /* There is no instance. */
                                        if (*val == NULL)
                                                return SNMP_ERR_NOSUCHNAME;
@@ -555,7 +568,7 @@ smux_getnext (oid *reqid, size_t *reqid_len, int exact,
                                                        v->name, v->namelen);
 
                                if (result <= 0) {
-                                       DEBUG3 ("SMUX function call index is %d", v->magic);
+                                       DEBUG2 ("SMUX function call index is %d", v->magic);
                                        if(result<0) {
                                                oid_copy(suffix, v->name, v->namelen);
                                                suffix_len = v->namelen;
@@ -588,17 +601,17 @@ smux_parse_get_header (char *ptr, size_t *len, long *reqid)
        /* Request ID. */
        ptr = asn_parse_int (ptr, len, &type, reqid, sizeof (*reqid));
 
-       DEBUG3 ("SMUX GET reqid: %ld len: %d", *reqid, (int) *len);
+       DEBUG2 ("SMUX GET reqid: %ld len: %d", *reqid, (int) *len);
 
        /* Error status. */
        ptr = asn_parse_int (ptr, len, &type, &errstat, sizeof (errstat));
 
-       DEBUG3 ("SMUX GET errstat %ld len: %d", errstat, *len);
+       DEBUG2 ("SMUX GET errstat %ld len: %d", errstat, *len);
 
        /* Error index. */
        ptr = asn_parse_int (ptr, len, &type, &errindex, sizeof (errindex));
 
-       DEBUG3 ("SMUX GET errindex %ld len: %d", errindex, *len);
+       DEBUG2 ("SMUX GET errindex %ld len: %d", errindex, *len);
 
        return ptr;
 }
@@ -614,7 +627,7 @@ smux_parse_set (char *ptr, size_t len, int action)
        size_t val_len;
        int ret;
 
-       DEBUG3 ("SMUX SET(%s) message parse: len %d",
+       DEBUG2 ("SMUX SET(%s) message parse: len %d",
                        (RESERVE1 == action) ? "RESERVE1" : ((FREE == action) ? "FREE" : "COMMIT"),
                        len);
 
@@ -643,7 +656,7 @@ smux_parse_get (char *ptr, size_t len, int exact)
        size_t val_len;
        int ret;
 
-       DEBUG3 ("SMUX GET message parse: len %d", len);
+       DEBUG2 ("SMUX GET message parse: len %d", len);
 
        /* Parse GET message header. */
        ptr = smux_parse_get_header (ptr, &len, &reqid);
@@ -686,7 +699,7 @@ smux_parse_rrsp (char *ptr, int len)
 
        ptr = asn_parse_int (ptr, &len, &val, &errstat, sizeof (errstat));
 
-       DEBUG3 ("SMUX_RRSP value: %d errstat: %ld", val, errstat);
+       DEBUG2 ("SMUX_RRSP value: %d errstat: %ld", val, errstat);
 }
 
 /* Parse SMUX message. */
@@ -755,35 +768,35 @@ process_rest: /* see note below: YYY */
                        break;
                case SMUX_CLOSE:
                        /* Close SMUX connection. */
-                       DEBUG3 ("SMUX_CLOSE");
+                       DEBUG2 ("SMUX_CLOSE");
                        smux_parse_close (ptr, len);
                        return -1;
                        break;
                case SMUX_RRSP:
                        /* This is response for register message. */
-                       DEBUG3 ("SMUX_RRSP");
+                       DEBUG2 ("SMUX_RRSP");
                        smux_parse_rrsp (ptr, len);
                        break;
                case SMUX_GET:
                        /* Exact request for object id. */
-                       DEBUG3 ("SMUX_GET");
+                       DEBUG2 ("SMUX_GET");
                        smux_parse_get (ptr, len, 1);
                        break;
                case SMUX_GETNEXT:
                        /* Next request for object id. */
-                       DEBUG3 ("SMUX_GETNEXT");
+                       DEBUG2 ("SMUX_GETNEXT");
                        smux_parse_get (ptr, len, 0);
                        break;
                case SMUX_SET:
                        /* SMUX_SET is supported with some limitations. */
-                       DEBUG3 ("SMUX_SET");
+                       DEBUG2 ("SMUX_SET");
                        /* save the data for future SMUX_SOUT */
                        memcpy (sout_save_buff, ptr, len);
                        sout_save_len = len;
                        smux_parse_set (ptr, len, RESERVE1);
                        break;
                default:
-                       DEBUG ("SMUX Unknown type: %d", type);
+                       DEBUG ("Unknown type: %d", type);
                        break;
        }
        return 0;
@@ -798,7 +811,7 @@ smux_read ()
        int ret;
 
        rad_snmp.smux_event=SMUX_NONE;
-       DEBUG3 ("SMUX read start");
+       DEBUG2 ("SMUX read start");
 
        /* Read message from SMUX socket. */
        len = recv (rad_snmp.smux_fd, buf, SMUXMAXPKTSIZE, 0);
@@ -819,7 +832,7 @@ smux_read ()
                return -1;
        }
 
-       DEBUG3 ("SMUX read len: %d", len);
+       DEBUG2 ("SMUX read len: %d", len);
 
        /* Parse the message. */
        ret = smux_parse (buf, len);
@@ -933,10 +946,9 @@ smux_register(void)
                len = BUFSIZ;
                asn_build_header (buf, &len, (u_char) SMUX_RREQ, (ptr - buf) - 2);
                ret = send (rad_snmp.smux_fd, buf, (ptr - buf), 0);
-               if (ret < 0) {
+               if (ret < 0)
                        return ret;
                }
-       }
        return ret;
 }
 
@@ -1081,7 +1093,7 @@ smux_init (oid defoid[], size_t defoid_len)
 
 /* Register subtree to smux master tree. */
 void
-smux_register_mib(UNUSED const char *descr, struct variable *var, size_t width,
+smux_register_mib(const char *descr, struct variable *var, size_t width,
                int num, oid name[], size_t namelen)
 {
        struct subtree *tree, *tt;
index 6decd72..1713d8d 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#ifdef HAVE_PTHREAD_H
+
+#include <stdlib.h>
+#include <string.h>
 
 /*
  *     Other OS's have sem_init, OS X doesn't.
  */
-#ifdef HAVE_SEMAPHORE_H
+#ifndef DARWIN
 #include <semaphore.h>
-#endif
-
-#ifdef DARWIN
+#else
 #include <mach/task.h>
 #include <mach/semaphore.h>
 
@@ -48,11 +47,18 @@ RCSID("$Id$")
 #define sem_post(s) semaphore_signal(*s)
 #endif
 
+#include <signal.h>
+
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
 
-#ifdef HAVE_PTHREAD_H
+#include "radiusd.h"
+#include "rad_assert.h"
+#include "conffile.h"
+
+static const char rcsid[] =
+"$Id$";
 
 #ifdef HAVE_OPENSSL_CRYPTO_H
 #include <openssl/crypto.h>
@@ -68,9 +74,6 @@ RCSID("$Id$")
 #define THREAD_CANCELLED       (2)
 #define THREAD_EXITED          (3)
 
-#define NUM_FIFOS               RAD_LISTEN_MAX
-
-
 /*
  *  A data structure which contains the information about
  *  the current thread.
@@ -101,6 +104,7 @@ typedef struct request_queue_t {
        RAD_REQUEST_FUNP  fun;
 } request_queue_t;
 
+
 typedef struct thread_fork_t {
        pid_t           pid;
        int             status;
@@ -118,7 +122,6 @@ typedef struct THREAD_POOL {
        THREAD_HANDLE *tail;
 
        int total_threads;
-       int active_threads;     /* protected by queue_mutex */
        int max_thread_num;
        int start_threads;
        int max_threads;
@@ -128,8 +131,11 @@ typedef struct THREAD_POOL {
        unsigned long request_count;
        time_t time_last_spawned;
        int cleanup_delay;
-       int spawn_flag;
 
+       /*
+        *      If threaded, we have to pay more attention to
+        *      child PID's when we fork...
+        */
        pthread_mutex_t wait_mutex;
        lrad_hash_table_t *waiters;
 
@@ -142,12 +148,13 @@ typedef struct THREAD_POOL {
        /*
         *      To ensure only one thread at a time touches the queue.
         */
-       pthread_mutex_t queue_mutex;
+       pthread_mutex_t mutex;
 
-       int             max_queue_size;
-       int             num_queued;
-       int             can_read_detail;
-       lrad_fifo_t     *fifo[NUM_FIFOS];
+       int             active_threads;
+       int             queue_head; /* first filled entry */
+       int             queue_tail; /* first empty entry */
+       int             queue_size;
+       request_queue_t *queue;
 } THREAD_POOL;
 
 static THREAD_POOL thread_pool;
@@ -164,7 +171,6 @@ static const CONF_PARSER thread_config[] = {
        { "max_spare_servers",       PW_TYPE_INTEGER, 0, &thread_pool.max_spare_threads,       "10" },
        { "max_requests_per_server", PW_TYPE_INTEGER, 0, &thread_pool.max_requests_per_thread, "0" },
        { "cleanup_delay",           PW_TYPE_INTEGER, 0, &thread_pool.cleanup_delay,           "5" },
-       { "max_queue_size",          PW_TYPE_INTEGER, 0, &thread_pool.max_queue_size,           "65536" },
        { NULL, -1, 0, NULL, NULL }
 };
 
@@ -183,18 +189,14 @@ static const CONF_PARSER thread_config[] = {
  *     to add them at some point.
  */
 
-static pthread_mutex_t *ssl_mutexes = NULL;
+static  pthread_mutex_t *ssl_mutexes = NULL;
 
-static unsigned long ssl_id_function(void)
-{
-       return (unsigned long) pthread_self();
-}
 
-static void ssl_locking_function(int mode, int n, const char *file, int line)
-{
-       file = file;            /* -Wunused */
-       line = line;            /* -Wunused */
+static unsigned long ssl_id_function (void) {
+       return (unsigned long)pthread_self();
+}
 
+static void ssl_locking_function (int mode, int n, const char *file, int line) {
        if (mode & CRYPTO_LOCK) {
                pthread_mutex_lock(&(ssl_mutexes[n]));
        } else {
@@ -202,17 +204,16 @@ static void ssl_locking_function(int mode, int n, const char *file, int line)
        }
 }
 
-static int setup_ssl_mutexes(void)
-{
+static int setup_ssl_mutexes (void) {
        int i;
 
-       ssl_mutexes = rad_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
-       if (!ssl_mutexes) {
+       ssl_mutexes = (pthread_mutex_t *)rad_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
+       if(!ssl_mutexes) {
                radlog(L_ERR, "Error allocating memory for SSL mutexes!");
                return 0;
        }
 
-       for (i = 0; i < CRYPTO_num_locks(); i++) {
+       for(i = 0; i < CRYPTO_num_locks(); i++) {
                pthread_mutex_init(&(ssl_mutexes[i]), NULL);
        }
 
@@ -221,6 +222,7 @@ static int setup_ssl_mutexes(void)
 
        return 1;
 }
+
 #endif
 
 
@@ -246,7 +248,6 @@ static void reap_children(void)
        int status;
        thread_fork_t mytf, *tf;
 
-
        pthread_mutex_lock(&thread_pool.wait_mutex);
 
        do {
@@ -256,7 +257,7 @@ static void reap_children(void)
                mytf.pid = pid;
                tf = lrad_hash_table_finddata(thread_pool.waiters, &mytf);
                if (!tf) continue;
-
+               
                tf->status = status;
                tf->exited = 1;
        } while (lrad_hash_table_num_elements(thread_pool.waiters) > 0);
@@ -264,6 +265,7 @@ static void reap_children(void)
        pthread_mutex_unlock(&thread_pool.wait_mutex);
 }
 
+
 /*
  *     Add a request to the list of waiting requests.
  *     This function gets called ONLY from the main handler thread...
@@ -272,51 +274,83 @@ static void reap_children(void)
  */
 static int request_enqueue(REQUEST *request, RAD_REQUEST_FUNP fun)
 {
-       int fifo;
-       request_queue_t *entry;
+       int num_entries;
 
-       pthread_mutex_lock(&thread_pool.queue_mutex);
+       pthread_mutex_lock(&thread_pool.mutex);
 
        thread_pool.request_count++;
 
-       if (thread_pool.num_queued >= thread_pool.max_queue_size) {
-               pthread_mutex_unlock(&thread_pool.queue_mutex);
+       /*
+        *      If the queue is empty, re-set the indices to zero,
+        *      for no particular reason...
+        */
+       if ((thread_pool.queue_head == thread_pool.queue_tail) &&
+           (thread_pool.queue_head != 0)) {
+               thread_pool.queue_head = thread_pool.queue_tail = 0;
+       }
+
+       /*
+        *      If the queue is full, die.
+        *
+        *      The math is to take into account the fact that it's a
+        *      circular queue.
+        */
+       num_entries = ((thread_pool.queue_tail + thread_pool.queue_size) -
+                      thread_pool.queue_head) % thread_pool.queue_size;
+       if (num_entries == (thread_pool.queue_size - 1)) {
+               int i;
+               request_queue_t *new_queue;
 
                /*
-                *      Mark the request as done.
+                *      If the queue becomes larger than 65536,
+                *      there's a serious problem.
                 */
-               radlog(L_ERR|L_CONS, "!!! ERROR !!! The server is blocked: discarding new request %d", request->number);
-               request->child_state = REQUEST_DONE;
-               return 0;
-       }
+               if (thread_pool.queue_size >= 65536) {
+                       pthread_mutex_unlock(&thread_pool.mutex);
 
-       entry = rad_malloc(sizeof(*entry));
-       entry->request = request;
-       entry->fun = fun;
+                       /*
+                        *      Mark the request as done.
+                        */
+                       radlog(L_ERR|L_CONS, "!!! ERROR !!! The server is blocked: discarding new request %d", request->number);
+                       request->finished = TRUE;
+                       return 0;
+               }
 
-       /*
-        *      Push the request onto the appropriate fifo for that
-        */
-       if (!lrad_fifo_push(thread_pool.fifo[request->priority],
-                           entry)) {
-               pthread_mutex_unlock(&thread_pool.queue_mutex);
-               radlog(L_ERR, "!!! ERROR !!! Failed inserting request %d into the queue", request->number);
-               request->child_state = REQUEST_DONE;
-               return 0;
+               /*
+                *      Malloc a new queue, doubled in size, copy the
+                *      data from the current queue over to it, zero
+                *      out the second half of the queue, free the old
+                *      one, and replace thread_pool.queue with the
+                *      new one.
+                */
+               new_queue = rad_malloc(sizeof(*new_queue) * thread_pool.queue_size * 2);
+               /*
+                *      Copy the queue element by element
+                */
+               for (i = 0; i < thread_pool.queue_size; i++) {
+                       new_queue[i] = thread_pool.queue[(i + thread_pool.queue_head) % thread_pool.queue_size];
+               }
+               memset(new_queue + thread_pool.queue_size,
+                      0, sizeof(*new_queue) * thread_pool.queue_size);
+
+               free(thread_pool.queue);
+               thread_pool.queue = new_queue;
+               thread_pool.queue_tail = ((thread_pool.queue_tail + thread_pool.queue_size) - thread_pool.queue_head) % thread_pool.queue_size;
+               thread_pool.queue_head = 0;
+               thread_pool.queue_size *= 2;
        }
 
        /*
-        *      We've added an entry that didn't come from the detail
-        *      file.  Note that the child thread should signal the
-        *      main worker thread again when the queue becomes empty.
+        *      Add the data to the queue tail, increment the tail,
+        *      and signal the semaphore that there's another request
+        *      in the queue.
         */
-       if (request->listener->type != RAD_LISTEN_DETAIL) {
-               thread_pool.can_read_detail = FALSE;
-       }
-
-       thread_pool.num_queued++;
+       thread_pool.queue[thread_pool.queue_tail].request = request;
+       thread_pool.queue[thread_pool.queue_tail].fun = fun;
+       thread_pool.queue_tail++;
+       thread_pool.queue_tail &= (thread_pool.queue_size - 1);
 
-       pthread_mutex_unlock(&thread_pool.queue_mutex);
+       pthread_mutex_unlock(&thread_pool.mutex);
 
        /*
         *      There's one more request in the queue.
@@ -327,6 +361,7 @@ static int request_enqueue(REQUEST *request, RAD_REQUEST_FUNP fun)
         *      the mutex, it will be unlocked, and there won't be
         *      contention.
         */
+
        sem_post(&thread_pool.semaphore);
 
        return 1;
@@ -335,88 +370,124 @@ static int request_enqueue(REQUEST *request, RAD_REQUEST_FUNP fun)
 /*
  *     Remove a request from the queue.
  */
-static int request_dequeue(REQUEST **request, RAD_REQUEST_FUNP *fun)
+static void request_dequeue(REQUEST **request, RAD_REQUEST_FUNP *fun)
 {
-       RAD_LISTEN_TYPE i, start;
-       request_queue_t *entry;
-
        reap_children();
 
-       pthread_mutex_lock(&thread_pool.queue_mutex);
-
-       /*
-        *      Clear old requests from all queues.
-        *
-        *      We only do one pass over the queue, in order to
-        *      amortize the work across the child threads.  Since we
-        *      do N checks for one request de-queued, the old
-        *      requests will be quickly cleared.
-        */
-       for (i = 0; i < RAD_LISTEN_MAX; i++) {
-               entry = lrad_fifo_peek(thread_pool.fifo[i]);
-               if (!entry ||
-                   (entry->request->master_state != REQUEST_STOP_PROCESSING)) {
-                       continue;
-}
-               /*
-                *      This entry was marked to be stopped.  Acknowledge it.
-                */
-               entry = lrad_fifo_pop(thread_pool.fifo[i]);
-               rad_assert(entry != NULL);
-               entry->request->child_state = REQUEST_DONE;
-       }
+       pthread_mutex_lock(&thread_pool.mutex);
 
-       start = 0;
- retry:
        /*
-        *      Pop results from the top of the queue
+        *      Head & tail are the same.  There's nothing in
+        *      the queue.
         */
-       for (i = start; i < RAD_LISTEN_MAX; i++) {
-               entry = lrad_fifo_pop(thread_pool.fifo[i]);
-               if (entry) {
-                       start = i;
-                       break;
-               }
-       }
-
-       if (!entry) {
-               pthread_mutex_unlock(&thread_pool.queue_mutex);
+       if (thread_pool.queue_head == thread_pool.queue_tail) {
+               pthread_mutex_unlock(&thread_pool.mutex);
                *request = NULL;
                *fun = NULL;
-               return 0;
+               return;
        }
 
-       rad_assert(thread_pool.num_queued > 0);
-       thread_pool.num_queued--;
-       *request = entry->request;
-       *fun = entry->fun;
-       free(entry);
+       *request = thread_pool.queue[thread_pool.queue_head].request;
+       *fun = thread_pool.queue[thread_pool.queue_head].fun;
 
        rad_assert(*request != NULL);
        rad_assert((*request)->magic == REQUEST_MAGIC);
        rad_assert(*fun != NULL);
 
+       thread_pool.queue_head++;
+       thread_pool.queue_head &= (thread_pool.queue_size - 1);
+
        /*
-        *      If the request has sat in the queue for too long,
-        *      kill it.
+        *      FIXME: Check the request timestamp.  If it's more than
+        *      "clean_delay" seconds old, then discard the request,
+        *      log an error, and try to de-queue another request.
         *
-        *      The main clean-up code can't delete the request from
-        *      the queue, and therefore won't clean it up until we
-        *      have acknowledged it as "done".
+        *      The main clean-up code won't delete the request from
+        *      the request list, because it's not marked "finished"
         */
-       if ((*request)->master_state == REQUEST_STOP_PROCESSING) {
-               (*request)->child_state = REQUEST_DONE;
-               goto retry;
-       }
 
        /*
         *      The thread is currently processing a request.
         */
        thread_pool.active_threads++;
 
-       pthread_mutex_unlock(&thread_pool.queue_mutex);
+       pthread_mutex_unlock(&thread_pool.mutex);
 
-       return 1;
+       /*
+        *      If the request is currently being processed, then that
+        *      MAY be OK, if it's a proxy reply.  In that case,
+        *      sending the packet may result in a reply being
+        *      received before that thread clears the child_pid.
+        *
+        *      In that case, we busy-wait for the request to be free.
+        *
+        *      We COULD push it onto the queue and try to grab
+        *      another request, but what if this is the only request?
+        *      What if there are multiple such packets with race
+        *      conditions?  We don't want to thrash the queue...
+        *
+        *      This busy-wait is less than optimal, but it's simple,
+        *      fail-safe, and it works.
+        */
+       if ((*request)->child_pid != NO_SUCH_CHILD_PID) {
+               int count, ok;
+               struct timeval tv;
+#ifdef HAVE_PTHREAD_SIGMASK
+               sigset_t set, old_set;
+
+               /*
+                *      Block a large number of signals which could
+                *      cause the select to return EINTR
+                */
+               sigemptyset(&set);
+               sigaddset(&set, SIGPIPE);
+               sigaddset(&set, SIGCONT);
+               sigaddset(&set, SIGSTOP);
+               sigaddset(&set, SIGCHLD);
+               pthread_sigmask(SIG_BLOCK, &set, &old_set);
+#endif
+
+               rad_assert((*request)->proxy_reply != NULL);
+
+               ok = FALSE;
+
+               /*
+                *      Sleep for 100 milliseconds.  If the other thread
+                *      doesn't get serviced in this time, to clear
+                *      the "child_pid" entry, then the server is too
+                *      busy, so we die.
+                */
+               for (count = 0; count < 10; count++) {
+                       tv.tv_sec = 0;
+                       tv.tv_usec = 10000; /* sleep for 10 milliseconds */
+
+                       /*
+                        *      Portable sleep that's thread-safe.
+                        *
+                        *      Don't worry about interrupts, as they're
+                        *      blocked above.
+                        */
+                       select(0, NULL, NULL, NULL, &tv);
+                       if ((*request)->child_pid == NO_SUCH_CHILD_PID) {
+                               ok = TRUE;
+                               break;
+                       }
+               }
+
+#ifdef HAVE_PTHREAD_SIGMASK
+               /*
+                *      Restore the original thread signal mask.
+                */
+               pthread_sigmask(SIG_SETMASK, &old_set, NULL);
+#endif
+
+               if (!ok) {
+                       radlog(L_ERR, "FATAL!  Server is too busy to process requests");
+                       exit(1);
+               }
+       }
+
+       return;
 }
 
 
@@ -429,13 +500,31 @@ static void *request_handler_thread(void *arg)
 {
        RAD_REQUEST_FUNP  fun;
        THREAD_HANDLE     *self = (THREAD_HANDLE *) arg;
+#ifdef HAVE_PTHREAD_SIGMASK
+       sigset_t set;
+
+       /*
+        *      Block SIGHUP handling for the child threads.
+        *
+        *      This ensures that only the main server thread will
+        *      process HUP signals.
+        *
+        *      If we don't have sigprocmask, then it shouldn't be
+        *      a problem, either, as the sig_hup handler should check
+        *      for this condition.
+        */
+       sigemptyset(&set);
+       sigaddset(&set, SIGHUP);
+       sigaddset(&set, SIGINT);
+       sigaddset(&set, SIGQUIT);
+       sigaddset(&set, SIGTERM);
+       pthread_sigmask(SIG_BLOCK, &set, NULL);
+#endif
 
        /*
         *      Loop forever, until told to exit.
         */
        do {
-               int can_read_detail;
-
                /*
                 *      Wait to be signalled.
                 */
@@ -465,7 +554,8 @@ static void *request_handler_thread(void *arg)
                 *      It may be empty, in which case we fail
                 *      gracefully.
                 */
-               if (!request_dequeue(&self->request, &fun)) continue;
+               request_dequeue(&self->request, &fun);
+               if (!self->request) continue;
 
                self->request->child_pid = self->pthread_id;
                self->request_count++;
@@ -474,37 +564,19 @@ static void *request_handler_thread(void *arg)
                       self->thread_num, self->request->number,
                       self->request_count);
 
-               radius_handle_request(self->request, fun);
+               /*
+                *      Respond, and reset request->child_pid
+                */
+               rad_respond(self->request, fun);
+               self->request = NULL;
 
                /*
                 *      Update the active threads.
                 */
-               pthread_mutex_lock(&thread_pool.queue_mutex);
+               pthread_mutex_lock(&thread_pool.mutex);
                rad_assert(thread_pool.active_threads > 0);
                thread_pool.active_threads--;
-
-               /*
-                *      If we're not currently allowed to read the
-                *      detail file, AND there are no requests queued,
-                *      THEN signal the main worker thread that
-                *      there's at least one waiting thread (us) who
-                *      can accept a packet from the detail file.
-                */
-               can_read_detail = FALSE;
-               if (!thread_pool.can_read_detail &&
-                   (thread_pool.num_queued == 0)) {
-                       can_read_detail = TRUE;
-               }
-
-               pthread_mutex_unlock(&thread_pool.queue_mutex);
-
-               /*
-                *      Do this out of the lock to be nice to everyone.
-                */
-               if (can_read_detail) {
-                       radius_signal_self(RADIUS_SIGNAL_SELF_DETAIL);
-               }
-
+               pthread_mutex_unlock(&thread_pool.mutex);
        } while (self->status != THREAD_CANCELLED);
 
        DEBUG2("Thread %d exiting...", self->thread_num);
@@ -527,11 +599,9 @@ static void *request_handler_thread(void *arg)
 }
 
 /*
- *     Take a THREAD_HANDLE, delete it from the thread pool and
- *     free its resources.
+ *     Take a THREAD_HANDLE, and delete it from the thread pool.
  *
- *     This function is called ONLY from the main server thread,
- *     ONLY after the thread has exited.
+ *     This function is called ONLY from the main server thread.
  */
 static void delete_thread(THREAD_HANDLE *handle)
 {
@@ -540,8 +610,6 @@ static void delete_thread(THREAD_HANDLE *handle)
 
        rad_assert(handle->request == NULL);
 
-       DEBUG2("Deleting thread %d", handle->thread_num);
-
        prev = handle->prev;
        next = handle->next;
        rad_assert(thread_pool.total_threads > 0);
@@ -564,8 +632,16 @@ static void delete_thread(THREAD_HANDLE *handle)
                next->prev = prev;
        }
 
+       DEBUG2("Deleting thread %d", handle->thread_num);
+
        /*
-        *      Free the handle, now that it's no longer referencable.
+        *      This thread has exited.  Delete any additional
+        *      resources associated with it.
+        */
+
+       /*
+        *      Free the memory, now that we're sure the thread
+        *      exited.
         */
        free(handle);
 }
@@ -667,13 +743,15 @@ static THREAD_HANDLE *spawn_thread(time_t now)
  */
 int total_active_threads(void)
 {
-       /*
-        *      We don't acquire the mutex, so this is just an estimate.
-        *      We can't return with the lock held, so there's no point
-        *      in getting the guaranteed correct value; by the time
-        *      the caller sees it, it can be wrong again.
-        */
-       return thread_pool.active_threads;
+        int rcode = 0;
+       THREAD_HANDLE *handle;
+
+       for (handle = thread_pool.head; handle != NULL; handle = handle->next){
+               if (handle->request != NULL) {
+                       rcode ++;
+               }
+       }
+       return (rcode);
 }
 
 
@@ -698,7 +776,7 @@ static int pid_cmp(const void *one, const void *two)
  *
  *     FIXME: What to do on a SIGHUP???
  */
-int thread_pool_init(int spawn_flag)
+int thread_pool_init(void)
 {
        int             i, rcode;
        CONF_SECTION    *pool_cf;
@@ -708,12 +786,6 @@ int thread_pool_init(int spawn_flag)
        now = time(NULL);
 
        /*
-        *      We're not spawning new threads, don't do
-        *      anything.
-        */
-       if (!spawn_flag) return 0;
-
-       /*
         *      After a SIGHUP, we don't over-write the previous values.
         */
        if (!pool_initialized) {
@@ -726,13 +798,12 @@ int thread_pool_init(int spawn_flag)
                thread_pool.total_threads = 0;
                thread_pool.max_thread_num = 1;
                thread_pool.cleanup_delay = 5;
-               thread_pool.spawn_flag = spawn_flag;
 
                if ((pthread_mutex_init(&thread_pool.wait_mutex,NULL) != 0)) {
-                       radlog(L_ERR, "FATAL: Failed to initialize wait mutex: %s",
+                       radlog(L_ERR, "FATAL: Failed to initialize mutex: %s",
                               strerror(errno));
                        exit(1);
-               }
+               }               
 
                /*
                 *      Create the hash table of child PID's
@@ -767,7 +838,6 @@ int thread_pool_init(int spawn_flag)
        /*
         *      Initialize the queue of requests.
         */
-       memset(&thread_pool.semaphore, 0, sizeof(thread_pool.semaphore));
        rcode = sem_init(&thread_pool.semaphore, 0, SEMAPHORE_LOCKED);
        if (rcode != 0) {
                radlog(L_ERR|L_CONS, "FATAL: Failed to initialize semaphore: %s",
@@ -775,30 +845,31 @@ int thread_pool_init(int spawn_flag)
                exit(1);
        }
 
-       rcode = pthread_mutex_init(&thread_pool.queue_mutex,NULL);
+       rcode = pthread_mutex_init(&thread_pool.mutex,NULL);
        if (rcode != 0) {
-               radlog(L_ERR, "FATAL: Failed to initialize queue mutex: %s",
+               radlog(L_ERR, "FATAL: Failed to initialize mutex: %s",
                       strerror(errno));
                exit(1);
        }
 
        /*
-        *      Allocate multiple fifos.
+        *      Queue head & tail are set to zero by the memset,
+        *      above.
+        *
+        *      Allocate an initial queue, always as a power of 2.
         */
-       for (i = 0; i < RAD_LISTEN_MAX; i++) {
-               thread_pool.fifo[i] = lrad_fifo_create(65536, NULL);
-               if (!thread_pool.fifo[i]) {
-                       radlog(L_ERR, "FATAL: Failed to set up request fifo");
-                       exit(1);
-               }
-       }
+       thread_pool.queue_size = 256;
+       thread_pool.queue = rad_malloc(sizeof(*thread_pool.queue) *
+                                      thread_pool.queue_size);
+       memset(thread_pool.queue, 0, (sizeof(*thread_pool.queue) *
+                                     thread_pool.queue_size));
 
 #ifdef HAVE_OPENSSL_CRYPTO_H
        /*
         *      If we're linking with OpenSSL too, then we need
         *      to set up the mutexes and enable the thread callbacks.
         */
-       if (!setup_ssl_mutexes()) {
+       if(!setup_ssl_mutexes()) {
                radlog(L_ERR, "FATAL: Failed to set up SSL mutexes");
                exit(1);
        }
@@ -831,34 +902,13 @@ int thread_pool_init(int spawn_flag)
 int thread_pool_addrequest(REQUEST *request, RAD_REQUEST_FUNP fun)
 {
        /*
-        *      We've been told not to spawn threads, so don't.
-        */
-       if (!thread_pool.spawn_flag) {
-               radius_handle_request(request, fun);
-
-               /*
-                *      Requests that care about child process exit
-                *      codes have already either called
-                *      rad_waitpid(), or they've given up.
-                */
-               wait(NULL);
-               return 1;
-       }
-
-       /*
         *      Add the new request to the queue.
         */
        if (!request_enqueue(request, fun)) return 0;
 
        /*
         *      If the thread pool is busy handling requests, then
-        *      try to spawn another one.  We don't acquire the mutex
-        *      before reading active_threads, so our thread count is
-        *      just an estimate.  It's fine to go ahead and spawn an
-        *      extra thread in that case.
-        *      NOTE: the log message may be in error since active_threads
-        *      is an estimate, but it's only in error about the thread
-        *      count, not about the fact that we can't create a new one.
+        *      try to spawn another one.
         */
        if (thread_pool.active_threads == thread_pool.total_threads) {
                if (spawn_thread(request->timestamp) == NULL) {
@@ -903,7 +953,7 @@ int thread_pool_clean(time_t now)
 
        /*
         *      We don't need a mutex lock here, as we're reading
-        *      active_threads, and not modifying it.  We want a close
+        *      the location, and not modifying it.  We want a close
         *      approximation of the number of active threads, and this
         *      is good enough.
         */
@@ -1059,7 +1109,7 @@ pid_t rad_fork(void)
 
                tf = rad_malloc(sizeof(*tf));
                memset(tf, 0, sizeof(*tf));
-
+               
                tf->pid = child_pid;
 
                pthread_mutex_lock(&thread_pool.wait_mutex);
@@ -1078,7 +1128,6 @@ pid_t rad_fork(void)
        return child_pid;
 }
 
-
 /*
  *     Wait 10 seconds at most for a child to exit, then give up.
  */
@@ -1098,10 +1147,10 @@ pid_t rad_waitpid(pid_t pid, int *status)
        pthread_mutex_unlock(&thread_pool.wait_mutex);
 
        if (!tf) return -1;
-
+       
        for (i = 0; i < 100; i++) {
                reap_children();
-
+               
                if (tf->exited) {
                        *status = tf->status;
 
@@ -1110,9 +1159,9 @@ pid_t rad_waitpid(pid_t pid, int *status)
                        pthread_mutex_unlock(&thread_pool.wait_mutex);
                        return pid;
                }
-               usleep(100000); /* sleep for 1/10 of a second */
+               usleep(100000);
        }
-
+       
        /*
         *      10 seconds have passed, give up on the child.
         */
@@ -1123,22 +1172,4 @@ pid_t rad_waitpid(pid_t pid, int *status)
        return 0;
 }
 
-#else /* HAVE_PTHREAD_H */
-/*
- *     "thread" code when we don't have threads.
- */
-int thread_pool_init(int spawn_flag)
-{
-       return 0;
-}
-
-/*
- *     call "radrespond".
- */
-int thread_pool_addrequest(REQUEST *request, RAD_REQUEST_FUNP fun)
-{
-       radius_handle_request(request, fun);
-       return 1;
-}
-
-#endif /* HAVE_PTHREAD_H */
+#endif
similarity index 94%
rename from src/modules/rlm_logintime/timestr.c
rename to src/main/timestr.c
index c90e471..a1da599 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/radiusd.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
+#include "radiusd.h"
+
 static const char *days[] =
        { "su", "mo", "tu", "we", "th", "fr", "sa", "wk", "any", "al" };
 
@@ -178,7 +183,7 @@ static int week_fill(char *bitmap, char *tm)
        char *s;
        char tmp[128];
 
-       strlcpy(tmp, tm, 128);
+       strncpy(tmp, tm, 128);
        tmp[127] = 0;
        for (s = tmp; *s; s++)
                if (isupper(*s)) *s = tolower(*s);
index 17e4ca1..a881ae9 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 #include <signal.h>
 
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#ifdef HAVE_UNISTD_H
+#      include <unistd.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "radiusd.h"
+#include "rad_assert.h"
+
 /*
  *     The signal() function in Solaris 2.5.1 sets SA_NODEFER in
  *     sa_flags, which causes grief if signal() is called in the
@@ -43,7 +56,6 @@ RCSID("$Id$")
  *     Using sigaction() to reset the signal handler fixes the problem,
  *     so where available, we prefer that solution.
  */
-
 void (*reset_signal(int signo, void (*func)(int)))(int)
 {
 #ifdef HAVE_SIGACTION
@@ -69,8 +81,6 @@ void (*reset_signal(int signo, void (*func)(int)))(int)
         *      so we don't have a choice.
         */
        signal(signo, func);
-
-       return NULL;
 #endif
 }
 
@@ -162,28 +172,6 @@ void *request_data_get(REQUEST *request,
 
 
 /*
- *     Get opaque data from a request without removing it.
- */
-void *request_data_reference(REQUEST *request,
-                      void *unique_ptr, int unique_int)
-{
-       request_data_t **last;
-
-       for (last = &(request->data); *last != NULL; last = &((*last)->next)) {
-               if (((*last)->unique_ptr == unique_ptr) &&
-                   ((*last)->unique_int == unique_int)) {
-                       request_data_t *this = *last;
-                       void *ptr = this->opaque;
-
-                       return ptr;
-               }
-       }
-
-       return NULL;            /* wasn't found, too bad... */
-}
-
-
-/*
  *     Free a REQUEST struct.
  */
 void request_free(REQUEST **request_ptr)
@@ -195,6 +183,12 @@ void request_free(REQUEST **request_ptr)
 
        request = *request_ptr;
 
+       /*
+        *      If there's a thread currently active on this request,
+        *      blow up!
+        */
+       rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
+
        if (request->packet)
                rad_free(&request->packet);
 
@@ -228,9 +222,9 @@ void request_free(REQUEST **request_ptr)
 
 #ifndef NDEBUG
        request->magic = 0x01020304;    /* set the request to be nonsense */
+       strcpy(request->secret, "REQUEST-DELETED");
+       strcpy(request->proxysecret, "REQUEST-DELETED");
 #endif
-       request->client = NULL;
-       request->home_server = NULL;
        free(request);
 
        *request_ptr = NULL;
@@ -321,6 +315,11 @@ void *rad_malloc(size_t size)
        return ptr;
 }
 
+void xfree(const char *ptr)
+{
+       free((char *)ptr);
+}
+
 /*
  *     Logs an error message and aborts the program
  *
@@ -353,6 +352,7 @@ REQUEST *request_alloc(void)
        request->password = NULL;
        request->timestamp = time(NULL);
        request->child_pid = NO_SUCH_CHILD_PID;
+       request->container = NULL;
        request->options = RAD_REQUEST_OPTION_NONE;
 
        return request;
@@ -365,146 +365,181 @@ REQUEST *request_alloc(void)
  *     This function allows modules to inject fake requests
  *     into the server, for tunneled protocols like TTLS & PEAP.
  */
-REQUEST *request_alloc_fake(REQUEST *request)
+REQUEST *request_alloc_fake(REQUEST *oldreq)
 {
-  REQUEST *fake;
+  REQUEST *request;
 
-  fake = request_alloc();
+  request = request_alloc();
 
-  fake->number = request->number;
-  fake->child_pid = NO_SUCH_CHILD_PID;
+  request->number = oldreq->number;
+  request->child_pid = NO_SUCH_CHILD_PID;
+  request->options = RAD_REQUEST_OPTION_FAKE_REQUEST;
 
-  fake->packet = rad_alloc(0);
-  if (!fake->packet) {
-         request_free(&fake);
-         return NULL;
-  }
+  request->packet = rad_alloc(0);
+  rad_assert(request->packet != NULL);
 
-  fake->reply = rad_alloc(0);
-  if (!fake->reply) {
-         request_free(&fake);
-         return NULL;
-  }
+  request->reply = rad_alloc(0);
+  rad_assert(request->reply != NULL);
 
   /*
-   *   Fill in the fake request.
+   *   Fill in the fake request packet.
    */
-  fake->packet->sockfd = -1;
-  fake->packet->src_ipaddr = request->packet->src_ipaddr;
-  fake->packet->src_port = request->packet->src_port;
-  fake->packet->dst_ipaddr = request->packet->dst_ipaddr;
-  fake->packet->dst_port = 0;
+  request->packet->sockfd = -1;
+  request->packet->src_ipaddr = htonl(INADDR_LOOPBACK);
+  request->packet->dst_ipaddr = htonl(INADDR_LOOPBACK);
+  request->packet->src_port = request->number >> 8;
+  request->packet->dst_port = 0;
 
   /*
-   *   This isn't STRICTLY required, as the fake request MUST NEVER
+   *   This isn't STRICTLY required, as the fake request SHOULD NEVER
    *   be put into the request list.  However, it's still reasonable
    *   practice.
    */
-  fake->packet->id = fake->number & 0xff;
-  fake->packet->code = request->packet->code;
-  fake->timestamp = request->timestamp;
+  request->packet->id = request->number & 0xff;
+  request->packet->code = oldreq->packet->code;
+  request->timestamp = oldreq->timestamp;
 
   /*
    *   Fill in the fake reply, based on the fake request.
    */
-  fake->reply->sockfd = fake->packet->sockfd;
-  fake->reply->src_ipaddr = fake->packet->dst_ipaddr;
-  fake->reply->src_port = fake->packet->dst_port;
-  fake->reply->dst_ipaddr = fake->packet->src_ipaddr;
-  fake->reply->dst_port = fake->packet->src_port;
-  fake->reply->id = fake->packet->id;
-  fake->reply->code = 0; /* UNKNOWN code */
-
-  return fake;
+  request->reply->sockfd = request->packet->sockfd;
+  request->reply->dst_ipaddr = request->packet->src_ipaddr;
+  request->reply->dst_port = request->packet->src_port;
+  request->reply->id = request->packet->id;
+  request->reply->code = 0; /* UNKNOWN code */
+
+  return request;
 }
 
 
 /*
- *     Copy a quoted string.
+ *  Perform any RFC specified cleaning of outgoing replies
  */
-int rad_copy_string(char *to, const char *from)
+void rfc_clean(RADIUS_PACKET *packet)
 {
-       int length = 0;
-       char quote = *from;
+       VALUE_PAIR *vps = NULL;
 
-       do {
-               if (*from == '\\') {
-                       *(to++) = *(from++);
-                       length++;
-               }
-               *(to++) = *(from++);
-               length++;
-       } while (*from && (*from != quote));
+       switch (packet->code) {
+               /*
+                *      In the default case, we just move all of the
+                *      attributes over.
+                */
+       default:
+               vps = packet->vps;
+               packet->vps = NULL;
+               break;
 
-       if (*from != quote) return -1; /* not properly quoted */
+               /*
+                *      Accounting responses can only contain
+                *      Proxy-State and VSA's.  Note that we do NOT
+                *      move the Proxy-State attributes over, as the
+                *      Proxy-State attributes in this packet are NOT
+                *      the right ones to use.  The reply function
+                *      takes care of copying those attributes from
+                *      the original request, which ARE the right ones
+                *      to use.
+                */
+       case PW_ACCOUNTING_RESPONSE:
+               pairmove2(&vps, &(packet->vps), PW_VENDOR_SPECIFIC);
+               break;
 
-       *(to++) = quote;
-       length++;
-       *to = '\0';
+               /*
+                *      Authentication REJECT's can have only
+                *      EAP-Message, Message-Authenticator
+                *      Reply-Message and Proxy-State.
+                *
+                *      We delete everything other than these.
+                *      Proxy-State is added below, just before the
+                *      reply is sent.
+                */
+       case PW_AUTHENTICATION_REJECT:
+               pairmove2(&vps, &(packet->vps), PW_EAP_MESSAGE);
+               pairmove2(&vps, &(packet->vps), PW_MESSAGE_AUTHENTICATOR);
+               pairmove2(&vps, &(packet->vps), PW_REPLY_MESSAGE);
+               break;
+       }
 
-       return length;
+       /*
+        *      Move the newly cleaned attributes over.
+        */
+       pairfree(&packet->vps);
+       packet->vps = vps;
+
+       /*
+        *      FIXME: Perform other, more generic sanity checks.
+        */
 }
 
 
 /*
- *     Copy a %{} string.
+ *  Reject a request, by sending a trivial reply packet.
  */
-int rad_copy_variable(char *to, const char *from)
+ void request_reject(REQUEST *request)
 {
-       int length = 0;
-       int sublen;
-
-       *(to++) = *(from++);
-       length++;
-
-       while (*from) {
-               switch (*from) {
-               case '"':
-               case '\'':
-                       sublen = rad_copy_string(to, from);
-                       if (sublen < 0) return sublen;
-                       from += sublen;
-                       to += sublen;
-                       break;
+       VALUE_PAIR *vps;
 
-               case '}':       /* end of variable expansion */
-                       *(to++) = *(from++);
-                       *to = '\0';
-                       length++;
-                       return length; /* proper end of variable */
+       /*
+        *      Already rejected.  Don't do anything.
+        */
+       if (request->options & RAD_REQUEST_OPTION_REJECTED) {
+               return;
+       }
 
-               case '\\':
-                       *(to++) = *(from++);
-                       *(to++) = *(from++);
-                       length += 2;
+       DEBUG2("Server rejecting request %d.", request->number);
+       switch (request->packet->code) {
+               /*
+                *  Accounting requests, etc. get dropped on the floor.
+                */
+               default:
+               case PW_ACCOUNTING_REQUEST:
+               case PW_STATUS_SERVER:
                        break;
 
-               case '%':       /* start of variable expansion */
-                       if (from[1] == '{') {
-                               *(to++) = *(from++);
-                               length++;
+               /*
+                *  Authentication requests get their Proxy-State
+                *  attributes copied over, and an otherwise blank
+                *  reject message sent.
+                */
+               case PW_AUTHENTICATION_REQUEST:
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
 
-                               sublen = rad_copy_variable(to, from);
-                               if (sublen < 0) return sublen;
-                               from += sublen;
-                               to += sublen;
-                               length += sublen;
-                       } /* else FIXME: catch %%{ ?*/
+                       /*
+                        *  Perform RFC limitations on outgoing replies.
+                        */
+                       rfc_clean(request->reply);
 
-                       /* FALL-THROUGH */
+                       /*
+                        *  Need to copy Proxy-State from request->packet->vps
+                        */
+                       vps = paircopy2(request->packet->vps, PW_PROXY_STATE);
+                       if (vps != NULL)
+                               pairadd(&(request->reply->vps), vps);
                        break;
+       }
 
-               default:
-                       *(to++) = *(from++);
-                       length++;
-                       break;
+       /*
+        *      If a reply exists, send it.
+        *
+        *      But DON'T send a RADIUS packet for a fake request.
+        */
+       if ((request->reply->code != 0) &&
+           ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) == 0)) {
+               /*
+                *      If we're not delaying authentication rejects,
+                *      then send the response immediately.  Otherwise,
+                *      mark the request as delayed, and do NOT send a
+                *      response.
+                */
+               if (mainconfig.reject_delay == 0) {
+                       rad_send(request->reply, request->packet,
+                                    request->secret);
+               } else {
+                       request->options |= RAD_REQUEST_OPTION_DELAYED_REJECT;
                }
-       } /* loop over the input string */
+       }
 
        /*
-        *      We ended the string before a trailing '}'
+        *      Remember that it was rejected.
         */
-
-       return -1;
+       request->options |= RAD_REQUEST_OPTION_REJECTED;
 }
-
index c632847..a7aab2e 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
 
 #ifdef HAVE_REGEX_H
 #      include <regex.h>
@@ -45,6 +52,8 @@ RCSID("$Id$")
 #endif
 #endif
 
+#include "radiusd.h"
+
 struct cmp {
        int attribute;
        int otherattr;
@@ -54,117 +63,40 @@ struct cmp {
 };
 static struct cmp *cmp;
 
-int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp)
+
+/*
+ *     Compare 2 attributes. May call the attribute compare function.
+ */
+static int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
+                      VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 {
        int ret = -2;
+       struct cmp *c;
+
+       /*
+        *      Sanity check.
+        */
+#if 0
+       if (request->attribute != check->attribute)
+               return -2;
+#endif
 
        /*
         *      Check for =* and !* and return appropriately
         */
        if( check->operator == T_OP_CMP_TRUE )
-                return 0;
+                return 0;  /* always return 0/EQUAL */
        if( check->operator == T_OP_CMP_FALSE )
-                return 1;
-
-#ifdef HAVE_REGEX_H
-       if (check->operator == T_OP_REG_EQ) {
-               int i, compare;
-               regex_t reg;
-               char name[1024];
-               char value[1024];
-               regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];
-
-               snprintf(name, sizeof(name), "%%{%s}", check->name);
-               radius_xlat(value, sizeof(value), name, request, NULL);
-
-               /*
-                *      Include substring matches.
-                */
-               regcomp(&reg, (char *)check->vp_strvalue,
-                       REG_EXTENDED);
-               compare = regexec(&reg, value,  REQUEST_MAX_REGEX + 1,
-                                 rxmatch, 0);
-               regfree(&reg);
-
-               /*
-                *      Add %{0}, %{1}, etc.
-                */
-               for (i = 0; i <= REQUEST_MAX_REGEX; i++) {
-                       char *p;
-                       char buffer[sizeof(check->vp_strvalue)];
-
-                       /*
-                        *      Didn't match: delete old
-                        *      match, if it existed.
-                        */
-                       if ((compare != 0) ||
-                           (rxmatch[i].rm_so == -1)) {
-                               p = request_data_get(request, request,
-                                                    REQUEST_DATA_REGEX | i);
-                               if (p) {
-                                       free(p);
-                                       continue;
-                               }
-
-                               /*
-                                *      No previous match
-                                *      to delete, stop.
-                                */
-                               break;
-                       }
-
-                       /*
-                        *      Copy substring into buffer.
-                        */
-                       memcpy(buffer, value + rxmatch[i].rm_so,
-                              rxmatch[i].rm_eo - rxmatch[i].rm_so);
-                       buffer[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0';
-
-                       /*
-                        *      Copy substring, and add it to
-                        *      the request.
-                        *
-                        *      Note that we don't check
-                        *      for out of memory, which is
-                        *      the only error we can get...
-                        */
-                       p = strdup(buffer);
-                       request_data_add(request, request,
-                                        REQUEST_DATA_REGEX | i,
-                                        p, free);
-               }
-               if (compare == 0) return 0;
-               return -1;
-       }
-
-       if (check->operator == T_OP_REG_NE) {
-               int i, compare;
-               regex_t reg;
-               char name[1024];
-               char value[1024];
-               regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];
-
-               snprintf(name, sizeof(name), "%%{%s}", check->name);
-               radius_xlat(value, sizeof(value), name, request, NULL);
-
-               /*
-                *      Include substring matches.
-                */
-               regcomp(&reg, (char *)check->vp_strvalue,
-                       REG_EXTENDED);
-               compare = regexec(&reg, value,  REQUEST_MAX_REGEX + 1,
-                                 rxmatch, 0);
-               regfree(&reg);
-
-               if (compare != 0) return 0;
-               return -1;
-
-       }
-#endif
+                return 1;  /* always return 1/NOT EQUAL */
 
        /*
-        *      Not a regular expression, compare the types.
+        *      See if there is a special compare function.
         */
+       for (c = cmp; c; c = c->next)
+               if (c->attribute == check->attribute)
+                       return (c->compare)(c->instance, req, request, check,
+                               check_pairs, reply_pairs);
+
        switch(check->type) {
 #ifdef ASCEND_BINARY
                /*
@@ -174,48 +106,24 @@ int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp)
                case PW_TYPE_ABINARY:
 #endif
                case PW_TYPE_OCTETS:
-                       if (vp->length != check->length) {
+                       if (request->length != check->length) {
                                ret = 1; /* NOT equal */
                                break;
                        }
-                       ret = memcmp(vp->vp_strvalue, check->vp_strvalue,
-                                    vp->length);
+                       ret = memcmp(request->strvalue, check->strvalue,
+                                       request->length);
                        break;
                case PW_TYPE_STRING:
-                       if (check->flags.caseless) {
-                               ret = strcasecmp((char *)vp->vp_strvalue,
-                                                (char *)check->vp_strvalue);
-                       } else {
-                               ret = strcmp((char *)vp->vp_strvalue,
-                                            (char *)check->vp_strvalue);
-                       }
+                       ret = strcmp((char *)request->strvalue,
+                                       (char *)check->strvalue);
                        break;
-               case PW_TYPE_BYTE:
-               case PW_TYPE_SHORT:
                case PW_TYPE_INTEGER:
-                       ret = vp->vp_integer - check->vp_integer;
-                       break;
                case PW_TYPE_DATE:
-                       ret = vp->vp_date - check->vp_date;
+                       ret = request->lvalue - check->lvalue;
                        break;
                case PW_TYPE_IPADDR:
-                       ret = ntohl(vp->vp_ipaddr) - ntohl(check->vp_ipaddr);
+                       ret = ntohl(request->lvalue) - ntohl(check->lvalue);
                        break;
-               case PW_TYPE_IPV6ADDR:
-                       ret = memcmp(&vp->vp_ipv6addr, &check->vp_ipv6addr,
-                                    sizeof(vp->vp_ipv6addr));
-                       break;
-
-               case PW_TYPE_IPV6PREFIX:
-                       ret = memcmp(&vp->vp_ipv6prefix, &check->vp_ipv6prefix,
-                                    sizeof(vp->vp_ipv6prefix));
-                       break;
-
-               case PW_TYPE_IFID:
-                       ret = memcmp(&vp->vp_ifid, &check->vp_ifid,
-                                    sizeof(vp->vp_ifid));
-                       break;
-
                default:
                        break;
        }
@@ -225,39 +133,6 @@ int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp)
 
 
 /*
- *     Compare 2 attributes. May call the attribute compare function.
- */
-int radius_callback_compare(REQUEST *req, VALUE_PAIR *request,
-                           VALUE_PAIR *check, VALUE_PAIR *check_pairs,
-                           VALUE_PAIR **reply_pairs)
-{
-       struct cmp *c;
-
-       /*
-        *      Check for =* and !* and return appropriately
-        */
-       if( check->operator == T_OP_CMP_TRUE )
-                return 0;  /* always return 0/EQUAL */
-       if( check->operator == T_OP_CMP_FALSE )
-                return 1;  /* always return 1/NOT EQUAL */
-
-       /*
-        *      See if there is a special compare function.
-        *
-        *      FIXME: use new RB-Tree code.
-        */
-       for (c = cmp; c; c = c->next)
-               if (c->attribute == check->attribute)
-                       return (c->compare)(c->instance, req, request, check,
-                               check_pairs, reply_pairs);
-
-       if (!request) return -1; /* doesn't exist, don't compare it */
-
-       return radius_compare_vps(req, check, request);
-}
-
-
-/*
  *     See what attribute we want to compare with.
  */
 static int otherattr(int attr)
@@ -293,6 +168,8 @@ int paircompare_register(int attr, int compare_attr, RAD_COMPARE_FUNC fun, void
 
        c = rad_malloc(sizeof(struct cmp));
 
+       if (compare_attr < 0)
+               compare_attr = attr;
        c->compare = fun;
        c->attribute = attr;
        c->otherattr = compare_attr;
@@ -334,13 +211,16 @@ void paircompare_unregister(int attr, RAD_COMPARE_FUNC fun)
  *
  *     Return 0 on match.
  */
-int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **reply)
+int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **reply)
 {
        VALUE_PAIR *check_item;
        VALUE_PAIR *auth_item;
        int result = 0;
        int compare;
        int other;
+#ifdef HAVE_REGEX_H
+       regex_t reg;
+#endif
 
        for (check_item = check; check_item != NULL; check_item = check_item->next) {
                /*
@@ -376,8 +256,8 @@ int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR
                         *
                         *      This hack makes CHAP-Password work..
                         */
-                       case PW_USER_PASSWORD:
-                               if (pairfind(request, PW_USER_PASSWORD) == NULL) {
+                       case PW_PASSWORD:
+                               if (pairfind(request, PW_PASSWORD) == NULL) {
                                        continue;
                                }
                                break;
@@ -390,11 +270,9 @@ int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR
 
                auth_item = request;
        try_again:
-               if (other >= 0) {
-                       for (; auth_item != NULL; auth_item = auth_item->next) {
-                               if (auth_item->attribute == other || other == 0)
-                                       break;
-                       }
+               for (; auth_item != NULL; auth_item = auth_item->next) {
+                       if (auth_item->attribute == other || other == 0)
+                               break;
                }
 
                /*
@@ -425,11 +303,11 @@ int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR
                 */
                if (check_item->flags.do_xlat) {
                        int rcode;
-                       char buffer[sizeof(check_item->vp_strvalue)];
+                       char buffer[sizeof(check_item->strvalue)];
 
                        check_item->flags.do_xlat = 0;
                        rcode = radius_xlat(buffer, sizeof(buffer),
-                                           check_item->vp_strvalue,
+                                           check_item->strvalue,
                                            req, NULL);
 
                        /*
@@ -441,13 +319,12 @@ int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR
                /*
                 *      OK it is present now compare them.
                 */
-               compare = radius_callback_compare(req, auth_item, check_item,
-                                                 check, reply);
+               compare = paircompare(req, auth_item, check_item, check, reply);
 
                switch (check_item->operator) {
                        case T_OP_EQ:
                        default:
-                               radlog(L_INFO,  "Invalid operator for item %s: "
+                               radlog(L_ERR,  "Invalid operator for item %s: "
                                                "reverting to '=='", check_item->name);
                                /*FALLTHRU*/
                        case T_OP_CMP_TRUE:    /* compare always == 0 */
@@ -478,17 +355,90 @@ int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR
 
 #ifdef HAVE_REGEX_H
                        case T_OP_REG_EQ:
+                       {
+                               int i;
+                               regmatch_t rxmatch[9];
+
+                               /*
+                                *      Include substring matches.
+                                */
+                               regcomp(&reg, (char *)check_item->strvalue,
+                                       REG_EXTENDED);
+                               compare = regexec(&reg,
+                                                 (char *)auth_item->strvalue,
+                                                 REQUEST_MAX_REGEX + 1,
+                                                 rxmatch, 0);
+                               regfree(&reg);
+
+                               /*
+                                *      Add %{0}, %{1}, etc.
+                                */
+                               for (i = 0; i <= REQUEST_MAX_REGEX; i++) {
+                                       char *p;
+                                       char buffer[sizeof(check_item->strvalue)];
+
+                                       /*
+                                        *      Didn't match: delete old
+                                        *      match, if it existed.
+                                        */
+                                       if ((compare != 0) ||
+                                           (rxmatch[i].rm_so == -1)) {
+                                               p = request_data_get(req, req,
+                                                                    REQUEST_DATA_REGEX | i);
+                                               if (p) {
+                                                       free(p);
+                                                       continue;
+                                               }
+
+                                               /*
+                                                *      No previous match
+                                                *      to delete, stop.
+                                                */
+                                               break;
+                                       }
+                                       
+                                       /*
+                                        *      Copy substring into buffer.
+                                        */
+                                       memcpy(buffer,
+                                              auth_item->strvalue + rxmatch[i].rm_so,
+                                              rxmatch[i].rm_eo - rxmatch[i].rm_so);
+                                       buffer[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0';
+
+                                       /*
+                                        *      Copy substring, and add it to
+                                        *      the request.
+                                        *
+                                        *      Note that we don't check
+                                        *      for out of memory, which is
+                                        *      the only error we can get...
+                                        */
+                                       p = strdup(buffer);
+                                       request_data_add(req,
+                                                        req,
+                                                        REQUEST_DATA_REGEX | i,
+                                                        p, free);
+                               }
+                       }                               
+                               if (compare != 0) result = -1;
+                               break;
+
                        case T_OP_REG_NE:
-                               result = compare;
+                               regcomp(&reg, (char *)check_item->strvalue, REG_EXTENDED|REG_NOSUB);
+                               compare = regexec(&reg, (char *)auth_item->strvalue,
+                                               0, NULL, 0);
+                               regfree(&reg);
+                               if (compare == 0) result = -1;
                                break;
 #endif
+
                } /* switch over the operator of the check item */
 
                /*
                 *      This attribute didn't match, but maybe there's
                 *      another of the same attribute, which DOES match.
                 */
-               if ((result != 0) && (other >= 0)) {
+               if (result != 0) {
                        auth_item = auth_item->next;
                        result = 0;
                        goto try_again;
@@ -496,10 +446,309 @@ int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR
 
        } /* for every entry in the check item list */
 
-       return result;
+       return 0;               /* it matched */
 }
 
 /*
+ *      Compare two attributes simply.  Calls paircompare.
+ */
+
+int simplepaircmp(REQUEST *req, VALUE_PAIR *first, VALUE_PAIR *second)
+{
+       return paircompare( req, first, second, NULL, NULL );
+}
+
+
+/*
+ *     Compare a Connect-Info and a Connect-Rate
+ */
+static int connectcmp(void *instance,
+                     REQUEST *req UNUSED,
+                     VALUE_PAIR *request,
+                     VALUE_PAIR *check,
+                     VALUE_PAIR *check_pairs,
+                     VALUE_PAIR **reply_pairs)
+{
+       int rate;
+
+       instance = instance;
+       check_pairs = check_pairs; /* shut the compiler up */
+       reply_pairs = reply_pairs;
+
+       rate = atoi((char *)request->strvalue);
+       return rate - check->lvalue;
+}
+
+
+/*
+ *     Compare a portno with a range.
+ */
+static int portcmp(void *instance,
+                  REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check,
+       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
+{
+       char buf[MAX_STRING_LEN];
+       char *s, *p;
+       uint32_t lo, hi;
+       uint32_t port = request->lvalue;
+
+       instance = instance;
+       check_pairs = check_pairs; /* shut the compiler up */
+       reply_pairs = reply_pairs;
+
+       if ((strchr((char *)check->strvalue, ',') == NULL) &&
+                       (strchr((char *)check->strvalue, '-') == NULL)) {
+               return (request->lvalue - check->lvalue);
+       }
+
+       /* Same size */
+       strcpy(buf, (char *)check->strvalue);
+       s = strtok(buf, ",");
+
+       while (s != NULL) {
+               if ((p = strchr(s, '-')) != NULL)
+                       p++;
+               else
+                       p = s;
+               lo = strtoul(s, NULL, 10);
+               hi = strtoul(p, NULL, 10);
+               if (lo <= port && port <= hi) {
+                       return 0;
+               }
+               s = strtok(NULL, ",");
+       }
+
+       return -1;
+}
+
+/*
+ *     Compare prefix/suffix.
+ *
+ *     If they compare:
+ *     - if PW_STRIP_USER_NAME is present in check_pairs,
+ *       strip the username of prefix/suffix.
+ *     - if PW_STRIP_USER_NAME is not present in check_pairs,
+ *       add a PW_STRIPPED_USER_NAME to the request.
+ */
+static int presufcmp(void *instance,
+                    REQUEST *req UNUSED,
+                    VALUE_PAIR *request, VALUE_PAIR *check,
+       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
+{
+       VALUE_PAIR *vp;
+       char *name = (char *)request->strvalue;
+       char rest[MAX_STRING_LEN];
+       int len, namelen;
+       int ret = -1;
+
+       instance = instance;
+       reply_pairs = reply_pairs; /* shut the compiler up */
+
+#if 0 /* DEBUG */
+       printf("Comparing %s and %s, check->attr is %d\n",
+               name, check->strvalue, check->attribute);
+#endif
+
+       len = strlen((char *)check->strvalue);
+       switch (check->attribute) {
+               case PW_PREFIX:
+                       ret = strncmp(name, (char *)check->strvalue, len);
+                       if (ret == 0 && rest)
+                               strcpy(rest, name + len);
+                       break;
+               case PW_SUFFIX:
+                       namelen = strlen(name);
+                       if (namelen < len)
+                               break;
+                       ret = strcmp(name + namelen - len,
+                                       (char *)check->strvalue);
+                       if (ret == 0 && rest) {
+                               strNcpy(rest, name, namelen - len + 1);
+                       }
+                       break;
+       }
+       if (ret != 0)
+               return ret;
+
+       if ((vp = pairfind(check_pairs, PW_STRIP_USER_NAME)) != NULL) {
+               if (vp->lvalue == 1) {
+                       /*
+                        *      I don't think we want to update the User-Name
+                        *      attribute in place... - atd
+                        */
+                       strcpy((char *)request->strvalue, rest);
+                       request->length = strlen(rest);
+               } else {
+                       return ret;
+               }
+       } else {
+               if ((vp = pairfind(check_pairs, PW_STRIPPED_USER_NAME)) != NULL){
+                       strcpy((char *)vp->strvalue, rest);
+                       vp->length = strlen(rest);
+               } else if ((vp = paircreate(PW_STRIPPED_USER_NAME,
+                               PW_TYPE_STRING)) != NULL) {
+                       strcpy((char *)vp->strvalue, rest);
+                       vp->length = strlen(rest);
+                       pairadd(&request, vp);
+               } /* else no memory! Die, die!: FIXME!! */
+       }
+
+       return ret;
+}
+
+
+/*
+ *     Compare the current time to a range.
+ */
+static int timecmp(void *instance,
+                  REQUEST *req UNUSED,
+                  VALUE_PAIR *request, VALUE_PAIR *check,
+       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
+{
+       instance = instance;
+       request = request;      /* shut the compiler up */
+       check_pairs = check_pairs;
+       reply_pairs = reply_pairs;
+
+       if (timestr_match((char *)check->strvalue,
+                         req ? req->timestamp : time(NULL)) >= 0) {
+               return 0;
+       }
+       return -1;
+}
+
+/*
+ *     Matches if there is NO SUCH ATTRIBUTE as the one named
+ *     in check->strvalue.  If there IS such an attribute, it
+ *     doesn't match.
+ *
+ *     This is ugly, and definitely non-optimal.  We should be
+ *     doing the lookup only ONCE, and storing the result
+ *     in check->lvalue...
+ */
+static int attrcmp(void *instance,
+                  REQUEST *req UNUSED,
+                  VALUE_PAIR *request, VALUE_PAIR *check,
+                  VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
+{
+       VALUE_PAIR *pair;
+       DICT_ATTR  *dict;
+       int attr;
+
+       instance = instance;
+       check_pairs = check_pairs; /* shut the compiler up */
+       reply_pairs = reply_pairs;
+
+       if (check->lvalue == 0) {
+               dict = dict_attrbyname((char *)check->strvalue);
+               if (dict == NULL) {
+                       return -1;
+               }
+               attr = dict->attr;
+       } else {
+               attr = check->lvalue;
+       }
+
+       /*
+        *      If there's no such attribute, then return MATCH,
+        *      else FAILURE.
+        */
+       pair = pairfind(request, attr);
+       if (pair == NULL) {
+               return 0;
+       }
+
+       return -1;
+}
+
+/*
+ *     Compare the expiration date.
+ */
+static int expirecmp(void *instance, REQUEST *req UNUSED,
+                    VALUE_PAIR *request, VALUE_PAIR *check,
+                    VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
+{
+       time_t now;
+
+       instance = instance;
+       request = request;      /* shut the compiler up */
+       check_pairs = check_pairs;
+       reply_pairs = reply_pairs;
+
+       /*
+        *  FIXME!  This should be request->timestamp!
+        */
+       now = time(NULL);
+
+       if (now <= (signed)check->lvalue) {
+               return 0;
+       }
+
+       return +1;
+}
+
+/*
+ *     Compare the request packet type.
+ */
+static int packetcmp(void *instance UNUSED, REQUEST *req,
+                    VALUE_PAIR *request UNUSED,
+                    VALUE_PAIR *check,
+                    VALUE_PAIR *check_pairs UNUSED,
+                    VALUE_PAIR **reply_pairs UNUSED)
+{
+       if (req->packet->code == check->lvalue) {
+               return 0;
+       }
+
+       return 1;
+}
+
+/*
+ *     Compare the response packet type.
+ */
+static int responsecmp(void *instance UNUSED,
+                      REQUEST *req,
+                      VALUE_PAIR *request UNUSED,
+                      VALUE_PAIR *check,
+                      VALUE_PAIR *check_pairs UNUSED,
+                      VALUE_PAIR **reply_pairs UNUSED)
+{
+       if (req->reply->code == check->lvalue) {
+               return 0;
+       }
+
+       return 1;
+}
+
+/*
+ *     Register server-builtin special attributes.
+ */
+void pair_builtincompare_init(void)
+{
+       paircompare_register(PW_NAS_PORT, -1, portcmp, NULL);
+       paircompare_register(PW_PREFIX, PW_USER_NAME, presufcmp, NULL);
+       paircompare_register(PW_SUFFIX, PW_USER_NAME, presufcmp, NULL);
+       paircompare_register(PW_CONNECT_RATE, PW_CONNECT_INFO, connectcmp, NULL);
+       paircompare_register(PW_CURRENT_TIME, 0, timecmp, NULL);
+       paircompare_register(PW_NO_SUCH_ATTRIBUTE, 0, attrcmp, NULL);
+       paircompare_register(PW_EXPIRATION, 0, expirecmp, NULL);
+       paircompare_register(PW_PACKET_TYPE, 0, packetcmp, NULL);
+       paircompare_register(PW_RESPONSE_PACKET_TYPE, 0, responsecmp, NULL);
+}
+
+void paircompare_builtin_free(void)
+{
+       struct cmp *c, *next;
+       
+       for (c = cmp; c != NULL; c = next) {
+               next = c->next;
+               free(c);
+       }
+}
+
+
+
+/*
  *     Move pairs, replacing/over-writing them, and doing xlat.
  */
 /*
@@ -539,11 +788,11 @@ void pairxlatmove(REQUEST *req, VALUE_PAIR **to, VALUE_PAIR **from)
                 */
                if (i->flags.do_xlat) {
                        int rcode;
-                       char buffer[sizeof(i->vp_strvalue)];
+                       char buffer[sizeof(i->strvalue)];
 
                        i->flags.do_xlat = 0;
                        rcode = radius_xlat(buffer, sizeof(buffer),
-                                           i->vp_strvalue,
+                                           i->strvalue,
                                            req, NULL);
 
                        /*
@@ -561,9 +810,9 @@ void pairxlatmove(REQUEST *req, VALUE_PAIR **to, VALUE_PAIR **from)
                         */
                case T_OP_SUB:          /* -= */
                        if (found) {
-                               if (!i->vp_strvalue[0] ||
-                                   (strcmp((char *)found->vp_strvalue,
-                                           (char *)i->vp_strvalue) == 0)){
+                               if (!i->strvalue[0] ||
+                                   (strcmp((char *)found->strvalue,
+                                           (char *)i->strvalue) == 0)){
                                        pairdelete(to, found->attribute);
 
                                        /*
@@ -642,28 +891,3 @@ void pairxlatmove(REQUEST *req, VALUE_PAIR **to, VALUE_PAIR **from)
                }
        } /* loop over the 'from' list */
 }
-
-/*
- *     Create a pair, and add it to a particular list of VPs
- *
- *     Note that this function ALWAYS returns.  If we're OOM, then
- *     it causes the server to exit!
- */
-VALUE_PAIR *radius_paircreate(REQUEST *request, VALUE_PAIR **vps,
-                             int attribute, int type)
-{
-       VALUE_PAIR *vp;
-
-       request = request;      /* -Wunused */
-
-       vp = paircreate(attribute, type);
-       if (!vp) {
-               radlog(L_ERR, "No memory!");
-               rad_assert("No memory" == NULL);
-               _exit(1);
-       }
-
-       pairadd(vps, vp);
-
-       return vp;
-}
index a66b1c8..272bba0 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2000  Chris Parker <cparker@starnetusa.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/radiusd.h>
+#include "autoconf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "radiusd.h"
 
 /*
  *     Display the revision number for this program
index f2528ed..7a11c41 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] =
+"$Id$";
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
 #include       <ctype.h>
 
+#include       "radiusd.h"
+
+#include       "rad_assert.h"
+
 typedef struct xlat_t {
        char            module[MAX_STRING_LEN];
        int             length;
@@ -43,17 +50,17 @@ static rbtree_t *xlat_root = NULL;
 /*
  *     Define all xlat's in the structure.
  */
-static const char * const internal_xlat[] = {"check",
-                                            "request",
-                                            "reply",
-                                            "proxy-request",
-                                            "proxy-reply",
-                                            NULL};
+static const char *internal_xlat[] = {"check",
+                                     "request",
+                                     "reply",
+                                     "proxy-request",
+                                     "proxy-reply",
+                                     NULL};
 
 #if REQUEST_MAX_REGEX > 8
 #error Please fix the following line
 #endif
-static const int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };  /* up to 8 for regex */
+static int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };        /* up to 8 for regex */
 
 
 /*
@@ -65,28 +72,25 @@ static int valuepair2str(char * out,int outlen,VALUE_PAIR * pair,
        char buffer[MAX_STRING_LEN * 4];
 
        if (pair != NULL) {
-               vp_prints_value(buffer, sizeof(buffer), pair, -1);
+               vp_prints_value(buffer, sizeof(buffer), pair, 0);
                return func(out, outlen, buffer);
        }
 
        switch (type) {
        case PW_TYPE_STRING :
-               strlcpy(out,"_",outlen);
+               strNcpy(out,"_",outlen);
                break;
        case PW_TYPE_INTEGER :
-               strlcpy(out,"0",outlen);
+               strNcpy(out,"0",outlen);
                break;
        case PW_TYPE_IPADDR :
-               strlcpy(out,"?.?.?.?",outlen);
-               break;
-       case PW_TYPE_IPV6ADDR :
-               strlcpy(out,":?:",outlen);
+               strNcpy(out,"?.?.?.?",outlen);
                break;
        case PW_TYPE_DATE :
-               strlcpy(out,"0",outlen);
+               strNcpy(out,"0",outlen);
                break;
        default :
-               strlcpy(out,"unknown_type",outlen);
+               strNcpy(out,"unknown_type",outlen);
        }
        return strlen(out);
 }
@@ -145,55 +149,14 @@ static int xlat_packet(void *instance, REQUEST *request,
                if (!p) return 0;
                if (strlen(fmt) > sizeof(buffer)) return 0;
 
-               strlcpy(buffer, fmt, p - fmt + 1);
-
-               da = dict_attrbyname(buffer);
-               if (!da) return 0;
-
-               /*
-                *      %{Attribute-Name[#]} returns the count of
-                *      attributes of that name in the list.
-                */
-               if ((p[1] == '#') && (p[2] == ']')) {
-                       count = 0;
-
-                       for (vp = pairfind(vps, da->attr);
-                            vp != NULL;
-                            vp = pairfind(vp->next, da->attr)) {
-                               count++;
-                       }
-                       snprintf(out, outlen, "%d", count);
-                       return strlen(out);
-               }
-
-               /*
-                *      %{Attribute-Name[*]} returns ALL of the
-                *      the attributes, separated by a newline.
-                */
-               if ((p[1] == '*') && (p[2] == ']')) {
-                       int total = 0;
-
-                       for (vp = pairfind(vps, da->attr);
-                            vp != NULL;
-                            vp = pairfind(vp->next, da->attr)) {
-                               count = valuepair2str(out, outlen - 1, vp, da->type, func);
-                               rad_assert(count <= outlen);
-                               total += count + 1;
-                               outlen -= (count + 1);
-                               out += count;
-
-                               *(out++) = '\n';
-
-                               if (outlen == 0) break;
-                       }
-
-                       return total;
-               }
+               strNcpy(buffer, fmt, p - fmt + 1);
 
                count = atoi(p + 1);
 
                /*
-                *      Skip the numbers.
+                *      Check the format of the index before looking
+                *      the attribute up in the dictionary, because
+                *      it's a cheap check.
                 */
                p += 1 + strspn(p + 1, "0123456789");
                if (*p != ']') {
@@ -202,6 +165,10 @@ static int xlat_packet(void *instance, REQUEST *request,
                        return 0;
                }
 
+               da = dict_attrbyname(buffer);
+               if (!da) return 0;
+
+
                /*
                 *      Find the N'th value.
                 */
@@ -226,19 +193,14 @@ static int xlat_packet(void *instance, REQUEST *request,
                 *      Some "magic" handlers, which are never in VP's, but
                 *      which are in the packet.
                 *
-                *      FIXME: We should really do this in a more
-                *      intelligent way...
+                *      FIXME: Add SRC/DST IP address!
                 */
                if (packet) {
-                       VALUE_PAIR localvp;
-
-                       localvp.vp_strvalue[0] = 0;
-
                        switch (da->attr) {
                        case PW_PACKET_TYPE:
                        {
                                DICT_VALUE *dval;
-
+                               
                                dval = dict_valbyattr(da->attr, packet->code);
                                if (dval) {
                                        snprintf(out, outlen, "%s", dval->name);
@@ -248,87 +210,10 @@ static int xlat_packet(void *instance, REQUEST *request,
                                return strlen(out);
                        }
                        break;
-
-                       case PW_CLIENT_IP_ADDRESS: /* the same as below */
-                       case PW_PACKET_SRC_IP_ADDRESS:
-                               if (packet->src_ipaddr.af != AF_INET) {
-                                       return 0;
-                               }
-                               localvp.attribute = da->attr;
-                               localvp.vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
-                               break;
-
-                       case PW_PACKET_DST_IP_ADDRESS:
-                               if (packet->dst_ipaddr.af != AF_INET) {
-                                       return 0;
-                               }
-                               localvp.attribute = da->attr;
-                               localvp.vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
-                               break;
-
-                       case PW_PACKET_SRC_PORT:
-                               localvp.attribute = da->attr;
-                               localvp.vp_integer = packet->src_port;
-                               break;
-
-                       case PW_PACKET_DST_PORT:
-                               localvp.attribute = da->attr;
-                               localvp.vp_integer = packet->dst_port;
-                               break;
-
-                       case PW_PACKET_AUTHENTICATION_VECTOR:
-                               localvp.attribute = da->attr;
-                               memcpy(localvp.vp_strvalue, packet->vector,
-                                      sizeof(packet->vector));
-                               localvp.length = sizeof(packet->vector);
-                               break;
-
-                               /*
-                                *      Authorization, accounting, etc.
-                                */
-                       case PW_REQUEST_PROCESSING_STAGE:
-                               if (request->component) {
-                                       strlcpy(out, request->component, outlen);
-                               } else {
-                                       strlcpy(out, "server_core", outlen);
-                               }
-                               return strlen(out);
-
-                       case PW_PACKET_SRC_IPV6_ADDRESS:
-                               if (packet->src_ipaddr.af != AF_INET6) {
-                                       return 0;
-                               }
-                               localvp.attribute = da->attr;
-                               memcpy(localvp.vp_strvalue,
-                                      &packet->src_ipaddr.ipaddr.ip6addr,
-                                      sizeof(packet->src_ipaddr.ipaddr.ip6addr));
-                               break;
-
-                       case PW_PACKET_DST_IPV6_ADDRESS:
-                               if (packet->dst_ipaddr.af != AF_INET6) {
-                                       return 0;
-                               }
-                               localvp.attribute = da->attr;
-                               memcpy(localvp.vp_strvalue,
-                                      &packet->dst_ipaddr.ipaddr.ip6addr,
-                                      sizeof(packet->dst_ipaddr.ipaddr.ip6addr));
-                               break;
-
-                       case PW_SERVER_IDENTITY:
-                               if (!request->listener || !request->listener->identity) return 0;
-
-                               snprintf(out, outlen, "%s", request->listener->identity);
-                               return strlen(out);
-                               break;
-
+                       
                        default:
-                               return 0; /* not found */
                                break;
                        }
-
-                       localvp.type = da->type;
-                       return valuepair2str(out, outlen, &localvp,
-                                            da->type, func);
                }
 
                /*
@@ -361,8 +246,8 @@ static int xlat_regex(void *instance, REQUEST *request,
         */
        fmt = fmt;              /* -Wunused */
        func = func;            /* -Wunused FIXME: do escaping? */
-
-       regex = request_data_reference(request, request,
+       
+       regex = request_data_get(request, request,
                                 REQUEST_DATA_REGEX | *(int *)instance);
        if (!regex) return 0;
 
@@ -370,12 +255,12 @@ static int xlat_regex(void *instance, REQUEST *request,
         *      Copy UP TO "freespace" bytes, including
         *      a zero byte.
         */
-       strlcpy(out, regex, outlen);
+       strNcpy(out, regex, outlen);
+       free(regex); /* was strdup'd */
        return strlen(out);
 }
 #endif                         /* HAVE_REGEX_H */
 
-
 /*
  *     Compare two xlat_t structs, based ONLY on the module name.
  */
@@ -394,27 +279,20 @@ static int xlat_cmp(const void *a, const void *b)
 /*
  *     find the appropriate registered xlat function.
  */
-static const xlat_t *xlat_find(const char *module)
+static xlat_t *xlat_find(const char *module)
 {
+       char *p;
        xlat_t my_xlat;
 
+       strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
+
        /*
-        *      Look for dictionary attributes first.
+        *      We get passed the WHOLE string, and all we want here
+        *      is the first piece.
         */
-       if ((dict_attrbyname(module) != NULL) ||
-           (strchr(module, '[') != NULL)) {
-               static const xlat_t dict_xlat = {
-                       "request",
-                       7,
-                       &xlat_inst[1],
-                       xlat_packet,
-                       TRUE
-               };
-
-               return &dict_xlat;
-       }
+       p = strchr(my_xlat.module, ':');
+       if (p) *p = '\0';
 
-       strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
        my_xlat.length = strlen(my_xlat.module);
 
        return rbtree_finddata(xlat_root, &my_xlat);
@@ -480,7 +358,7 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
        /*
         *      If it already exists, replace the instance.
         */
-       strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
+       strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
        my_xlat.length = strlen(my_xlat.module);
        c = rbtree_finddata(xlat_root, &my_xlat);
        if (c) {
@@ -501,7 +379,7 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
        memset(c, 0, sizeof(*c));
 
        c->do_xlat = func;
-       strlcpy(c->module, module, sizeof(c->module));
+       strNcpy(c->module, module, sizeof(c->module));
        c->length = strlen(c->module);
        c->instance = instance;
 
@@ -523,9 +401,7 @@ void xlat_unregister(const char *module, RAD_XLAT_FUNC func)
 
        func = func;            /* -Wunused */
 
-       if (!module) return;
-
-       strlcpy(my_xlat.module, module, sizeof(my_xlat.module));
+       strNcpy(my_xlat.module, module, sizeof(my_xlat.module));
        my_xlat.length = strlen(my_xlat.module);
 
        node = rbtree_find(xlat_root, &my_xlat);
@@ -534,6 +410,7 @@ void xlat_unregister(const char *module, RAD_XLAT_FUNC func)
        rbtree_delete(xlat_root, node);
 }
 
+
 /*
  *     De-register all xlat functions,
  *     used mainly for debugging.
@@ -548,23 +425,20 @@ void xlat_free(void)
  *     Decode an attribute name into a string.
  */
 static void decode_attribute(const char **from, char **to, int freespace,
-                            int *open_p, REQUEST *request,
+                            int *open, REQUEST *request,
                             RADIUS_ESCAPE_STRING func)
 {
-       int     do_length = 0;
-       char    xlat_name[128];
-       char    *xlat_string = NULL; /* can be large */
-       int     free_xlat_string = FALSE;
+       char attrname[4096];
        const char *p;
        char *q, *pa;
-       int found=0, retlen=0;
-       int openbraces = *open_p;
-       const xlat_t *c;
-       int spaces = FALSE;
+       int stop=0, found=0, retlen=0;
+       int openbraces = *open;
+       xlat_t *c;
+       size_t namelen = sizeof(attrname);
 
        p = *from;
        q = *to;
-       pa = &xlat_name[0];
+       pa = &attrname[0];
 
        *q = '\0';
 
@@ -575,99 +449,19 @@ static void decode_attribute(const char **from, char **to, int freespace,
        p++;
        openbraces++;
 
-       if (*p == '#') {
-               p++;
-               do_length = 1;
-       }
-
        /*
-        *      First, copy the xlat key name to one buffer
+        *  Copy over the rest of the string.
         */
-       while (*p && (*p != '}') && (*p != ':')) {
-               *pa++ = *p++;
-
-               if (pa >= (xlat_name + sizeof(xlat_name) - 1)) {
+       while ((*p) && (!stop) && (namelen > 1)) {
+               switch(*p) {
                        /*
-                        *      Skip to the end of the input
+                        *  Allow braces inside things, too.
                         */
-                       p += strlen(p);
-                       DEBUG("xlat: Module name is too long in string %%%s",
-                             *from);
-                       goto done;
-               }
-       }
-       *pa = '\0';
-
-       if (!*p) {
-               DEBUG("xlat: Invalid syntax in %s", *from);
-
-               /*
-                *      %{name} is a simple attribute reference,
-                *      or regex reference.
-                */
-       } else if (*p == '}') {
-               openbraces--;
-               rad_assert(openbraces == *open_p);
-
-               p++;
-               xlat_string = xlat_name;
-               goto do_xlat;
-
-       } else if (p[1] == '-') { /* handle ':- */
-               p += 2;
-               xlat_string = xlat_name;
-               goto do_xlat;
-
-       } else {      /* module name, followed by per-module string */
-               int stop = 0;
-               int delimitbrace = *open_p;
-
-               rad_assert(*p == ':');
-               p++;                    /* skip the ':' */
-
-               /*
-                *  If there's a brace immediately following the colon,
-                *  then we've chosen to delimite the per-module string,
-                *  so keep track of that.
-                */
-               if (*p == '{') {
-                       delimitbrace = openbraces;
-                       openbraces++;
-                       p++;
-               }
-
-               xlat_string = rad_malloc(strlen(p) + 1); /* always returns */
-               free_xlat_string = TRUE;
-               pa = xlat_string;
-
-               /*
-                *  Copy over the rest of the string, which is per-module
-                *  data.
-                */
-               while (*p && !stop) {
-                       switch(*p) {
-
-                               /*
-                                *      What the heck is this supposed
-                                *      to be doing?
-                                */
                        case '\\':
                                p++; /* skip it */
                                *pa++ = *p++;
                                break;
 
-                       case ':':
-                               if (!spaces && p[1] == '-') {
-                                       p += 2;
-                                       stop = 1;
-                                       break;
-                               }
-
-                               /*
-                                *      This is pretty hokey...  we
-                                *      should use the functions in
-                                *      util.c
-                                */
                        case '{':
                                openbraces++;
                                *pa++ = *p++;
@@ -675,7 +469,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
 
                        case '}':
                                openbraces--;
-                               if (openbraces == delimitbrace) {
+                               if (openbraces == *open) {
                                        p++;
                                        stop=1;
                                } else {
@@ -683,50 +477,65 @@ static void decode_attribute(const char **from, char **to, int freespace,
                                }
                                break;
 
-                       case ' ':
-                       case '\t':
-                               spaces = TRUE;
-                               /* FALL-THROUGH */
+                               /*
+                                *  Attr-Name1:-Attr-Name2
+                                *
+                                *  Use Attr-Name1, and if not found,
+                                *  use Attr-Name2.
+                                */
+                       case ':':
+                               if (p[1] == '-') {
+                                       p += 2;
+                                       stop = 1;
+                                       break;
+                               }
+                               /* else FALL-THROUGH */
 
                        default:
                                *pa++ = *p++;
                                break;
-                       }
                }
+               namelen--;
+       }
+       *pa = '\0';
 
-               *pa = '\0';
+       /*
+        *      Look up almost everything in the new tree of xlat
+        *      functions.  this makes it a little quicker...
+        */
+       if ((c = xlat_find(attrname)) != NULL) {
+               if (!c->internal) DEBUG("radius_xlat: Running registered xlat function of module %s for string \'%s\'",
+                                       c->module, attrname+ c->length + 1);
+               retlen = c->do_xlat(c->instance, request, attrname+(c->length+1), q, freespace, func);
+               /* If retlen is 0, treat it as not found */
+               if (retlen == 0) {
+                       found = 0;
+               } else {
+                       found = 1;
+                       q += retlen;
+               }
 
                /*
-                *      Now check to see if we're at the end of the string
-                *      we were sent.  If we're not, check for :-
+                *      Not in the default xlat database.  Must be
+                *      a bare attribute number.
                 */
-               if (openbraces == delimitbrace) {
-                       if (p[0] == ':' && p[1] == '-') {
-                               p += 2;
-                       }
-               }
+       } else if ((retlen = xlat_packet(&xlat_inst[1], request, attrname,
+                                        q, freespace, func)) > 0) {
+               found = 1;
+               q += retlen;
 
                /*
-                *      Look up almost everything in the new tree of xlat
-                *      functions.  This makes it a little quicker...
+                *      Look up the name, in order to get the correct
+                *      debug message.
                 */
-       do_xlat:
-               if ((c = xlat_find(xlat_name)) != NULL) {
-                       if (!c->internal) DEBUG("radius_xlat: Running registered xlat function of module %s for string \'%s\'",
-                                               c->module, xlat_string);
-                       retlen = c->do_xlat(c->instance, request, xlat_string,
-                                           q, freespace, func);
-                       /* If retlen is 0, treat it as not found */
-                       if (retlen > 0) found = 1;
 #ifndef NDEBUG
-               } else {
-                       /*
-                        *      No attribute by that name, return an error.
-                        */
-                       DEBUG2("WARNING: Unknown module \"%s\" in string expansion \"%%%s\"", xlat_name, *from);
+       } else if (dict_attrbyname(attrname) == NULL) {
+               /*
+                *      No attribute by that name, return an error.
+                */
+               DEBUG2("WARNING: Attempt to use unknown xlat function, or non-existent attribute in string %%{%s}", attrname);
 #endif
-               }
-       }
+       } /* else the attribute is known, but not in the request */
 
        /*
         * Skip to last '}' if attr is found
@@ -734,14 +543,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
         * useless if we found what we need
         */
        if (found) {
-               if (do_length) {
-                       snprintf(q, freespace, "%d", retlen);
-                       retlen = strlen(q);
-               }
-
-               q += retlen;
-
-               while((*p != '\0') && (openbraces > *open_p)) {
+               while((*p != '\0') && (openbraces > *open)) {
                        /*
                         *      Handle escapes outside of the loop.
                         */
@@ -771,10 +573,7 @@ static void decode_attribute(const char **from, char **to, int freespace,
                }
        }
 
-       done:
-       if (free_xlat_string) free(xlat_string);
-
-       *open_p = openbraces;
+       *open = openbraces;
        *from = p;
        *to = q;
 }
@@ -834,7 +633,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                func = xlat_copy;
        }
 
-               q = out;
+       q = out;
        p = fmt;
        while (*p) {
                /* Calculate freespace in output */
@@ -921,7 +720,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%d", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
@@ -936,8 +735,8 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                break;
                        case 'l': /* request timestamp */
                                snprintf(tmpdt, sizeof(tmpdt), "%lu",
-                                        (unsigned long) request->received.tv_sec);
-                               strlcpy(q,tmpdt,freespace);
+                                        (unsigned long) request->timestamp);
+                               strNcpy(q,tmpdt,freespace);
                                q += strlen(q);
                                p++;
                                break;
@@ -945,7 +744,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%m", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
@@ -966,7 +765,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                CTIME_R(&request->timestamp, tmpdt, sizeof(tmpdt));
                                nl = strchr(tmpdt, '\n');
                                if (nl) *nl = '\0';
-                               strlcpy(q, tmpdt, freespace);
+                               strNcpy(q, tmpdt, freespace);
                                q += strlen(q);
                                p++;
                                break;
@@ -975,12 +774,12 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'A': /* radacct_dir */
-                               strlcpy(q,radacct_dir,freespace);
+                               strNcpy(q,radacct_dir,freespace-1);
                                q += strlen(q);
                                p++;
                                break;
                        case 'C': /* ClientName */
-                               strlcpy(q,client_name_old(&request->packet->src_ipaddr),freespace);
+                               strNcpy(q,client_name(request->packet->src_ipaddr),freespace-1);
                                q += strlen(q);
                                p++;
                                break;
@@ -988,7 +787,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%Y%m%d", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
@@ -997,13 +796,13 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%H", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
                                break;
                        case 'L': /* radlog_dir */
-                               strlcpy(q,radlog_dir,freespace);
+                               strNcpy(q,radlog_dir,freespace-1);
                                q += strlen(q);
                                p++;
                                break;
@@ -1012,7 +811,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'R': /* radius_dir */
-                               strlcpy(q,radius_dir,freespace);
+                               strNcpy(q,radius_dir,freespace-1);
                                q += strlen(q);
                                p++;
                                break;
@@ -1020,7 +819,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d %H:%M:%S", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
@@ -1029,7 +828,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d-%H.%M.%S.000000", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
@@ -1039,7 +838,10 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'V': /* Request-Authenticator */
-                               strlcpy(q,"Verified",freespace);
+                               if (request->packet->verified)
+                                       strNcpy(q,"Verified",freespace-1);
+                               else
+                                       strNcpy(q,"None",freespace-1);
                                q += strlen(q);
                                p++;
                                break;
@@ -1047,7 +849,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                TM = localtime_r(&request->timestamp, &s_TM);
                                len = strftime(tmpdt, sizeof(tmpdt), "%Y", TM);
                                if (len > 0) {
-                                       strlcpy(q, tmpdt, freespace);
+                                       strNcpy(q, tmpdt, freespace);
                                        q += strlen(q);
                                }
                                p++;
@@ -1055,7 +857,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                        case 'Z': /* Full request pairs except password */
                                tmp = request->packet->vps;
                                while (tmp && (freespace > 3)) {
-                                       if (tmp->attribute != PW_USER_PASSWORD) {
+                                       if (tmp->attribute != PW_PASSWORD) {
                                                *q++ = '\t';
                                                len = vp_prints(q, freespace - 2, tmp);
                                                q += len;
index 691ca40..6b3ac7c 100644 (file)
@@ -38,7 +38,7 @@ reconfig:
                 if grep AC_CONFIG_HEADERS configure.in >/dev/null; then\
                        $(AUTOHEADER); \
                 fi; \
-               )  || exit $$?; \
+               ) || exit $$?; \
        done
 
 common:
index 2d3f014..46e1375 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include <ctype.h>
+#include "radiusd.h"
+#include "modules.h"
 
 /*
  *  Room for at least 16 attributes.
  */
 #define  BUFFERLEN  4096
 
+static const char rcsid[] = "$Id$";
+
 typedef struct rlm_acct_unique_list_t {
        DICT_ATTR                     *dattr;
        struct rlm_acct_unique_list_t *next;
@@ -41,7 +45,7 @@ typedef struct rlm_acct_unique_t {
        rlm_acct_unique_list_t *head;
 } rlm_acct_unique_t;
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "key",  PW_TYPE_STRING_PTR, offsetof(rlm_acct_unique_t,key), NULL,  NULL },
   { NULL, -1, 0, NULL, NULL }    /* end the list */
 };
@@ -71,21 +75,14 @@ static int unique_parse_key(rlm_acct_unique_t *inst, char *key)
        char *ptr, *prev, *keyptr;
        DICT_ATTR *a;
 
+       keyptr = key;
+       ptr = key;
        prev = key;
-       keyptr = ptr = key;
 
        /* Let's remove spaces in the string */
-       while (*keyptr) {
-               if (isspace((int) *keyptr)) {
-                       keyptr++;
-               } else {
-                       *(ptr++) = *(keyptr++);
-               }
-       }
-       *ptr = '\0';
+       rad_rmspace(key);
 
-
-       keyptr = ptr = key;
+       ptr = key;
        while(ptr) {
                switch(*ptr) {
                case ',':
@@ -124,6 +121,7 @@ static int unique_detach(void *instance)
        rlm_acct_unique_t *inst = instance;
        rlm_acct_unique_list_t *this, *next;
 
+       free(inst->key);
        for (this = inst->head; this != NULL; this = next) {
                next = this->next;
                free(this);
@@ -236,11 +234,10 @@ static int add_unique_id(void *instance, REQUEST *request)
 
 /* globally exported name */
 module_t rlm_acct_unique = {
-       RLM_MODULE_INIT,
        "Acct-Unique-Session-Id",
        0,                              /* type: reserved */
+       NULL,                           /* initialization */
        unique_instantiate,             /* instantiation */
-       unique_detach,          /* detach */
        {
                NULL,                   /* authentication */
                add_unique_id,  /* authorization */
@@ -251,4 +248,6 @@ module_t rlm_acct_unique = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       unique_detach,          /* detach */
+       NULL,                           /* destroy */
 };
diff --git a/src/modules/rlm_acctlog/Makefile.in b/src/modules/rlm_acctlog/Makefile.in
deleted file mode 100644 (file)
index a39c006..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-TARGET      = @targetname@
-SRCS        = rlm_acctlog.c
-RLM_CFLAGS  = @acctlog_cflags@
-RLM_LIBS    = @acctlog_ldflags@
-
-include ../rules.mak
-
-$(LT_OBJS): $(HEADERS)
-
-install-example:
-       touch .
diff --git a/src/modules/rlm_acctlog/configure.in b/src/modules/rlm_acctlog/configure.in
deleted file mode 100644 (file)
index fc92aaa..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-AC_PREREQ([2.53])
-AC_INIT(rlm_acctlog.c)
-AC_REVISION(0.1)
-AC_DEFUN(modname,[rlm_acctlog])
-
-if test x$with_[]modname != xno; then
-
-       AC_PROG_CC
-       AC_PROG_CPP
-
-       AC_CHECK_HEADER(stdio.h,
-               [ slog_cflags="$acctlog_cflags -I/usr/include" ],
-               [ fail=$fail" stdio.h" ]
-       )
-
-       targetname=modname
-else
-       targetname=
-       echo \*\*\* module modname is disabled.
-fi
-
-dnl  Don't change this section.
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
-       else
-               AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
-               targetname=""
-       fi
-fi
-
-
-AC_SUBST(acctlog_cflags)
-AC_SUBST(acctlog_ldflags)
-
-
-AC_SUBST(targetname)
-AC_OUTPUT(Makefile)
diff --git a/src/modules/rlm_acctlog/rlm_acctlog.c b/src/modules/rlm_acctlog/rlm_acctlog.c
deleted file mode 100644 (file)
index cb84d6f..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- *      rlm_acctlog.c
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *   Copyright 2006 Suntel Communications - www.suntel.com.tr
- *   Copyright 2006 The FreeRADIUS server project
- *
- *   Tuyan Ozipek
- *   Peter Nixon
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-typedef struct rlm_acctlog_t {
-    char        *acctstart;
-    char        *acctstop;
-       char            *acctupdate;
-    char        *accton;
-       char            *acctoff;
-
-} rlm_acctlog_t;
-
-static const CONF_PARSER module_config[] = {
-    { "acctlog_update",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctupdate), NULL,  ""},
-    { "acctlog_start",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctstart), NULL,  ""},
-    { "acctlog_stop",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctstop), NULL,  ""},
-    { "acctlog_on",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, accton), NULL,  ""},
-    { "acctlog_off",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctoff), NULL,  ""},
-    { NULL, -1, 0, NULL, NULL }     /* end the list */
-};
-
-
-static int acctlog_detach(void *instance)
-{
-    rlm_acctlog_t *inst = instance;
-
-
-    free(inst);
-    return 0;
-}
-
-static int acctlog_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_acctlog_t *inst;
-
-    inst = rad_malloc(sizeof(*inst));
-    memset(inst, 0, sizeof(*inst));
-
-       if (cf_section_parse(conf, inst, module_config) < 0) {
-               acctlog_detach(inst);
-               return -1;
-       }
-
-       *instance = inst;
-
-    return 0;
-
-}
-
-static int do_acctlog_acct(void *instance, REQUEST *request)
-{
-       rlm_acctlog_t *inst;
-       VALUE_PAIR *pair;
-
-       char    logstr[MAX_STRING_LEN];
-       int     acctstatustype = 0;
-
-
-       inst = (rlm_acctlog_t*) instance;
-
-    if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {
-        acctstatustype = pair->vp_integer;
-    } else {
-        radius_xlat(logstr, sizeof(logstr), "packet has no accounting status type. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);
-        radlog(L_ERR, "rlm_acctlog (%s)", logstr);
-        return RLM_MODULE_INVALID;
-    }
-
-       switch (acctstatustype) {
-               case PW_STATUS_START:
-                       radius_xlat(logstr, sizeof(logstr), inst->acctstart, request, NULL);
-               break;
-               case PW_STATUS_STOP:
-                       radius_xlat(logstr, sizeof(logstr), inst->acctstop, request, NULL);
-               break;
-               case PW_STATUS_ALIVE:
-                       radius_xlat(logstr, sizeof(logstr), inst->acctupdate, request, NULL);
-               break;
-               case PW_STATUS_ACCOUNTING_ON:
-                       radius_xlat(logstr, sizeof(logstr), inst->accton, request, NULL);
-               break;
-               case PW_STATUS_ACCOUNTING_OFF:
-                       radius_xlat(logstr, sizeof(logstr), inst->acctoff, request, NULL);
-               break;
-
-       }
-
-       if (strlen(logstr))
-               radlog(L_ACCT,"%s", logstr);
-
-       return RLM_MODULE_OK;
-}
-
-/*
- *  Externally visible module definition.
- */
-module_t rlm_acctlog = {
-    RLM_MODULE_INIT,
-    "acctlog",
-    RLM_TYPE_THREAD_SAFE,       /* type */
-    acctlog_instantiate,        /* instantiation */
-    acctlog_detach,         /* detach */
-    {
-        NULL, /* authentication */
-        NULL, /* authorization */
-        NULL, /* preaccounting */
-        do_acctlog_acct, /* accounting */
-        NULL,       /* checksimul */
-        NULL,     /* pre-proxy */
-        NULL, /* post-proxy */
-        NULL  /* post-auth */
-    },
-};
-
index f6a2189..ddc6648 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
 
 /*
  *     The instance data for rlm_always is the list of fake values we are
@@ -44,7 +51,7 @@ typedef struct rlm_always_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "rcode",      PW_TYPE_STRING_PTR, offsetof(rlm_always_t,rcode_str),
     NULL, "fail" },
   { "simulcount", PW_TYPE_INTEGER,    offsetof(rlm_always_t,simulcount),
@@ -108,6 +115,8 @@ static int always_instantiate(CONF_SECTION *conf, void **instance)
         *      Convert the rcode string to an int, and get rid of it
         */
        data->rcode = str2rcode(data->rcode_str);
+       free(data->rcode_str);
+       data->rcode_str = NULL;
        if (data->rcode == -1) {
                free(data);
                return -1;
@@ -152,11 +161,10 @@ static int always_detach(void *instance)
 }
 
 module_t rlm_always = {
-       RLM_MODULE_INIT,
        "always",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        always_instantiate,             /* instantiation */
-       always_detach,                  /* detach */
        {
                always_return,          /* authentication */
                always_return,          /* authorization */
@@ -167,4 +175,6 @@ module_t rlm_always = {
                always_return,          /* post-proxy */
                always_return           /* post-auth */
        },
+       always_detach,                  /* detach */
+       NULL,                           /* destroy */
 };
index c1189ed..093f80e 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * Copyright (C) 2001,2006 The FreeRADIUS server project
+ * Copyright (C) 2001 The FreeRADIUS server project
  * Copyright (C) 2001 Chris Parker <cparker@starnetusa.net>
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
 #include       <sys/stat.h>
 
+#include       <stdlib.h>
+#include       <string.h>
+#include       <netdb.h>
 #include       <ctype.h>
 #include       <fcntl.h>
 #include        <limits.h>
 
+#ifdef HAVE_REGEX_H
+#  include      <regex.h>
+#endif
+
+#include       "radiusd.h"
+#include       "modules.h"
+
+static const char rcsid[] = "$Id$";
 
-/*
- *     Define a structure with the module configuration, so it can
- *     be used as the instance handle.
- */
 struct attr_filter_instance {
+        /* autz */
         char *attrsfile;
-       char *key;
         PAIR_LIST *attrs;
 };
 
-static const CONF_PARSER module_config[] = {
-       { "attrsfile",     PW_TYPE_FILENAME,
-         offsetof(struct attr_filter_instance,attrsfile), NULL, "${raddbdir}/attrs" },
-       { "key",     PW_TYPE_STRING_PTR,
-         offsetof(struct attr_filter_instance,key), NULL, "%{Realm}" },
-       { NULL, -1, 0, NULL, NULL }
-};
+static int check_pair(VALUE_PAIR *check_item, VALUE_PAIR *reply_item,
+                      int comp, int *pa, int *fa) {
+#ifdef HAVE_REGEX_H
+       regex_t         reg;
+#endif
+       switch(check_item->operator) {
+
+               case T_OP_SET:            /* nothing to do for set */
+                   break;
+               case T_OP_EQ:
+                    default:
+                       radlog(L_ERR, "Invalid operator for item %s: "
+                       "reverting to '=='", check_item->name);
+
+               case T_OP_CMP_TRUE:       /* comp always == 0 */
+               case T_OP_CMP_FALSE:      /* comp always == 1 */
+               case T_OP_CMP_EQ:
+                   if (comp == 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
 
-static void check_pair(VALUE_PAIR *check_item, VALUE_PAIR *reply_item,
-                      int *pass, int *fail)
-{
-       int compare;
+               case T_OP_NE:
+                   if (comp != 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
 
-       if (check_item->operator == T_OP_SET) return;
+               case T_OP_LT:
+                   if (comp < 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
 
-       compare = paircmp(check_item, reply_item);
-       if (compare == 1) {
-               ++*(pass);
-       } else {
-               ++*(fail);
-       }
+               case T_OP_GT:
+                   if (comp > 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
+
+               case T_OP_LE:
+                   if (comp <= 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
 
-       return;
+               case T_OP_GE:
+                   if (comp >= 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
+#ifdef HAVE_REGEX_H
+               case T_OP_REG_EQ:
+                   regcomp(&reg, (char *)check_item->strvalue, REG_EXTENDED);
+                   comp = regexec(&reg, (char *)reply_item->strvalue,
+                                     0, NULL, 0);
+                   regfree(&reg);
+                   if (comp == 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
+
+               case T_OP_REG_NE:
+                   regcomp(&reg, (char *)check_item->strvalue, REG_EXTENDED);
+                   comp = regexec(&reg, (char *)reply_item->strvalue,
+                                     0, NULL, 0);
+                   regfree(&reg);
+                   if (comp != 0) {
+                       ++*(pa);
+                   } else {
+                       ++*(fa);
+                   }
+                   break;
+#endif
+       }
+        return 0;
 }
 
 /*
  *     Copy the specified attribute to the specified list
  */
-static int mypairappend(REQUEST *request, VALUE_PAIR *item, VALUE_PAIR **to)
+static int mypairappend(VALUE_PAIR *item, VALUE_PAIR **to)
+{
+  VALUE_PAIR *tmp;
+  tmp = paircreate(item->attribute, item->type);
+  if (!tmp) {
+       radlog(L_ERR|L_CONS, "no memory");
+       return -1;
+  }
+
+  /*
+   *   Copy EVERYTHING.
+   */
+  memcpy(tmp, item, sizeof(*tmp));
+  tmp->next = NULL;
+  pairadd(to, tmp);
+  return 0;
+}
+
+/*
+ *     See if a VALUE_PAIR list contains Fall-Through = Yes
+ */
+static int fallthrough(VALUE_PAIR *vp)
 {
        VALUE_PAIR *tmp;
-       tmp = radius_paircreate(request, to, item->attribute, item->type);
 
-       /*
-        *      Copy EVERYTHING.
-        */
-       memcpy(tmp, item, sizeof(*tmp));
-       tmp->next = NULL;
-       *to = tmp;
+       tmp = pairfind(vp, PW_FALL_THROUGH);
 
-       return 0;
+       return tmp ? tmp->lvalue : 0;
 }
 
+static CONF_PARSER module_config[] = {
+       { "attrsfile",     PW_TYPE_STRING_PTR,
+         offsetof(struct attr_filter_instance,attrsfile), NULL, "${raddbdir}/attrs" },
+       { NULL, -1, 0, NULL, NULL }
+};
+
 static int getattrsfile(const char *filename, PAIR_LIST **pair_list)
 {
        int rcode;
@@ -136,19 +227,6 @@ static int getattrsfile(const char *filename, PAIR_LIST **pair_list)
        return 0;
 }
 
-
-/*
- *     Clean up.
- */
-static int attr_filter_detach(void *instance)
-{
-       struct attr_filter_instance *inst = instance;
-       pairlist_free(&inst->attrs);
-       free(inst);
-       return 0;
-}
-
-
 /*
  *     (Re-)read the "attrs" file into memory.
  */
@@ -164,203 +242,572 @@ static int attr_filter_instantiate(CONF_SECTION *conf, void **instance)
        memset(inst, 0, sizeof(*inst));
 
        if (cf_section_parse(conf, inst, module_config) < 0) {
-               attr_filter_detach(inst);
+               free(inst);
                return -1;
        }
 
        rcode = getattrsfile(inst->attrsfile, &inst->attrs);
         if (rcode != 0) {
                radlog(L_ERR|L_CONS, "Errors reading %s", inst->attrsfile);
-               attr_filter_detach(inst);
+               free(inst->attrsfile);
+               free(inst);
                return -1;
        }
+       radlog(L_ERR|L_CONS, " rlm_attr_filter: Authorize method will be"\
+                             " deprecated.");
        *instance = inst;
        return 0;
 }
 
-
-/*
- *     Common attr_filter checks
- */
-static int attr_filter_common(void *instance, REQUEST *request,
-                             VALUE_PAIR **input)
+static int attr_filter_authorize(void *instance, REQUEST *request)
 {
        struct attr_filter_instance *inst = instance;
-       VALUE_PAIR      *vp;
-       VALUE_PAIR      *output = NULL;
-       VALUE_PAIR      **output_tail;
-       VALUE_PAIR      *check_item;
-       PAIR_LIST       *pl;
-       int             found = 0;
-       int             pass, fail = 0;
-       char            *keyname = NULL;
-       char            buffer[256];
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      **reply_items;
+       VALUE_PAIR      *reply_item;
+       VALUE_PAIR      *reply_tmp = NULL;
+       VALUE_PAIR      *check_item;
+       PAIR_LIST       *pl;
+       int             found = 0;
+       int             compare;
+       int             pass, fail;
+       VALUE_PAIR      *realmpair;
+       char            *realmname;
 
-       if (!inst->key) {
-               VALUE_PAIR      *namepair;
+       /*
+        *      It's not a proxy reply, so return NOOP
+        */
 
-               namepair = pairfind(request->packet->vps, PW_REALM);
-               if (!namepair) {
-                       return (RLM_MODULE_NOOP);
-               }
-               keyname = namepair->vp_strvalue;
-       } else {
-               int len;
-
-               len = radius_xlat(buffer, sizeof(buffer), inst->key,
-                                 request, NULL);
-               if (!len) {
-                       return RLM_MODULE_NOOP;
-               }
-               keyname = buffer;
+       if( request->proxy == NULL ) {
+               return( RLM_MODULE_NOOP );
        }
 
-       output_tail = &output;
+       request_pairs = request->packet->vps;
+       reply_items = &request->reply->vps;
 
        /*
-        *      Find the attr_filter profile entry for the entry.
+        *      Get the realm.  Can't use request->config_items as
+        *      that gets freed by rad_authenticate....  use the one
+        *      set in the original request vps
         */
-       for (pl = inst->attrs; pl; pl = pl->next) {
-               int fall_through = 0;
+       realmpair = pairfind(request_pairs, PW_REALM);
+       if(!realmpair) {
+               /*    Can't find a realm, so no filtering of attributes
+                *    or should we use a DEFAULT entry?
+                *    For now, just return NOTFOUND. (maybe NOOP?)
+                */
+               return RLM_MODULE_NOTFOUND;
+       }
+
+       realmname = (char *) realmpair->strvalue;
+
+       /*
+        *      Find the attr_filter profile entry for the realm.
+        */
+       for(pl = inst->attrs; pl; pl = pl->next) {
 
                /*
                 *  If the current entry is NOT a default,
                 *  AND the realm does NOT match the current entry,
                 *  then skip to the next entry.
                 */
-               if ((strcmp(pl->name, "DEFAULT") != 0) &&
-                   (strcmp(keyname, pl->name) != 0))  {
+               if ( (strcmp(pl->name, "DEFAULT") != 0) &&
+                    (strcmp(realmname, pl->name) != 0) )  {
                    continue;
                }
 
                DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,
-                      pl->lineno);
+                                                                   pl->lineno);
                found = 1;
 
-               for (check_item = pl->check;
-                    check_item != NULL;
-                    check_item = check_item->next) {
-                       if (check_item->attribute == PW_FALL_THROUGH) {
-                               fall_through = 1;
-                               continue;
-                       }
+               check_item = pl->check;
+
+               while( check_item != NULL ) {
 
-                       /*
-                        *    If it is a SET operator, add the attribute to
-                        *    the output list without checking it.
-                        */
-                       if (check_item->operator == T_OP_SET ) {
-                               if (mypairappend(request, check_item, output_tail) < 0) {
-                                       pairfree(&output);
-                                       return RLM_MODULE_FAIL;
-                               }
-                               output_tail = &((*output_tail)->next);
+                   /*
+                    *      If it is a SET operator, add the attribute to
+                    *      the reply list without checking reply_items.
+                    *
+                    */
+
+                   if( check_item->operator == T_OP_SET ) {
+                       if (mypairappend(check_item, &reply_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
                        }
+                   }
+                   check_item = check_item->next;
+
                }
 
-               /*
-                *      Iterate through the input items, comparing
-                *      each item to every rule, then moving it to the
-                *      output list only if it matches all rules
-                *      for that attribute.  IE, Idle-Timeout is moved
-                *      only if it matches all rules that describe an
-                *      Idle-Timeout.
-                */
-               for (vp = *input; vp != NULL; vp = vp->next ) {
-                       /* reset the pass,fail vars for each reply item */
-                       pass = fail = 0;
-
-                       /*
-                        *      reset the check_item pointer to
-                        *      beginning of the list
-                        */
-                       for (check_item = pl->check;
-                            check_item != NULL;
-                            check_item = check_item->next) {
-                               /*
-                                *      Vendor-Specific is special, and
-                                *      matches any VSA if the comparison
-                                *      is always true.
-                                */
-                               if ((check_item->attribute == PW_VENDOR_SPECIFIC) &&
-                                   (VENDOR(vp->attribute) != 0) &&
-                                   (check_item->operator == T_OP_CMP_TRUE)) {
-                                       pass++;
-                                       continue;
-                               }
-
-                               if (vp->attribute == check_item->attribute) {
-                                       check_pair(check_item, vp,
-                                                  &pass, &fail);
-                               }
+                /*
+                 * Iterate through the reply items, comparing each reply item
+                * to every rule, then moving it to the reply_tmp list
+                * only if it matches all rules for that attribute.
+                * IE, Idle-Timeout is moved only if it matches all rules that
+                 * describe an Idle-Timeout.
+                 */
+
+               for(reply_item = *reply_items;
+                   reply_item != NULL;
+                   reply_item = reply_item->next ) {
+
+                   /* reset the pass,fail vars for each reply item */
+                   pass = fail = 0;
+
+                   /* reset the check_item pointer to beginning of the list */
+                   check_item = pl->check;
+
+                   while( check_item != NULL ) {
+
+                       if(reply_item->attribute == check_item->attribute) {
+
+                           compare = simplepaircmp(request, reply_item,
+                                                   check_item);
+                           check_pair(check_item, reply_item, compare,
+                                      &pass, &fail);
                        }
 
-                       /* only move attribute if it passed all rules */
-                       if (fail == 0 && pass > 0) {
-                               if (mypairappend(request, vp, output_tail) < 0) {
-                                       pairfree(&output);
-                                       return RLM_MODULE_FAIL;
-                               }
-                               output_tail = &((*output_tail)->next);
+                       check_item = check_item->next;
+
+                   }
+
+                   /* only move attribute if it passed all rules */
+                   if (fail == 0 && pass > 0) {
+                       if (mypairappend( reply_item, &reply_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
                        }
+                   }
+
                }
 
                /* If we shouldn't fall through, break */
-               if (!fall_through)
-                       break;
+               if(!fallthrough(pl->check))
+                   break;
        }
 
+       pairfree(&request->reply->vps);
+       request->reply->vps = reply_tmp;
+
        /*
-        *      No entry matched.  We didn't do anything.
+        *      See if we succeeded.  If we didn't find the realm,
+        *      then exit from the module.
         */
-       if (!found) {
-               rad_assert(output == NULL);
-               return RLM_MODULE_NOOP;
-       }
+       if (!found)
+               return RLM_MODULE_OK;
 
-       pairfree(input);
-       *input = output;
+       /*
+        *      Remove server internal parameters.
+        */
+       pairdelete(reply_items, PW_FALL_THROUGH);
 
        return RLM_MODULE_UPDATED;
 }
 
 static int attr_filter_accounting(void *instance, REQUEST *request)
 {
-       return attr_filter_common(instance, request, &request->packet->vps);
+       struct attr_filter_instance *inst = instance;
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      *send_item;
+       VALUE_PAIR      *send_tmp = NULL;
+       VALUE_PAIR      *check_item;
+       PAIR_LIST       *pl;
+       int             found = 0;
+       int             compare;
+       int             pass, fail;
+       VALUE_PAIR      *realmpair;
+       char            *realmname;
+       /*
+        * Accounting is similar to pre-proxy.
+        * Here we are concerned with what we are going to forward to
+        * the remote server as opposed to concerns with what we will send
+        * to the NAS based on a proxy reply to an auth request.
+        */
+
+       if (request->packet->code != PW_ACCOUNTING_REQUEST) {
+               return (RLM_MODULE_NOOP);
+       }
+
+       request_pairs = request->packet->vps;
+
+       /* Get the realm from the original request vps. */
+       realmpair = pairfind(request_pairs, PW_REALM);
+
+       if (!realmpair) {
+               /* If there is no realm...NOOP */
+               return (RLM_MODULE_NOOP);
+       }
+
+       realmname = (char *) realmpair->strvalue;
+
+       /*
+        * Find the attr_filter profile entry for the realm
+        */
+       for (pl = inst->attrs; pl; pl = pl->next) {
+
+               /*
+                * If the current entry is NOT a default,
+                * AND the realm does not match the current entry,
+                * then skip to the next entry.
+                */
+               if ( (strcmp(pl->name, "DEFAULT") != 0) &&
+                    (strcasecmp(realmname, pl->name) != 0) ) {
+                   continue;
+               }
+
+               DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,
+                                                                   pl->lineno);
+               found = 1;
+
+               check_item = pl->check;
+
+               while (check_item != NULL) {
+
+                   /*
+                    * If it is a SET operator, add the attribute to
+                    * the send list w/out checking.
+                    */
+
+                   if (check_item->operator == T_OP_SET) {
+                       if (mypairappend(check_item, &send_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
+                       }
+                   }
+                   check_item = check_item->next;
+               }
+               /*
+                * Iterate through the request_pairs (items sent from NAS).
+                * Compare each pair to every rule for this realm/DEFAULT.
+                * Move an item to send_tmp if it matches all rules for
+                * attribute in question.
+                */
+               for (send_item = request_pairs; send_item != NULL;
+                    send_item = send_item->next ) {
+
+                   /* reset the pass/fail vars for each packet->vp. */
+                   pass = fail = 0;
+
+                   /* reset the check_item pointer to beginning of the list */
+                   check_item = pl->check;
+
+                   while (check_item != NULL) {
+                       if (send_item->attribute == check_item->attribute) {
+
+                           compare = simplepaircmp(request, send_item,
+                                                   check_item);
+                           check_pair(check_item, send_item, compare,
+                                      &pass, &fail);
+                       }
+
+                       check_item = check_item->next;
+                   }
+                   /* only send if attribute passed all rules */
+                   if (fail == 0 && pass > 0) {
+                       if (mypairappend (send_item, &send_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
+                       }
+                   }
+               }
+               if (!fallthrough(pl->check))
+                   break;
+       }
+       pairfree (&request->packet->vps);
+       request->packet->vps = send_tmp;
+
+       /*
+        * See if we succeeded. If we didn't find the realm,
+        * then exit from the module.
+        */
+       if (!found)
+               return RLM_MODULE_OK;
+
+       /*
+        * Remove server internal paramters.
+        */
+       pairdelete(&send_tmp, PW_FALL_THROUGH);
+
+       return RLM_MODULE_UPDATED;
 }
 
-static int attr_filter_preproxy(void *instance, REQUEST *request)
+static int attr_filter_preproxy (void *instance, REQUEST *request)
 {
-       return attr_filter_common(instance, request, &request->proxy->vps);
+       struct attr_filter_instance *inst = instance;
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      *send_item;
+       VALUE_PAIR      *send_tmp = NULL;
+       VALUE_PAIR      *check_item;
+       PAIR_LIST       *pl;
+       int             found = 0;
+       int             compare;
+       int             pass, fail;
+       VALUE_PAIR      *realmpair;
+       char            *realmname;
+
+       /*
+        * Pre-proxy we are
+         * concerned with what we are going to forward to
+        * to the remote server as opposed to we will do with
+        * with the remote servers' repsonse pairs. Consequently,
+        * we deal with modifications to the request->packet->vps;
+        */
+       request_pairs = request->proxy->vps;
+       if (request->packet->code != PW_AUTHENTICATION_REQUEST) {
+               return (RLM_MODULE_NOOP);
+       }
+       realmpair = pairfind(request_pairs, PW_REALM);
+       if (!realmpair) {
+               return (RLM_MODULE_NOOP);
+       }
+
+       realmname = (char *)realmpair->strvalue;
+
+       for (pl = inst->attrs; pl; pl = pl->next) {
+               if ( (strcmp(pl->name, "DEFAULT") != 0) &&
+                    (strcasecmp(realmname, pl->name) != 0) ) {
+                   continue;
+               }
+
+               DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,
+                                                                   pl->lineno);
+               found = 1;
+
+               check_item = pl->check;
+
+               while (check_item != NULL) {
+
+                   /*
+                    * Append all SET operator attributes with no check.
+                    */
+                   if (check_item->operator == T_OP_SET) {
+                       if (mypairappend(check_item, &send_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
+                       }
+                   }
+                   check_item = check_item->next;
+               }
+               /*
+                * Iterate through the request_pairs (items sent from NAS).
+                * Compare each pair to every rule for this realm/DEFAULT.
+                * Move an item to send_tmp if it matches all rules for
+                * attribute in question.
+                */
+               for (send_item = request_pairs;
+                    send_item != NULL;
+                   send_item = send_item->next ) {
+
+                   /* reset the pass/fail vars for each packet->vp. */
+                   pass = fail = 0;
+
+                   /* reset the check_item to the beginning */
+                   check_item = pl->check;
+
+                   /*
+                    * compare each packet->vp to the entire list of
+                    * check_items for this realm.
+                    */
+                   while (check_item != NULL) {
+                       if (send_item->attribute == check_item->attribute) {
+
+                           compare = simplepaircmp(request, send_item,
+                                                   check_item);
+                           check_pair(check_item, send_item, compare,
+                                      &pass, &fail);
+
+                       }
+
+                       check_item = check_item->next;
+                   }
+
+                   /* only send if attribute passed all rules */
+                   if (fail == 0 && pass > 0) {
+                       if (mypairappend (send_item, &send_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
+                       }
+                   }
+               }
+               if (!fallthrough(pl->check))
+                   break;
+       }
+       pairfree (&request->proxy->vps);
+       request->proxy->vps = send_tmp;
+
+       if (!found)
+               return RLM_MODULE_OK;
+       pairdelete(&send_tmp, PW_FALL_THROUGH);
+       return RLM_MODULE_UPDATED;
 }
 
 static int attr_filter_postproxy(void *instance, REQUEST *request)
 {
-       return attr_filter_common(instance, request, &request->proxy_reply->vps);
+       struct attr_filter_instance *inst = instance;
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      **reply_items;
+       VALUE_PAIR      *reply_item;
+       VALUE_PAIR      *reply_tmp = NULL;
+       VALUE_PAIR      *check_item;
+       PAIR_LIST       *pl;
+       int             found = 0;
+       int             compare;
+       int             pass, fail = 0;
+       VALUE_PAIR      *realmpair;
+       char            *realmname;
+       /*
+        *      It's not a proxy reply, so return NOOP
+        */
+
+       if( request->proxy == NULL ) {
+               return( RLM_MODULE_NOOP );
+       }
+
+       request_pairs = request->packet->vps;
+       reply_items = &request->proxy_reply->vps;
+
+       /*
+        * Get the realm.  Can't use request->config_items as
+        * that gets freed by rad_authenticate....  use the one
+        * set in the original request vps
+        */
+       realmpair = pairfind(request_pairs, PW_REALM);
+       if(!realmpair) {
+               /*    Can't find a realm, so no filtering of attributes
+                *    or should we use a DEFAULT entry?
+                *    For now, just return NOTFOUND. (maybe NOOP?)
+                */
+               return RLM_MODULE_NOTFOUND;
+       }
+
+       realmname = (char *) realmpair->strvalue;
+
+       /*
+        *      Find the attr_filter profile entry for the realm.
+        */
+       for(pl = inst->attrs; pl; pl = pl->next) {
+
+               /*
+                *  If the current entry is NOT a default,
+                *  AND the realm does NOT match the current entry,
+                *  then skip to the next entry.
+                */
+               if ( (strcmp(pl->name, "DEFAULT") != 0) &&
+                    (strcmp(realmname, pl->name) != 0) )  {
+                   continue;
+               }
+
+               DEBUG2(" attr_filter: Matched entry %s at line %d", pl->name,
+                                                                   pl->lineno);
+               found = 1;
+
+               check_item = pl->check;
+
+               while( check_item != NULL ) {
+
+                   /*
+                    *    If it is a SET operator, add the attribute to
+                    *    the reply list without checking reply_items.
+                    */
+
+                   if( check_item->operator == T_OP_SET ) {
+                       if (mypairappend(check_item, &reply_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
+                       }
+                   }
+                   check_item = check_item->next;
+
+               }
+
+               /*
+                * Iterate through the reply items,
+                * comparing each reply item to every rule,
+                * then moving it to the reply_tmp list only if it matches all
+                * rules for that attribute.
+                * IE, Idle-Timeout is moved only if it matches
+                * all rules that describe an Idle-Timeout.
+                */
+
+               for( reply_item = *reply_items; reply_item != NULL;
+                    reply_item = reply_item->next ) {
+
+                   /* reset the pass,fail vars for each reply item */
+                   pass = fail = 0;
+
+                   /* reset the check_item pointer to beginning of the list */
+                   check_item = pl->check;
+
+                   while( check_item != NULL ) {
+
+                       if(reply_item->attribute == check_item->attribute) {
+
+                           compare = simplepaircmp(request, reply_item,
+                                                   check_item);
+                           check_pair(check_item, reply_item, compare,
+                                      &pass, &fail);
+                       }
+
+                       check_item = check_item->next;
+
+                   }
+
+                   /* only move attribute if it passed all rules */
+                   if (fail == 0 && pass > 0) {
+                       if (mypairappend( reply_item, &reply_tmp) < 0) {
+                               return RLM_MODULE_FAIL;
+                       }
+                   }
+
+               }
+
+               /* If we shouldn't fall through, break */
+               if(!fallthrough(pl->check))
+                   break;
+       }
+
+       pairfree(&request->proxy_reply->vps);
+       request->proxy_reply->vps = reply_tmp;
+
+       /*
+        * See if we succeeded.  If we didn't find the realm,
+        * then exit from the module.
+        */
+       if (!found)
+               return RLM_MODULE_OK;
+
+       /*
+        *      Remove server internal parameters.
+        */
+       pairdelete(reply_items, PW_FALL_THROUGH);
+
+       return RLM_MODULE_UPDATED;
 }
 
-static int attr_filter_postauth(void *instance, REQUEST *request)
+/*
+ *     Clean up.
+ */
+static int attr_filter_detach(void *instance)
 {
-       return attr_filter_common(instance, request, &request->reply->vps);
+       struct attr_filter_instance *inst = instance;
+       pairlist_free(&inst->attrs);
+       free(inst->attrsfile);
+       free(inst);
+       return 0;
 }
 
 
 /* globally exported name */
 module_t rlm_attr_filter = {
-       RLM_MODULE_INIT,
        "attr_filter",
        0,                              /* type: reserved */
+       NULL,                           /* initialization */
        attr_filter_instantiate,        /* instantiation */
-       attr_filter_detach,             /* detach */
        {
                NULL,                   /* authentication */
-               NULL,                   /* authorization */
+               attr_filter_authorize,  /* authorization */
                NULL,                   /* preaccounting */
                attr_filter_accounting, /* accounting */
                NULL,                   /* checksimul */
                attr_filter_preproxy,   /* pre-proxy */
                attr_filter_postproxy,  /* post-proxy */
-               attr_filter_postauth    /* post-auth */
+               NULL                    /* post-auth */
        },
+       attr_filter_detach,             /* detach */
+       NULL                            /* destroy */
 };
 
index 6c6222b..7f67892 100644 (file)
@@ -4,10 +4,6 @@
 
 TARGET      = @targetname@
 SRCS        = rlm_attr_rewrite.c
-HEADERS     =
-RLM_CFLAGS  = @attr_rewrite_cflags@
-RLM_LIBS    = @attr_rewrite_ldflags@
-RLM_INSTALL =
 
 include ../rules.mak
 
index 8c82b74..db1e7d5 100755 (executable)
@@ -1,10 +1,9 @@
 #! /bin/sh
-# From configure.in Revision: 1.3 .
+# From configure.in Revision: 1.1.10.1 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.60.
+# Generated by GNU Autoconf 2.59.
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 ## --------------------- ##
@@ -18,35 +17,11 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -55,43 +30,8 @@ else
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""       $as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
 # Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
+$as_unset ENV MAIL MAILPATH
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -105,19 +45,18 @@ do
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
@@ -125,386 +64,157 @@ fi
 
 
 # Name of the executable.
-as_me=`$as_basename -- "$0" ||
+as_me=`$as_basename "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
-  if (eval ":") 2>/dev/null; then
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-
-  if test $as_have_required = yes &&    (eval ":
-(as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
 
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
 
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
 fi
 
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
 
-test \$exitcode = 0) || { (exit 1); exit 1; }
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
 
-(
-  as_lineno_1=\$LINENO
-  as_lineno_2=\$LINENO
-  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
-  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
-  :
-else
-  as_candidate_shells=
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
     as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  case $as_dir in
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
         /*)
-          for as_base in sh bash ksh sh5; do
-            as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
-          done;;
-       esac
-done
-IFS=$as_save_IFS
-
-
-      for as_shell in $as_candidate_shells $SHELL; do
-        # Try only shells that exist, to save several forks.
-        if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-               { ("$as_shell") 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-_ASEOF
-}; then
-  CONFIG_SHELL=$as_shell
-              as_have_required=yes
-              if { "$as_shell" 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-(as_func_return () {
-  (exit $1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
-  break
-fi
-
-fi
-
-      done
-
-      if test "x$CONFIG_SHELL" != x; then
-  for as_var in BASH_ENV ENV
-        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-        done
-        export CONFIG_SHELL
-        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
-    if test $as_have_required = no; then
-  echo This script requires a shell more modern than all the
-      echo shells that I found on your system.  Please install a
-      echo modern shell, or manually run the script under such a
-      echo shell if you do have one.
-      { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
-  echo No shell found that supports shell functions.
-  echo Please tell autoconf@gnu.org about your system,
-  echo including any error possibly output before this
-  echo message
-}
-
-
-
+          if ("$as_dir/$as_base" -c '
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
 
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
     sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
       N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
       t loop
-      s/-\n.*//
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
     ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
+  chmod +x $as_me.lineno ||
     { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
   # Exit status is that of the last command.
   exit
 }
 
 
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
     as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
+rm -f conf$$ conf$$.exe conf$$.file
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -513,19 +223,7 @@ else
   as_mkdir_p=false
 fi
 
-# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  as_executable_p="test -x"
-else
-  as_executable_p=:
-fi
-rm -f conf$$.file
+as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -534,27 +232,39 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
 
-exec 7<&0 </dev/null 6>&1
 
 # Name of the host.
 # hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
+exec 6>&1
+
 #
 # Initializations.
 #
 ac_default_prefix=/usr/local
-ac_clean_files=
 ac_config_libobj_dir=.
-LIBOBJS=
 cross_compiling=no
 subdirs=
 MFLAGS=
 MAKEFLAGS=
 SHELL=${CONFIG_SHELL-/bin/sh}
 
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
 # Identity of this package.
 PACKAGE_NAME=
 PACKAGE_TARNAME=
@@ -563,104 +273,8 @@ PACKAGE_STRING=
 PACKAGE_BUGREPORT=
 
 ac_unique_file="rlm_attr_rewrite.c"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# if HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#endif
-#if HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-CPP
-GREP
-EGREP
-attr_rewrite_cflags
-attr_rewrite_ldflags
-targetname
-LIBOBJS
-LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS targetname LIBOBJS LTLIBOBJS'
 ac_subst_files=''
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-CPP'
-
 
 # Initialize some variables set by options.
 ac_init_help=
@@ -687,48 +301,34 @@ x_libraries=NONE
 # and all the variables that are supposed to be based on exec_prefix
 # by default will actually change.
 # Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
 bindir='${exec_prefix}/bin'
 sbindir='${exec_prefix}/sbin'
 libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
+datadir='${prefix}/share'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
 
 ac_prev=
-ac_dashdash=
 for ac_option
 do
   # If the previous option needs an argument, assign it.
   if test -n "$ac_prev"; then
-    eval $ac_prev=\$ac_option
+    eval "$ac_prev=\$ac_option"
     ac_prev=
     continue
   fi
 
-  case $ac_option in
-  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)   ac_optarg=yes ;;
-  esac
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
 
-  case $ac_dashdash$ac_option in
-  --)
-    ac_dashdash=yes ;;
+  case $ac_option in
 
   -bindir | --bindir | --bindi | --bind | --bin | --bi)
     ac_prev=bindir ;;
@@ -750,18 +350,12 @@ do
   --config-cache | -C)
     cache_file=config.cache ;;
 
-  -datadir | --datadir | --datadi | --datad)
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
     ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
     datadir=$ac_optarg ;;
 
-  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
-  | --dataroo | --dataro | --datar)
-    ac_prev=datarootdir ;;
-  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
-  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
-    datarootdir=$ac_optarg ;;
-
   -disable-* | --disable-*)
     ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
@@ -769,17 +363,7 @@ do
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
     ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval enable_$ac_feature=no ;;
-
-  -docdir | --docdir | --docdi | --doc | --do)
-    ac_prev=docdir ;;
-  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
-    docdir=$ac_optarg ;;
-
-  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
-    ac_prev=dvidir ;;
-  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
-    dvidir=$ac_optarg ;;
+    eval "enable_$ac_feature=no" ;;
 
   -enable-* | --enable-*)
     ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
@@ -788,7 +372,11 @@ do
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
     ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval enable_$ac_feature=\$ac_optarg ;;
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -815,12 +403,6 @@ do
   -host=* | --host=* | --hos=* | --ho=*)
     host_alias=$ac_optarg ;;
 
-  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
-    ac_prev=htmldir ;;
-  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
-  | --ht=*)
-    htmldir=$ac_optarg ;;
-
   -includedir | --includedir | --includedi | --included | --include \
   | --includ | --inclu | --incl | --inc)
     ac_prev=includedir ;;
@@ -845,16 +427,13 @@ do
   | --libexe=* | --libex=* | --libe=*)
     libexecdir=$ac_optarg ;;
 
-  -localedir | --localedir | --localedi | --localed | --locale)
-    ac_prev=localedir ;;
-  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
-    localedir=$ac_optarg ;;
-
   -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst | --locals)
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
     ac_prev=localstatedir ;;
   -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
     localstatedir=$ac_optarg ;;
 
   -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -919,16 +498,6 @@ do
   | --progr-tra=* | --program-tr=* | --program-t=*)
     program_transform_name=$ac_optarg ;;
 
-  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
-    ac_prev=pdfdir ;;
-  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
-    pdfdir=$ac_optarg ;;
-
-  -psdir | --psdir | --psdi | --psd | --ps)
-    ac_prev=psdir ;;
-  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
-    psdir=$ac_optarg ;;
-
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
@@ -985,7 +554,11 @@ do
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
     ac_package=`echo $ac_package| sed 's/-/_/g'`
-    eval with_$ac_package=\$ac_optarg ;;
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
 
   -without-* | --without-*)
     ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
@@ -994,7 +567,7 @@ do
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
     ac_package=`echo $ac_package | sed 's/-/_/g'`
-    eval with_$ac_package=no ;;
+    eval "with_$ac_package=no" ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -1025,7 +598,8 @@ Try \`$0 --help' for more information." >&2
     expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
    { (exit 1); exit 1; }; }
-    eval $ac_envvar=\$ac_optarg
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
     export $ac_envvar ;;
 
   *)
@@ -1045,19 +619,27 @@ if test -n "$ac_prev"; then
    { (exit 1); exit 1; }; }
 fi
 
-# Be sure to have absolute directory names.
-for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
-               datadir sysconfdir sharedstatedir localstatedir includedir \
-               oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
 do
-  eval ac_val=\$$ac_var
+  eval ac_val=$`echo $ac_var`
   case $ac_val in
-    [\\/$]* | ?:[\\/]* )  continue;;
-    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
   esac
-  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; }
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1084,76 +666,54 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias-
 test "$silent" = yes && exec 6>/dev/null
 
 
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  { echo "$as_me: error: Working directory cannot be determined" >&2
-   { (exit 1); exit 1; }; }
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  { echo "$as_me: error: pwd does not report name of working directory" >&2
-   { (exit 1); exit 1; }; }
-
-
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$0" ||
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
 $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$0" : 'X\(//\)[^/]' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$0" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r "$srcdir/$ac_unique_file"; then
+  if test ! -r $srcdir/$ac_unique_file; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r "$srcdir/$ac_unique_file"; then
-  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
    { (exit 1); exit 1; }; }
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
-       cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
    { (exit 1); exit 1; }; }
-       pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
-  srcdir=.
+  fi
 fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
-  eval ac_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_env_${ac_var}_value=\$${ac_var}
-  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
 
 #
 # Report the --help message.
@@ -1182,6 +742,9 @@ Configuration:
   -n, --no-create         do not create output files
       --srcdir=DIR        find the sources in DIR [configure dir or \`..']
 
+_ACEOF
+
+  cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
@@ -1199,22 +762,15 @@ Fine tuning of the installation directories:
   --bindir=DIR           user executables [EPREFIX/bin]
   --sbindir=DIR          system admin executables [EPREFIX/sbin]
   --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
   --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
   --libdir=DIR           object code libraries [EPREFIX/lib]
   --includedir=DIR       C header files [PREFIX/include]
   --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR          info documentation [DATAROOTDIR/info]
-  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR           man documentation [DATAROOTDIR/man]
-  --docdir=DIR           documentation root [DATAROOTDIR/doc/PACKAGE]
-  --htmldir=DIR          html documentation [DOCDIR]
-  --dvidir=DIR           dvi documentation [DOCDIR]
-  --pdfdir=DIR           pdf documentation [DOCDIR]
-  --psdir=DIR            ps documentation [DOCDIR]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
 _ACEOF
 
   cat <<\_ACEOF
@@ -1225,99 +781,119 @@ if test -n "$ac_init_help"; then
 
   cat <<\_ACEOF
 
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
 _ACEOF
-ac_status=$?
 fi
 
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" || continue
+    test -d $ac_dir || continue
     ac_builddir=.
 
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
+if test "$ac_dir" != .; then
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
 
 case $srcdir in
-  .)  # We are building in place.
+  .)  # No --srcdir option.  We are building in place.
     ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
 esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
-    else
-      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
-  done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
-  cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.60
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
 _ACEOF
-  exit
+  exit 0
 fi
-cat >config.log <<_ACEOF
+exec 5>config.log
+cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
 
 _ACEOF
-exec 5>>config.log
 {
 cat <<_ASUNAME
 ## --------- ##
@@ -1336,7 +912,7 @@ uname -v = `(uname -v) 2>/dev/null || echo unknown`
 /bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
 /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
 /bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
 /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
@@ -1350,7 +926,6 @@ do
   test -z "$as_dir" && as_dir=.
   echo "PATH: $as_dir"
 done
-IFS=$as_save_IFS
 
 } >&5
 
@@ -1372,6 +947,7 @@ _ACEOF
 ac_configure_args=
 ac_configure_args0=
 ac_configure_args1=
+ac_sep=
 ac_must_keep_next=false
 for ac_pass in 1 2
 do
@@ -1382,7 +958,7 @@ do
     -q | -quiet | --quiet | --quie | --qui | --qu | --q \
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
-    *\'*)
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
       ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
@@ -1404,7 +980,9 @@ do
          -* ) ac_must_keep_next=true ;;
        esac
       fi
-      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
       ;;
     esac
   done
@@ -1415,8 +993,8 @@ $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
 trap 'exit_status=$?
   # Save into config.log some information that might help in debugging.
   {
@@ -1429,34 +1007,20 @@ trap 'exit_status=$?
 _ASBOX
     echo
     # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
+{
   (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
       sed -n \
-       "s/'\''/'\''\\\\'\'''\''/g;
-         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
     *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
-    esac |
-    sort
-)
+    esac;
+}
     echo
 
     cat <<\_ASBOX
@@ -1467,28 +1031,22 @@ _ASBOX
     echo
     for ac_var in $ac_subst_vars
     do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      echo "$ac_var='\''$ac_val'\''"
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
       cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
+## ------------- ##
+## Output files. ##
+## ------------- ##
 _ASBOX
       echo
       for ac_var in $ac_subst_files
       do
-       eval ac_val=\$$ac_var
-       case $ac_val in
-       *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-       esac
-       echo "$ac_var='\''$ac_val'\''"
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
       done | sort
       echo
     fi
@@ -1500,24 +1058,26 @@ _ASBOX
 ## ----------- ##
 _ASBOX
       echo
-      cat confdefs.h
+      sed "/^$/d" confdefs.h | sort
       echo
     fi
     test "$ac_signal" != 0 &&
       echo "$as_me: caught signal $ac_signal"
     echo "$as_me: exit $exit_status"
   } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
-' 0
+     ' 0
 for ac_signal in 1 2 13 15; do
   trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
 done
 ac_signal=0
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
 
 # Predefined preprocessor variables.
 
@@ -1548,17 +1108,14 @@ _ACEOF
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
-  set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
-  set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
-  set x "$ac_default_prefix/share/config.site" \
-       "$ac_default_prefix/etc/config.site"
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
 fi
-shift
-for ac_site_file
-do
+for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
     { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
 echo "$as_me: loading site script $ac_site_file" >&6;}
@@ -1574,8 +1131,8 @@ if test -r "$cache_file"; then
     { echo "$as_me:$LINENO: loading cache $cache_file" >&5
 echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
     esac
   fi
 else
@@ -1587,11 +1144,12 @@ fi
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
   eval ac_old_set=\$ac_cv_env_${ac_var}_set
   eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
   case $ac_old_set,$ac_new_set in
     set,)
       { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
@@ -1616,7 +1174,8 @@ echo "$as_me:   current value: $ac_new_val" >&2;}
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
@@ -1633,22 +1192,6 @@ echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start ov
    { (exit 1); exit 1; }; }
 fi
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -1659,2026 +1202,150 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-if test x$with_rlm_attr_rewrite != xno; then
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
 
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
 
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
 
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
 
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
 
 
-  test -n "$ac_ct_CC" && break
-done
+if test x$with_rlm_attr_rewrite != xno; then
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
 
+       targetname=rlm_attr_rewrite
+else
+       targetname=
+       echo \*\*\* module rlm_attr_rewrite is disabled.
 fi
 
 
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
 #
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort.  b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
 #
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions.  Remove them first so a
-# subsequent execution test works.
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { (ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
-       ;;
-    [ab].out )
-       # We found the default executable, but exeext='' is most
-       # certainly right.
-       break;;
-    *.* )
-        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-       then :; else
-          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       fi
-       # We set ac_cv_exeext here because the later test for it is not
-       # safe: cross compilers may not add the suffix if given an `-o'
-       # argument, so we may need to know it at that point already.
-       # Even if this section looks crufty: it has the advantage of
-       # actually working.
-       break;;
-    * )
-       break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
 
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-fi
+_ACEOF
 
-ac_exeext=$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
-
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
   else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
+    echo "not updating unwritable cache $cache_file"
   fi
 fi
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-         break;;
-    * ) break;;
-  esac
-done
-else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
+rm -f confcache
 
-int
-main ()
-{
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_compiler_gnu=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       CFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_c_werror_flag=$ac_save_c_werror_flag
-        CFLAGS="-g"
-        cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_c89=$ac_arg
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
-else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in grep ggrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
-    # Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_GREP_found && break 3
-  done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in egrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
-    # Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_EGREP_found && break 3
-  done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-else
-  ac_cv_path_EGREP=$EGREP
-fi
-
-
-   fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_header_stdc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_cv_header_stdc=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-                 inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  eval "$as_ac_Header=yes"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       eval "$as_ac_Header=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-for ac_header in regex.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-       if test "$ac_cv_header_regex_h" != "yes"; then
-               { echo "$as_me:$LINENO: result: no regex.h" >&5
-echo "${ECHO_T}no regex.h" >&6; }
-                fail=$fail" regex.h"
-       fi
-
-       targetname=rlm_attr_rewrite
-else
-       targetname=
-       echo \*\*\* module rlm_attr_rewrite is disabled.
-fi
-
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               { { echo "$as_me:$LINENO: error: set --without-rlm_attr_rewrite to disable it explicitly." >&5
-echo "$as_me: error: set --without-rlm_attr_rewrite to disable it explicitly." >&2;}
-   { (exit 1); exit 1; }; }
-       else
-               { echo "$as_me:$LINENO: WARNING: silently not building rlm_attr_rewrite." >&5
-echo "$as_me: WARNING: silently not building rlm_attr_rewrite." >&2;}
-               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_attr_rewrite requires: $fail." >&5
-echo "$as_me: WARNING: FAILURE: rlm_attr_rewrite requires: $fail." >&2;};
-               targetname=""
-       fi
-fi
-
-
-
-
-
-
-ac_config_files="$ac_config_files Makefile"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems.  If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
-  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
-
-  (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes (double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \).
-      sed -n \
-       "s/'/'\\\\''/g;
-         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;; #(
-    *)
-      # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-) |
-  sed '
-     /^ac_cv_env_/b end
-     t clear
-     :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
-     t end
-     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
-  if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
-      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
-  else
-    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
-  fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
 
 # Transform confdefs.h into DEFS.
 # Protect against shell expansion while executing Makefile rules.
 # Protect against Makefile macro expansion.
 #
 # If the first sed substitution is executed (which looks for macros that
-# take arguments), then branch to the quote section.  Otherwise,
+# take arguments), then we branch to the quote section.  Otherwise,
 # look for a macro that doesn't take arguments.
-ac_script='
+cat >confdef2opt.sed <<\_ACEOF
 t clear
-:clear
-s/^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\)/-D\1=\2/g
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
 t quote
-s/^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)/-D\1=\2/g
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
 t quote
-b any
-:quote
-s/[     `~#$^&*(){}\\|;'\''"<>?]/\\&/g
-s/\[/\\&/g
-s/\]/\\&/g
-s/\$/$$/g
-H
-:any
-${
-       g
-       s/^\n//
-       s/\n/ /g
-       p
-}
-'
-DEFS=`sed -n "$ac_script" confdefs.h`
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
 
 
 ac_libobjs=
 ac_ltlibobjs=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
-  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`echo "$ac_i" | sed "$ac_script"`
-  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
-  #    will be set to the directory where LIBOBJS objects are built.
-  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -3716,35 +1383,11 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -3753,43 +1396,8 @@ else
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""       $as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
 # Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
+$as_unset ENV MAIL MAILPATH
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -3803,19 +1411,18 @@ do
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
 
 
 # Name of the executable.
-as_me=`$as_basename -- "$0" ||
+as_me=`$as_basename "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
 
-# CDPATH.
-$as_unset CDPATH
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
 
 
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
 
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
 
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
     sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
       N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
       t loop
-      s/-\n.*//
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
     ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
   # Exit status is that of the last command.
   exit
 }
 
 
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
     as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
+rm -f conf$$ conf$$.exe conf$$.file
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -3945,19 +1591,7 @@ else
   as_mkdir_p=false
 fi
 
-# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  as_executable_p="test -x"
-else
-  as_executable_p=:
-fi
-rm -f conf$$.file
+as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -3966,14 +1600,31 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
 exec 6>&1
 
-# Save the log message, to keep $[0] and so on meaningful, and to
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -3981,18 +1632,30 @@ generated by GNU Autoconf 2.60.  Invocation command line was
   CONFIG_COMMANDS = $CONFIG_COMMANDS
   $ $0 $@
 
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
 _ACEOF
 
-cat >>$CONFIG_STATUS <<_ACEOF
 # Files that config.status was made for.
-config_files="$ac_config_files"
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
 
-_ACEOF
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
 
 cat >>$CONFIG_STATUS <<\_ACEOF
+
 ac_cs_usage="\
 \`$as_me' instantiates files from templates according to the
 current configuration.
@@ -4011,20 +1674,18 @@ Configuration files:
 $config_files
 
 Report bugs to <bug-autoconf@gnu.org>."
-
 _ACEOF
+
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.60,
-  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
-Copyright (C) 2006 Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
+srcdir=$srcdir
 _ACEOF
 
 cat >>$CONFIG_STATUS <<\_ACEOF
@@ -4035,42 +1696,60 @@ while test $# != 0
 do
   case $1 in
   --*=*)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
     ac_shift=:
     ;;
-  *)
+  -*)
     ac_option=$1
     ac_optarg=$2
     ac_shift=shift
     ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
   esac
 
   case $ac_option in
   # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
-  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    echo "$ac_cs_version"; exit ;;
-  --debug | --debu | --deb | --de | --d | -d )
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     CONFIG_FILES="$CONFIG_FILES $ac_optarg"
     ac_need_defaults=false;;
-  --he | --h |  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit ;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
    { (exit 1); exit 1; }; } ;;
 
-  *) ac_config_targets="$ac_config_targets $1"
-     ac_need_defaults=false ;;
+  *) ac_config_targets="$ac_config_targets $1" ;;
 
   esac
   shift
@@ -4086,42 +1765,28 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 if \$ac_cs_recheck; then
-  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  CONFIG_SHELL=$SHELL
-  export CONFIG_SHELL
-  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-  echo "$ac_log"
-} >&5
 
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
 
-# Handling of arguments.
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
 for ac_config_target in $ac_config_targets
 do
-  case $ac_config_target in
-    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
    { (exit 1); exit 1; }; };;
   esac
 done
 
-
 # If the user did not use the arguments to specify the items to instantiate,
 # then the envvar interface is used.  Set only those that are not.
 # We use the long form for the default assignment because of an extremely
@@ -4131,362 +1796,283 @@ if $ac_need_defaults; then
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
+# simply because there is no reason to put it here, and in addition,
 # creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
+# Create a temporary directory, and hook for its removal unless debugging.
 $debug ||
 {
-  tmp=
-  trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
   trap '{ (exit 1); exit 1; }' 1 2 13 15
 }
+
 # Create a (secure) tmp directory for tmp files.
 
 {
-  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
   test -n "$tmp" && test -d "$tmp"
 }  ||
 {
-  tmp=./conf$$-$RANDOM
-  (umask 077 && mkdir "$tmp")
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
 } ||
 {
    echo "$me: cannot create a temporary directory in ." >&2
    { (exit 1); exit 1; }
 }
 
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
 #
-# Set up the sed scripts for CONFIG_FILES section.
+# CONFIG_FILES section.
 #
 
 # No need to generate the scripts if there are no CONFIG_FILES.
 # This happens for instance when ./config.status config.h
-if test -n "$CONFIG_FILES"; then
-
-_ACEOF
-
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
-  cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CPP!$CPP$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-attr_rewrite_cflags!$attr_rewrite_cflags$ac_delim
-attr_rewrite_ldflags!$attr_rewrite_ldflags$ac_delim
-targetname!$targetname$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
-
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 52; then
-    break
-  elif $ac_last_try; then
-    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
-   { (exit 1); exit 1; }; }
-  else
-    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@targetname@,$targetname,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
   fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
-  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
-  ac_eof=`expr $ac_eof + 1`
-fi
+fi # test -n "$CONFIG_FILES"
 
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
 _ACEOF
-
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[         ]*VPATH[        ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[    ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[      ]*$//
-}'
-fi
-
 cat >>$CONFIG_STATUS <<\_ACEOF
-fi # test -n "$CONFIG_FILES"
-
-
-for ac_tag in  :F $CONFIG_FILES
-do
-  case $ac_tag in
-  :[FHLC]) ac_mode=$ac_tag; continue;;
-  esac
-  case $ac_mode$ac_tag in
-  :[FHL]*:*);;
-  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
-   { (exit 1); exit 1; }; };;
-  :[FH]-) ac_tag=-:-;;
-  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
-  esac
-  ac_save_IFS=$IFS
-  IFS=:
-  set x $ac_tag
-  IFS=$ac_save_IFS
-  shift
-  ac_file=$1
-  shift
-
-  case $ac_mode in
-  :L) ac_source=$1;;
-  :[FH])
-    ac_file_inputs=
-    for ac_f
-    do
-      case $ac_f in
-      -) ac_f="$tmp/stdin";;
-      *) # Look for the file first in the build tree, then in the source tree
-        # (if the path is not absolute).  The absolute path cannot be DOS-style,
-        # because $ac_f cannot contain `:'.
-        test -f "$ac_f" ||
-          case $ac_f in
-          [\\/$]*) false;;
-          *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
-          esac ||
-          { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
-   { (exit 1); exit 1; }; };;
-      esac
-      ac_file_inputs="$ac_file_inputs $ac_f"
-    done
-
-    # Let's still pretend it is `configure' which instantiates (i.e., don't
-    # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
-    configure_input="Generated from "`IFS=:
-         echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
-    if test x"$ac_file" != x-; then
-      configure_input="$ac_file.  $configure_input"
-      { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    fi
-
-    case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin";;
-    esac
-    ;;
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
   esac
 
-  ac_dir=`$as_dirname -- "$ac_file" ||
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$ac_file" : 'X\(//\)[^/]' \| \
         X"$ac_file" : 'X\(//\)$' \| \
-        X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-  { as_dir="$ac_dir"
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
     as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
-        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-      test -d "$as_dir" && break
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
     done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
    { (exit 1); exit 1; }; }; }
+
   ac_builddir=.
 
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
+if test "$ac_dir" != .; then
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
 
 case $srcdir in
-  .)  # We are building in place.
+  .)  # No --srcdir option.  We are building in place.
     ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
 esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
 
-  case $ac_mode in
-  :F)
-  #
-  # CONFIG_FILE
-  #
-
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
 
-case `sed -n '/datarootdir/ {
-  p
-  q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-  ac_datarootdir_hack='
-  s&@datadir@&$datadir&g
-  s&@docdir@&$docdir&g
-  s&@infodir@&$infodir&g
-  s&@localedir@&$localedir&g
-  s&@mandir@&$mandir&g
-    s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
 _ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
 $extrasub
@@ -4494,39 +2080,28 @@ _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
-  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
-
-  rm -f "$tmp/stdin"
-  case $ac_file in
-  -) cat "$tmp/out"; rm -f "$tmp/out";;
-  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
-  esac
- ;;
-
-
-
-  esac
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
 
-done # for ac_tag
+done
+_ACEOF
 
+cat >>$CONFIG_STATUS <<\_ACEOF
 
 { (exit 0); exit 0; }
 _ACEOF
index 09a80ef..9900215 100644 (file)
@@ -1,19 +1,11 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_attr_rewrite.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_attr_rewrite])
 
 if test x$with_[]modname != xno; then
 
-       AC_PROG_CC
-       AC_PROG_CPP
-
-       AC_CHECK_HEADERS(regex.h)
-
-       if test "$ac_cv_header_regex_h" != "yes"; then
-               AC_MSG_RESULT(no regex.h)
-               [ fail=$fail" regex.h" ]
-       fi
+       dnl  This module doesn't need any autoconf test which is not already
+       dnl  in top-level configure.
 
        targetname=modname
 else
@@ -21,20 +13,5 @@ else
        echo \*\*\* module modname is disabled.
 fi
 
-dnl  Don't change this section.
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
-       else
-               AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
-               targetname=""
-       fi
-fi
-
-
-AC_SUBST(attr_rewrite_cflags)
-AC_SUBST(attr_rewrite_ldflags)
-
 AC_SUBST(targetname)
 AC_OUTPUT(Makefile)
index eb55588..ca06e50 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Kostas Kalevras <kkalev@noc.ntua.gr>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "autoconf.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #ifdef HAVE_REGEX_H
 #      include <regex.h>
 #endif
 
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
 #define RLM_REGEX_INPACKET 0
 #define RLM_REGEX_INCONFIG 1
 #define RLM_REGEX_INREPLY  2
 #define RLM_REGEX_INPROXY 3
 #define RLM_REGEX_INPROXYREPLY 4
 
+static const char rcsid[] = "$Id$";
+
 typedef struct rlm_attr_rewrite_t {
        char *attribute;        /* The attribute to search for */
        int  attr_num;          /* The attribute number */
@@ -53,6 +58,7 @@ typedef struct rlm_attr_rewrite_t {
        char *name;             /* The module name */
 } rlm_attr_rewrite_t;
 
+
 static const CONF_PARSER module_config[] = {
   { "attribute", PW_TYPE_STRING_PTR, offsetof(rlm_attr_rewrite_t,attribute), NULL, NULL },
   { "searchfor", PW_TYPE_STRING_PTR, offsetof(rlm_attr_rewrite_t,search), NULL, NULL },
@@ -65,11 +71,12 @@ static const CONF_PARSER module_config[] = {
   { NULL, -1, 0, NULL, NULL }
 };
 
+
 static int attr_rewrite_instantiate(CONF_SECTION *conf, void **instance)
 {
        rlm_attr_rewrite_t *data;
        DICT_ATTR *dattr;
-       const char *instance_name = NULL;
+       char *instance_name = NULL;
 
        /*
         *      Set up a storage area for instance data
@@ -175,7 +182,7 @@ static int do_attr_rewrite(void *instance, REQUEST *request)
        int replace_len = 0;
 
        if ((attr_vp = pairfind(request->config_items, PW_REWRITE_RULE)) != NULL){
-               if (data->name == NULL || strcmp(data->name,attr_vp->vp_strvalue))
+               if (data->name == NULL || strcmp(data->name,attr_vp->strvalue))
                        return RLM_MODULE_NOOP;
        }
 
@@ -230,7 +237,7 @@ static int do_attr_rewrite(void *instance, REQUEST *request)
                        case RLM_REGEX_INPACKET:
                                if (data->attr_num == PW_USER_NAME)
                                        attr_vp = request->username;
-                               else if (data->attr_num == PW_USER_PASSWORD)
+                               else if (data->attr_num == PW_PASSWORD)
                                        attr_vp = request->password;
                                else
                                        tmp = request->packet->vps;
@@ -264,7 +271,7 @@ do_again:
                        DEBUG2("rlm_attr_rewrite: Could not find value pair for attribute %s",data->attribute);
                        return ret;
                }
-               if (attr_vp->vp_strvalue == NULL || attr_vp->length == 0){
+               if (attr_vp->strvalue == NULL || attr_vp->length == 0){
                        DEBUG2("rlm_attr_rewrite: Attribute %s string value NULL or of zero length",data->attribute);
                        return ret;
                }
@@ -282,16 +289,8 @@ do_again:
                        DEBUG2("rlm_attr_rewrite: regcomp() returned error: %s",err_msg);
                        return ret;
                }
-
-               if ((attr_vp->type == PW_TYPE_IPADDR) &&
-                   (attr_vp->vp_strvalue[0] == '\0')) {
-                       inet_ntop(AF_INET, &(attr_vp->vp_ipaddr),
-                                 attr_vp->vp_strvalue,
-                                 sizeof(attr_vp->vp_strvalue));
-               }
-
                ptr = new_str;
-               ptr2 = attr_vp->vp_strvalue;
+               ptr2 = attr_vp->strvalue;
                counter = 0;
 
                for ( i = 0 ;i < (unsigned)data->num_matches; i++) {
@@ -299,7 +298,7 @@ do_again:
                        if (err == REG_NOMATCH) {
                                if (i == 0) {
                                        DEBUG2("rlm_attr_rewrite: No match found for attribute %s with value '%s'",
-                                                       data->attribute, attr_vp->vp_strvalue);
+                                                       data->attribute, attr_vp->strvalue);
                                        regfree(&preg);
                                        goto to_do_again;
                                } else
@@ -308,7 +307,7 @@ do_again:
                        if (err != 0) {
                                regfree(&preg);
                                radlog(L_ERR, "rlm_attr_rewrite: match failure for attribute %s with value '%s'",
-                                               data->attribute, attr_vp->vp_strvalue);
+                                               data->attribute, attr_vp->strvalue);
                                return ret;
                        }
                        if (pmatch[0].rm_so == -1)
@@ -321,13 +320,12 @@ do_again:
                        if (counter >= MAX_STRING_LEN) {
                                regfree(&preg);
                                DEBUG2("rlm_attr_rewrite: Replacement out of limits for attribute %s with value '%s'",
-                                               data->attribute, attr_vp->vp_strvalue);
+                                               data->attribute, attr_vp->strvalue);
                                return ret;
                        }
 
-                       memcpy(ptr, ptr2,len);
+                       strncpy(ptr, ptr2,len);
                        ptr += len;
-                       *ptr = '\0';
                        ptr2 += pmatch[0].rm_eo;
 
                        if (i == 0){
@@ -336,10 +334,10 @@ do_again:
                                 */
                                for(j = 0; j <= REQUEST_MAX_REGEX; j++){
                                        char *p;
-                                       char buffer[sizeof(attr_vp->vp_strvalue)];
+                                       char buffer[sizeof(attr_vp->strvalue)];
 
                                        /*
-                                        * Stolen from src/main/valuepair.c, paircompare()
+                                        * Stolen from src/main/valuepair.c, paircmp()
                                         */
 
                                        /*
@@ -355,7 +353,7 @@ do_again:
                                                break;
                                        }
                                        memcpy(buffer,
-                                              attr_vp->vp_strvalue + pmatch[j].rm_so,
+                                              attr_vp->strvalue + pmatch[j].rm_so,
                                               pmatch[j].rm_eo - pmatch[j].rm_so);
                                        buffer[pmatch[j].rm_eo - pmatch[j].rm_so] = '\0';
                                        p = strdup(buffer);
@@ -377,13 +375,12 @@ do_again:
                        if (counter >= MAX_STRING_LEN) {
                                regfree(&preg);
                                DEBUG2("rlm_attr_rewrite: Replacement out of limits for attribute %s with value '%s'",
-                                               data->attribute, attr_vp->vp_strvalue);
+                                               data->attribute, attr_vp->strvalue);
                                return ret;
                        }
                        if (replace_len){
-                               memcpy(ptr, replace_STR, replace_len);
+                               strncpy(ptr, replace_STR, replace_len);
                                ptr += replace_len;
-                               *ptr = '\0';
                        }
                }
                regfree(&preg);
@@ -391,14 +388,13 @@ do_again:
                counter += len;
                if (counter >= MAX_STRING_LEN){
                        DEBUG2("rlm_attr_rewrite: Replacement out of limits for attribute %s with value '%s'",
-                                       data->attribute, attr_vp->vp_strvalue);
+                                       data->attribute, attr_vp->strvalue);
                        return ret;
                }
-               memcpy(ptr, ptr2, len);
-               ptr[len] = '\0';
+               strncpy(ptr, ptr2, len);
 
                DEBUG2("rlm_attr_rewrite: Changed value for attribute %s from '%s' to '%s'",
-                               data->attribute, attr_vp->vp_strvalue, new_str);
+                               data->attribute, attr_vp->strvalue, new_str);
                if (pairparsevalue(attr_vp, new_str) == NULL) {
                        DEBUG2("rlm_attr_rewrite: Could not write value '%s' into attribute %s: %s", new_str, data->attribute, librad_errstr);
                        return ret;
@@ -417,6 +413,7 @@ to_do_again:
        return ret;
 }
 
+
 static int attr_rewrite_accounting(void *instance, REQUEST *request)
 {
        return do_attr_rewrite(instance, request);
@@ -426,18 +423,15 @@ static int attr_rewrite_authorize(void *instance, REQUEST *request)
 {
        return do_attr_rewrite(instance, request);
 }
-
 static int attr_rewrite_authenticate(void *instance, REQUEST *request)
 {
        return do_attr_rewrite(instance, request);
 }
-
 static int attr_rewrite_preacct(void *instance, REQUEST *request)
 {
        return do_attr_rewrite(instance, request);
 }
-
-static int attr_rewrite_checksimul(void *instance, REQUEST *request)
+static int attr_rewrite_ismul(void *instance, REQUEST *request)
 {
        return do_attr_rewrite(instance, request);
 }
@@ -461,6 +455,12 @@ static int attr_rewrite_detach(void *instance)
 {
        rlm_attr_rewrite_t *data = (rlm_attr_rewrite_t *) instance;
 
+       if (data->attribute)
+               free(data->attribute);
+       if (data->search)
+               free(data->search);
+       if (data->replace)
+               free(data->replace);
        if (data->name)
                free(data->name);
 
@@ -478,19 +478,20 @@ static int attr_rewrite_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_attr_rewrite = {
-       RLM_MODULE_INIT,
        "attr_rewrite",
        RLM_TYPE_THREAD_UNSAFE,         /* type */
+       NULL,                           /* initialization */
        attr_rewrite_instantiate,               /* instantiation */
-       attr_rewrite_detach,                    /* detach */
        {
                attr_rewrite_authenticate,      /* authentication */
                attr_rewrite_authorize,         /* authorization */
                attr_rewrite_preacct,           /* preaccounting */
                attr_rewrite_accounting,        /* accounting */
-               attr_rewrite_checksimul,        /* checksimul */
+               attr_rewrite_ismul,             /* checksimul */
                attr_rewrite_preproxy,          /* pre-proxy */
                attr_rewrite_postproxy,         /* post-proxy */
                attr_rewrite_postauth           /* post-auth */
        },
+       attr_rewrite_detach,                    /* detach */
+       NULL,                           /* destroy */
 };
diff --git a/src/modules/rlm_caching/Makefile.in b/src/modules/rlm_caching/Makefile.in
deleted file mode 100644 (file)
index ff82a91..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# $Id$
-#
-
-TARGET      = @targetname@
-SRCS        = rlm_caching.c
-HEADERS     =
-RLM_CFLAGS  = @caching_cflags@
-RLM_LIBS    = @caching_ldflags@
-RLM_INSTALL =
-
-include ../rules.mak
-
-$(LT_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_caching/rlm_caching.c b/src/modules/rlm_caching/rlm_caching.c
deleted file mode 100644 (file)
index 2f446c4..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * rlm_caching.c
- *
- * Version:  $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2001,2006  The FreeRADIUS server project
- * Copyright 2001  Alan DeKok <aland@ox.org>
- * Copyright 2001-3  Kostas Kalevras <kkalev@noc.ntua.gr>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-#include <ctype.h>
-
-#include "config.h"
-
-#include <gdbm.h>
-#include <time.h>
-
-#ifdef NEEDS_GDBM_SYNC
-#      define GDBM_SYNCOPT GDBM_SYNC
-#else
-#      define GDBM_SYNCOPT 0
-#endif
-
-#ifdef GDBM_NOLOCK
-#define GDBM_COUNTER_OPTS (GDBM_SYNCOPT | GDBM_NOLOCK)
-#else
-#define GDBM_COUNTER_OPTS (GDBM_SYNCOPT)
-#endif
-
-#ifndef HAVE_GDBM_FDESC
-#define gdbm_fdesc(foo) (-1)
-#endif
-
-#define UNIQUEID_MAX_LEN 32
-
-/*
- *     Define a structure for our module configuration.
- *
- *     These variables do not need to be in a structure, but it's
- *     a lot cleaner to do so, and a pointer to the structure can
- *     be used as the instance handle.
- */
-typedef struct rlm_caching_t {
-       char *filename;         /* name of the database file */
-       char *key;              /* An xlated string to use as key for the records */
-       char *post_auth;        /* If set and we find a cached entry, set Post-Auth to this value */
-       char *cache_ttl_str;    /* The string represantation of the TTL */
-       int cache_ttl;          /* The cache TTL */
-       int hit_ratio;          /* Show cache hit ratio every so many queries */
-       int cache_rejects;      /* Do we also cache rejects? */
-       int cache_size;         /* The cache size to pass to GDBM */
-       uint32_t cache_queries; /* The number of cache requests */
-       uint32_t cache_hits;    /* The number of cache hits */
-       GDBM_FILE gdbm;         /* The gdbm file handle */
-#ifdef HAVE_PTHREAD_H
-       pthread_mutex_t mutex;  /* A mutex to lock the gdbm file for only one reader/writer */
-#endif
-} rlm_caching_t;
-
-#define MAX_RECORD_LEN 750
-#define MAX_AUTH_TYPE 32
-
-#define show_hit_ratio \
-       if (data->hit_ratio && (data->cache_queries % data->hit_ratio) == 0) \
-               radlog(L_INFO, "rlm_caching: Cache Queries: %7d, Cache Hits: %7d, Hit Ratio: %.2f%%", \
-                       data->cache_queries,data->cache_hits,hit_ratio)
-
-typedef struct rlm_caching_data {
-       time_t creation;
-       char data[MAX_RECORD_LEN];
-       char auth_type[MAX_AUTH_TYPE];
-       int len;
-} rlm_caching_data;
-
-#ifndef HAVE_PTHREAD_H
-/*
- *     This is a lot simpler than putting ifdef's around
- *     every use of the pthread functions.
- */
-#define pthread_mutex_lock(a)
-#define pthread_mutex_unlock(a)
-#define pthread_mutex_init(a,b)
-#define pthread_mutex_destroy(a)
-#endif
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-  { "filename", PW_TYPE_STRING_PTR, offsetof(rlm_caching_t,filename), NULL, NULL },
-  { "key", PW_TYPE_STRING_PTR, offsetof(rlm_caching_t,key), NULL, "%{Acct-Unique-Session-Id}" },
-  { "post-auth", PW_TYPE_STRING_PTR, offsetof(rlm_caching_t,post_auth), NULL,  NULL },
-  { "cache-ttl", PW_TYPE_STRING_PTR, offsetof(rlm_caching_t,cache_ttl_str), NULL, "1d" },
-  { "cache-size", PW_TYPE_INTEGER, offsetof(rlm_caching_t,cache_size), NULL, "1000" },
-  { "hit-ratio", PW_TYPE_INTEGER, offsetof(rlm_caching_t,hit_ratio), NULL, "0" },
-  { "cache-rejects", PW_TYPE_BOOLEAN, offsetof(rlm_caching_t,cache_rejects), NULL, "yes" },
-  { NULL, -1, 0, NULL, NULL }
-};
-
-static int caching_detach(void *instance);
-
-static int find_ttl(char *ttl)
-{
-       unsigned len = 0;
-       char last = 's';
-
-       if (isdigit((int) ttl[0])){
-               len = strlen(ttl);
-               if (len == 0)
-                       return -1;
-               last = ttl[len - 1];
-               if (!isalpha((int) last))
-                       last = 's';
-               len = atoi(ttl);
-               DEBUG("rlm_caching::find_ttl: num=%d, last=%c",len,last);
-       }
-       switch (last){
-               case 's':
-               default:
-                       break;
-               case 'm':
-                       len *= 60;
-                       break;
-               case 'h':
-                       len *= 3600;
-                       break;
-               case 'd':
-                       len *= 86400;
-                       break;
-               case 'w':
-                       len *= 604800;
-                       break;
-       }
-
-       DEBUG("rlm_caching::find_ttl: Returning '%d'",len);
-
-       return len;
-}
-
-/*
- *     Do any per-module initialization that is separate to each
- *     configured instance of the module.  e.g. set up connections
- *     to external databases, read configuration files, set up
- *     dictionary entries, etc.
- *
- *     If configuration information is given in the config section
- *     that must be referenced in later calls, store a handle to it
- *     in *instance otherwise put a null pointer there.
- */
-static int caching_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_caching_t *data;
-       int cache_size;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       data = rad_malloc(sizeof(*data));
-       if (!data) {
-               radlog(L_ERR, "rlm_caching: rad_malloc() failed.");
-               return -1;
-       }
-       memset(data, 0, sizeof(*data));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, data, module_config) < 0) {
-               free(data);
-               return -1;
-       }
-       cache_size = data->cache_size;
-
-       /*
-        *      Discover the attribute number of the key.
-        */
-       if (data->key == NULL) {
-               radlog(L_ERR, "rlm_caching: 'key' must be set.");
-               caching_detach(data);
-               return -1;
-       }
-       if (data->cache_ttl_str == NULL) {
-               radlog(L_ERR, "rlm_caching: 'cache-ttl' must be set.");
-               caching_detach(data);
-               return -1;
-       }
-       else {
-               data->cache_ttl = find_ttl(data->cache_ttl_str);
-               if (data->cache_ttl == 0) {
-                       radlog(L_ERR, "rlm_caching: 'cache-ttl' is invalid.");
-                       caching_detach(data);
-                       return -1;
-               }
-       }
-
-       if (data->filename == NULL) {
-               radlog(L_ERR, "rlm_caching: 'filename' must be set.");
-               caching_detach(data);
-               return -1;
-       }
-       data->gdbm = gdbm_open(data->filename, sizeof(int),
-                       GDBM_WRCREAT | GDBM_COUNTER_OPTS, 0600, NULL);
-       if (data->gdbm == NULL) {
-               radlog(L_ERR, "rlm_caching: Failed to open file %s: %s",
-                               data->filename, strerror(errno));
-               caching_detach(data);
-               return -1;
-       }
-       if (gdbm_setopt(data->gdbm, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1)
-               radlog(L_ERR, "rlm_caching: Failed to set cache size");
-
-       /*
-        * Init the mutex
-        */
-       pthread_mutex_init(&data->mutex, NULL);
-
-       *instance = data;
-
-       return 0;
-}
-
-/*
- *     Cache the reply items and the Auth-Type
- */
-static int caching_postauth(void *instance, REQUEST *request)
-{
-       rlm_caching_t *data = (rlm_caching_t *)instance;
-       char key[MAX_STRING_LEN];
-       datum key_datum;
-       datum data_datum;
-       VALUE_PAIR *reply_vp;
-       VALUE_PAIR *auth_type;
-       rlm_caching_data cache_data;
-       int count = 0;
-       int ret = 0;
-       int size = 0;
-       int rcode = 0;
-
-       if (pairfind(request->packet->vps, PW_CACHE_NO_CACHING) != NULL){
-               DEBUG("rlm_caching: Cache-No-Caching is set. Returning NOOP");
-               return RLM_MODULE_NOOP;
-       }
-       if ((auth_type = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL){
-               DEBUG("rlm_caching: Found Auth-Type, value: '%s'",auth_type->vp_strvalue);
-               if (strcmp(auth_type->vp_strvalue,"Reject") == 0 && data->cache_rejects == 0){
-                       DEBUG("rlm_caching: No caching of Rejects. Returning NOOP");
-                       return RLM_MODULE_NOOP;
-               }
-               if (strlen(auth_type->vp_strvalue) > MAX_AUTH_TYPE - 1){
-                       DEBUG("rlm_caching: Auth-Type value too large");
-                       return RLM_MODULE_NOOP;
-               }
-       }
-       else{
-               DEBUG("rlm_caching: No Auth-Type found. Returning NOOP");
-               return RLM_MODULE_NOOP;
-       }
-
-       reply_vp = request->reply->vps;
-
-       if (reply_vp == NULL) {
-               DEBUG("rlm_caching: The Request does not contain any reply attributes");
-               return RLM_MODULE_NOOP;
-       }
-       if (!radius_xlat(key,sizeof(key), data->key, request, NULL)){
-               radlog(L_ERR, "rlm_caching: xlat on key '%s' failed.",data->key);
-               return RLM_MODULE_FAIL;
-       }
-
-       memset(&cache_data,0,sizeof(rlm_caching_data));
-
-       cache_data.creation = time(NULL);
-       strcpy(cache_data.auth_type,auth_type->vp_strvalue);
-
-       size = MAX_RECORD_LEN;
-
-       while(reply_vp) {
-               if (size <= 1){
-                       DEBUG("rlm_caching: Not enough space.");
-                       return RLM_MODULE_NOOP;
-               }
-               ret = vp_prints(cache_data.data + count,size,reply_vp);
-               if (ret == 0) {
-                       DEBUG("rlm_caching: Record is too large, will not store it.");
-                       return RLM_MODULE_NOOP;
-               }
-               count += (ret + 1);
-               size -= (ret + 1);
-               DEBUG("rlm_caching: VP=%s,VALUE=%s,length=%d,cache record length=%d, space left=%d",
-                       reply_vp->name,reply_vp->vp_strvalue,ret,count,size);
-               reply_vp = reply_vp->next;
-       }
-       cache_data.len = count;
-
-       DEBUG("rlm_caching: Storing cache for Key='%s'",key);
-       data_datum.dptr = (rlm_caching_data *) &cache_data;
-       data_datum.dsize = sizeof(rlm_caching_data);
-
-       key_datum.dptr = (char *) key;
-       key_datum.dsize = strlen(key);
-
-       pthread_mutex_lock(&data->mutex);
-       rcode = gdbm_store(data->gdbm, key_datum, data_datum, GDBM_REPLACE);
-       pthread_mutex_unlock(&data->mutex);
-       if (rcode < 0) {
-               radlog(L_ERR, "rlm_caching: Failed storing data to %s: %s",
-                               data->filename, gdbm_strerror(gdbm_errno));
-               return RLM_MODULE_FAIL;
-       }
-       DEBUG("rlm_caching: New value stored successfully.");
-
-       return RLM_MODULE_OK;
-}
-
-/*
- *     Find the named user in this modules database.  Create the set
- *     of attribute-value pairs to check and reply with for this user
- *     from the database. The authentication code only needs to check
- *     the password, the rest is done here.
- */
-static int caching_authorize(void *instance, REQUEST *request)
-{
-       rlm_caching_t *data = (rlm_caching_t *) instance;
-       char key[MAX_STRING_LEN];
-       datum key_datum;
-       datum data_datum;
-       rlm_caching_data cache_data;
-       VALUE_PAIR *reply_item;
-       VALUE_PAIR *item;
-       char *tmp;
-       int len = 0;
-       int delete_cache = 0;
-       float hit_ratio = 0.0;
-
-       /* quiet the compiler */
-       instance = instance;
-       request = request;
-
-       if (pairfind(request->packet->vps, PW_CACHE_NO_CACHING) != NULL){
-               DEBUG("rlm_caching: Cache-No-Caching is set. Returning NOOP");
-               return RLM_MODULE_NOOP;
-       }
-       if (pairfind(request->packet->vps, PW_CACHE_DELETE_CACHE) != NULL){
-               DEBUG("rlm_caching: Found Cache-Delete-Cache. Will delete record if found");
-               delete_cache = 1;
-       }
-
-       if (!radius_xlat(key,sizeof(key), data->key, request, NULL)){
-               radlog(L_ERR, "rlm_caching: xlat on key '%s' failed.",data->key);
-               return RLM_MODULE_FAIL;
-       }
-
-       key_datum.dptr = key;
-       key_datum.dsize = strlen(key);
-
-
-       DEBUG("rlm_caching: Searching the database for key '%s'",key);
-       pthread_mutex_lock(&data->mutex);
-       data_datum = gdbm_fetch(data->gdbm, key_datum);
-       pthread_mutex_unlock(&data->mutex);
-       data->cache_queries++;
-       if (data_datum.dptr != NULL){
-               DEBUG("rlm_caching: Key Found.");
-               data->cache_hits++;
-               hit_ratio = (float)data->cache_hits / data->cache_queries;
-               hit_ratio *= 100.0;
-               memcpy(&cache_data, data_datum.dptr, sizeof(rlm_caching_data));
-               free(data_datum.dptr);
-
-               if (delete_cache == 0 && cache_data.creation + data->cache_ttl <= time(NULL)){
-                       DEBUG("rlm_caching: Cache entry has expired");
-                       DEBUG("rlm_caching: Cache Queries: %7d, Cache Hits: %7d, Hit Ratio: %.2f%%",
-                       data->cache_queries,data->cache_hits,hit_ratio);
-                       show_hit_ratio;
-                       delete_cache = 1;
-               }
-               if (delete_cache){
-                       DEBUG("rlm_caching: Deleting record");
-
-                       pthread_mutex_lock(&data->mutex);
-                       gdbm_delete(data->gdbm, key_datum);
-                       pthread_mutex_unlock(&data->mutex);
-
-                       return RLM_MODULE_NOOP;
-               }
-               tmp = cache_data.data;
-               if (tmp){
-                       pairfree(&request->reply->vps);
-                       while(tmp && len < cache_data.len){
-                               reply_item = NULL;
-                               if (userparse(tmp, &reply_item) > 0 && reply_item != NULL)
-                                       pairadd(&request->reply->vps, reply_item);
-                               len += (strlen(tmp) + 1);
-                               DEBUG("rlm_caching: VP='%s',VALUE='%s',lenth='%d',cache record length='%d'",
-                               reply_item->name,reply_item->vp_strvalue,reply_item->length,len);
-                               tmp = cache_data.data + len;
-                       }
-               }
-               else{
-                       DEBUG("rlm_caching: No reply items found. Returning NOOP");
-                       return RLM_MODULE_NOOP;
-               }
-               if (cache_data.auth_type){
-                       DEBUG("rlm_caching: Adding Auth-Type '%s'",cache_data.auth_type);
-
-                       if ((item = pairfind(request->config_items, PW_AUTH_TYPE)) == NULL){
-                               item = pairmake("Auth-Type", cache_data.auth_type, T_OP_SET);
-                               pairadd(&request->config_items, item);
-                       }
-                       else{
-                               strcmp(item->vp_strvalue, cache_data.auth_type);
-                               item->length = strlen(cache_data.auth_type);
-                       }
-               }
-               if (data->post_auth){
-                       DEBUG("rlm_caching: Adding Post-Auth-Type '%s'",data->post_auth);
-
-                       if ((item = pairfind(request->config_items, PW_POST_AUTH_TYPE)) == NULL){
-                               item = pairmake("Post-Auth-Type", data->post_auth, T_OP_SET);
-                               pairadd(&request->config_items, item);
-                       }
-                       else{
-                               strcmp(item->vp_strvalue, data->post_auth);
-                               item->length = strlen(data->post_auth);
-                       }
-               }
-               item = pairmake("Cache-No-Caching", "YES", T_OP_EQ);
-               pairadd(&request->packet->vps, item);
-
-               DEBUG("rlm_caching: Cache Queries: %7d, Cache Hits: %7d, Hit Ratio: %.2f%%",
-                       data->cache_queries,data->cache_hits,hit_ratio);
-               show_hit_ratio;
-
-               return RLM_MODULE_OK;
-       }
-       else{
-               DEBUG("rlm_caching: Could not find the requested key in the database.");
-               DEBUG("rlm_caching: Cache Queries: %7d, Cache Hits: %7d, Hit Ratio: %.2f%%",
-                       data->cache_queries,data->cache_hits,hit_ratio);
-               show_hit_ratio;
-       }
-
-       return RLM_MODULE_NOOP;
-}
-
-static int caching_detach(void *instance)
-{
-       rlm_caching_t *data = (rlm_caching_t *) instance;
-
-       if (data->gdbm)
-               gdbm_close(data->gdbm);
-       pthread_mutex_destroy(&data->mutex);
-
-       free(instance);
-       return 0;
-}
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- *
- *     If the module needs to temporarily modify it's instantiation
- *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
- *     The server will then take care of ensuring that the module
- *     is single-threaded.
- */
-module_t rlm_caching = {
-       RLM_MODULE_INIT,
-       "Caching",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       caching_instantiate,            /* instantiation */
-       caching_detach,                 /* detach */
-       {
-               NULL,                   /* authentication */
-               caching_authorize,      /* authorization */
-               NULL,                   /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               caching_postauth        /* post-auth */
-       },
-};
index c38967c..44ea3b5 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2001  Kostas Kalevras <kkalev@noc.ntua.gr>
  *
  * Nov 03 2001, Kostas Kalevras <kkalev@noc.ntua.gr>
  * - Added module messages when rejecting user
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
 
 static int chap_authorize(void *instance, REQUEST *request)
 {
@@ -38,7 +45,8 @@ static int chap_authorize(void *instance, REQUEST *request)
        instance = instance;
        request = request;
 
-       if (!pairfind(request->packet->vps, PW_CHAP_PASSWORD)) {
+       if (!request->password ||
+           request->password->attribute != PW_CHAP_PASSWORD) {
                return RLM_MODULE_NOOP;
        }
 
@@ -62,8 +70,8 @@ static int chap_authorize(void *instance, REQUEST *request)
  */
 static int chap_authenticate(void *instance, REQUEST *request)
 {
-       VALUE_PAIR *passwd_item, *chap;
-       uint8_t pass_str[MAX_STRING_LEN];
+       VALUE_PAIR *passwd_item;
+       char pass_str[MAX_STRING_LEN];
        VALUE_PAIR *module_fmsg_vp;
        char module_fmsg[MAX_STRING_LEN];
 
@@ -76,19 +84,18 @@ static int chap_authenticate(void *instance, REQUEST *request)
                return RLM_MODULE_INVALID;
        }
 
-       chap = pairfind(request->packet->vps, PW_CHAP_PASSWORD);
-       if (!chap) {
+       if (!request->password) {
                radlog(L_AUTH, "rlm_chap: Attribute \"CHAP-Password\" is required for authentication.");
                return RLM_MODULE_INVALID;
        }
 
-       if (chap->length == 0) {
-               radlog(L_ERR, "rlm_chap: empty password supplied");
+       if (request->password->attribute != PW_CHAP_PASSWORD) {
+               radlog(L_AUTH, "rlm_chap: Attribute \"CHAP-Password\" is required for authentication. Cannot use \"%s\".", request->password->name);
                return RLM_MODULE_INVALID;
        }
 
-       if (chap->length != CHAP_VALUE_LENGTH + 1) {
-               radlog(L_ERR, "rlm_chap: password supplied has wrong length");
+       if (request->password->length == 0) {
+               radlog(L_ERR, "rlm_chap: empty password supplied");
                return RLM_MODULE_INVALID;
        }
 
@@ -96,37 +103,30 @@ static int chap_authenticate(void *instance, REQUEST *request)
         *      Don't print out the CHAP password here.  It's binary crap.
         */
        DEBUG("  rlm_chap: login attempt by \"%s\" with CHAP password",
-               request->username->vp_strvalue);
-
-       if ((passwd_item = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD)) == NULL){
-         DEBUG("  rlm_chap: Cleartext-Password is required for authentication");
-               snprintf(module_fmsg, sizeof(module_fmsg),
-                        "rlm_chap: Clear text password not available");
-               module_fmsg_vp = pairmake("Module-Failure-Message",
-                                         module_fmsg, T_OP_EQ);
+               request->username->strvalue);
+
+       if ((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL){
+               DEBUG("  rlm_chap: Could not find clear text password for user %s",request->username->strvalue);
+               snprintf(module_fmsg,sizeof(module_fmsg),"rlm_chap: Clear text password not available");
+               module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
                pairadd(&request->packet->vps, module_fmsg_vp);
                return RLM_MODULE_INVALID;
        }
 
        DEBUG("  rlm_chap: Using clear text password \"%s\" for user %s authentication.",
-             passwd_item->vp_strvalue, request->username->vp_strvalue);
+             passwd_item->strvalue, request->username->strvalue);
 
-       rad_chap_encode(request->packet,pass_str,
-                       chap->vp_octets[0],passwd_item);
+       rad_chap_encode(request->packet,pass_str,request->password->strvalue[0],passwd_item);
 
-       if (memcmp(pass_str + 1, chap->vp_octets + 1,
-                  CHAP_VALUE_LENGTH) != 0){
+       if (memcmp(pass_str+1,request->password->strvalue+1,CHAP_VALUE_LENGTH) != 0){
                DEBUG("  rlm_chap: Password check failed");
-               snprintf(module_fmsg, sizeof(module_fmsg),
-                        "rlm_chap: Wrong user password");
-               module_fmsg_vp = pairmake("Module-Failure-Message",
-                                         module_fmsg, T_OP_EQ);
+               snprintf(module_fmsg,sizeof(module_fmsg),"rlm_chap: Wrong user password");
+               module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
                pairadd(&request->packet->vps, module_fmsg_vp);
                return RLM_MODULE_REJECT;
        }
 
-       DEBUG("  rlm_chap: chap user %s authenticated succesfully",
-             request->username->vp_strvalue);
+       DEBUG("  rlm_chap: chap user %s authenticated succesfully",request->username->strvalue);
 
        return RLM_MODULE_OK;
 }
@@ -141,11 +141,10 @@ static int chap_authenticate(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_chap = {
-        RLM_MODULE_INIT,
        "CHAP",
        0,                              /* type */
+       NULL,                           /* initialization */
        NULL,                           /* instantiation */
-       NULL,                           /* detach */
        {
                chap_authenticate,      /* authentication */
                chap_authorize,         /* authorization */
@@ -156,4 +155,6 @@ module_t rlm_chap = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       NULL,                           /* detach */
+       NULL,                           /* destroy */
 };
index c022199..e5cf75d 100644 (file)
@@ -4,10 +4,6 @@
 
 TARGET      = @targetname@
 SRCS        = rlm_checkval.c
-HEADERS     =
-RLM_CFLAGS  = @checkval_cflags@
-RLM_LIBS    = @checkval_ldflags@
-RLM_INSTALL =
 
 include ../rules.mak
 
index 81980e0..ba7ed70 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.4 .
+# From configure.in Revision: 1.2.6.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -273,7 +273,7 @@ PACKAGE_STRING=
 PACKAGE_BUGREPORT=
 
 ac_unique_file="rlm_checkval.c"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP checkval_cflags checkval_ldflags targetname LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS targetname LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -714,26 +714,6 @@ ac_env_target_alias_set=${target_alias+set}
 ac_env_target_alias_value=$target_alias
 ac_cv_env_target_alias_set=${target_alias+set}
 ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
 
 #
 # Report the --help message.
@@ -801,18 +781,6 @@ if test -n "$ac_init_help"; then
 
   cat <<\_ACEOF
 
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
-              headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
 _ACEOF
 fi
 
@@ -901,7 +869,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1253,1164 +1221,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 if test x$with_rlm_checkval != xno; then
 
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  test -n "$ac_ct_CC" && break
-done
-
-  CC=$ac_ct_CC
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
-  (eval $ac_link_default) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Find the output, starting from the most likely.  This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
-       ;;
-    conftest.$ac_ext )
-       # This is the source file.
-       ;;
-    [ab].out )
-       # We found the default executable, but exeext='' is most
-       # certainly right.
-       break;;
-    *.* )
-       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       # FIXME: I believe we export ac_cv_exeext for Libtool,
-       # but it would be cool to find out if it's true.  Does anybody
-       # maintain Libtool? --akim.
-       export ac_cv_exeext
-       break;;
-    * )
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-         export ac_cv_exeext
-         break;;
-    * ) break;;
-  esac
-done
-else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std1 is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std1.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX                  -qlanglvl=ansi
-# Ultrix and OSF/1     -std1
-# HP-UX 10.20 and later        -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4                 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_stdc=$ac_arg
-break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
-  x|xno)
-    echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
-  *)
-    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
-    CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
-# Some people use a C++ compiler to compile C.  Since we use `exit',
-# in C++ we need to declare it.  In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
-  choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  for ac_declaration in \
-   '' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
-fi
-
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether non-existent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether non-existent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
-else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
 
        targetname=rlm_checkval
 else
@@ -2418,24 +1228,6 @@ else
        echo \*\*\* module rlm_checkval is disabled.
 fi
 
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               { { echo "$as_me:$LINENO: error: set --without-rlm_checkval to disable it explicitly." >&5
-echo "$as_me: error: set --without-rlm_checkval to disable it explicitly." >&2;}
-   { (exit 1); exit 1; }; }
-       else
-               { echo "$as_me:$LINENO: WARNING: silently not building rlm_checkval." >&5
-echo "$as_me: WARNING: silently not building rlm_checkval." >&2;}
-               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_checkval requires: $fail." >&5
-echo "$as_me: WARNING: FAILURE: rlm_checkval requires: $fail." >&2;};
-               targetname=""
-       fi
-fi
-
-
-
-
-
 
           ac_config_files="$ac_config_files Makefile"
 cat >confcache <<\_ACEOF
@@ -3072,16 +1864,6 @@ s,@ECHO_C@,$ECHO_C,;t t
 s,@ECHO_N@,$ECHO_N,;t t
 s,@ECHO_T@,$ECHO_T,;t t
 s,@LIBS@,$LIBS,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@CPP@,$CPP,;t t
-s,@checkval_cflags@,$checkval_cflags,;t t
-s,@checkval_ldflags@,$checkval_ldflags,;t t
 s,@targetname@,$targetname,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
@@ -3247,6 +2029,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3285,12 +2072,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 3363ff5..f334371 100644 (file)
@@ -1,12 +1,11 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_checkval.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_checkval])
 
 if test x$with_[]modname != xno; then
 
-       AC_PROG_CC
-       AC_PROG_CPP
+       dnl  This module doesn't need any autoconf test which is not already
+       dnl  in top-level configure.
 
        targetname=modname
 else
@@ -14,20 +13,5 @@ else
        echo \*\*\* module modname is disabled.
 fi
 
-dnl  Don't change this section.
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
-       else
-               AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
-               targetname=""
-       fi
-fi
-
-
-AC_SUBST(checkval_cflags)
-AC_SUBST(checkval_ldflags)
-
 AC_SUBST(targetname)
 AC_OUTPUT(Makefile)
index 60b9994..aac33ec 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  * Copyright 2003  Kostas Kalevras <kkalev@noc.ntua.gr>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 #ifdef HAVE_REGEX_H
 #      include <regex.h>
 #endif
@@ -63,7 +67,7 @@ typedef struct rlm_checkval_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "item-name",  PW_TYPE_STRING_PTR, offsetof(rlm_checkval_t,item_name), NULL,  NULL},
   { "check-name",  PW_TYPE_STRING_PTR, offsetof(rlm_checkval_t,check_name), NULL,  NULL},
   { "data-type",    PW_TYPE_STRING_PTR, offsetof(rlm_checkval_t,data_type),NULL, "integer"},
@@ -74,6 +78,15 @@ static const CONF_PARSER module_config[] = {
 
 static int checkval_detach(void *instance)
 {
+       rlm_checkval_t *data = (rlm_checkval_t *) instance;
+
+       if (data->item_name)
+               free((char *)data->item_name);
+       if (data->check_name)
+               free((char *)data->check_name);
+       if (data->data_type)
+               free((char *)data->data_type);
+
        free(instance);
        return 0;
 }
@@ -214,7 +227,7 @@ static int do_checkval(void *instance, REQUEST *request)
                        ret = RLM_MODULE_NOTFOUND;
        }
        if (item_vp)
-               DEBUG2("rlm_checkval: Item Name: %s, Value: %s",data->item_name, item_vp->vp_strvalue);
+               DEBUG2("rlm_checkval: Item Name: %s, Value: %s",data->item_name, item_vp->strvalue);
        tmp = request->config_items;
        do{
                if (!(chk_vp = pairfind(tmp, data->chk_attr))){
@@ -226,12 +239,10 @@ static int do_checkval(void *instance, REQUEST *request)
                }
                if (!item_vp)
                        break;
-               DEBUG2("rlm_checkval: Value Name: %s, Value: %s",data->check_name, chk_vp->vp_strvalue);
+               DEBUG2("rlm_checkval: Value Name: %s, Value: %s",data->check_name, chk_vp->strvalue);
 
                /*
                * Check if item != check
-               *
-               *       FIXME:  !!! Call normal API functions!
                */
                found = 1;
                if (data->dat_type == PW_TYPE_STRING ||
@@ -239,20 +250,17 @@ static int do_checkval(void *instance, REQUEST *request)
                        if (item_vp->length != chk_vp->length)
                                ret = RLM_MODULE_REJECT;
                        else{
-                               if (!memcmp(item_vp->vp_strvalue,
-                                           chk_vp->vp_strvalue,
+                               if (!memcmp(item_vp->strvalue,
+                                           chk_vp->strvalue,
                                            (size_t) chk_vp->length))
                                        ret = RLM_MODULE_OK;
                                else
                                        ret = RLM_MODULE_REJECT;
                        }
-               } else if (data->dat_type == PW_TYPE_DATE) {
-                       if (item_vp->vp_date == chk_vp->vp_date)
-                               ret = RLM_MODULE_OK;
-                       else
-                               ret = RLM_MODULE_REJECT;
-               } else if (data->dat_type == PW_TYPE_INTEGER) {
-                       if (item_vp->vp_integer == chk_vp->vp_integer)
+               }
+               else{   /* Integer or Date */
+
+                       if (item_vp->lvalue == chk_vp->lvalue)
                                ret = RLM_MODULE_OK;
                        else
                                ret = RLM_MODULE_REJECT;
@@ -265,13 +273,13 @@ static int do_checkval(void *instance, REQUEST *request)
                        char err_msg[MAX_STRING_LEN];
 
                        DEBUG("rlm_checkval: Doing regex");
-                       err = regcomp(&reg, (char *)chk_vp->vp_strvalue, REG_EXTENDED|REG_NOSUB);
+                       err = regcomp(&reg, (char *)chk_vp->strvalue, REG_EXTENDED|REG_NOSUB);
                        if (err){
                                regerror(err, &reg,err_msg, MAX_STRING_LEN);
                                DEBUG("rlm_checkval: regcomp() returned error: %s", err_msg);
                                return RLM_MODULE_FAIL;
                        }
-                       if (regexec(&reg, (char *)item_vp->vp_strvalue,0, NULL, 0) == 0)
+                       if (regexec(&reg, (char *)item_vp->strvalue,0, NULL, 0) == 0)
                                ret = RLM_MODULE_OK;
                        else
                                ret = RLM_MODULE_REJECT;
@@ -329,11 +337,10 @@ static int checkval_accounting(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_checkval = {
-        RLM_MODULE_INIT,
        "checkval",
        0,              /* type */
+       NULL,                           /* initialization */
        checkval_instantiate,           /* instantiation */
-       checkval_detach,                /* detach */
        {
                NULL,                   /* authentication */
                checkval_authorize,     /* authorization */
@@ -344,4 +351,6 @@ module_t rlm_checkval = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       checkval_detach,                /* detach */
+       NULL,                           /* destroy */
 };
diff --git a/src/modules/rlm_copy_packet/Makefile b/src/modules/rlm_copy_packet/Makefile
deleted file mode 100644 (file)
index 2b182ac..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile
-#
-# Version:     $Id$
-#
-
-TARGET         = rlm_copy_packet
-SRCS           = rlm_copy_packet.c
-
-include ../rules.mak
diff --git a/src/modules/rlm_copy_packet/README b/src/modules/rlm_copy_packet/README
deleted file mode 100644 (file)
index e2fe1bb..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-  This module initializes the Access-Accept packet by copying all of
-the attributes from the Access-Request to the Access-Accept.
-
-  It should be listed in the "authorize" section of "radiusd.conf",
-probably after "preprocess", but before any other module.
-
-
-       authorize {
-               ...
-
-               copy_packet
-
-               ...
-       }
-
-  It currently takes no configuration, so the sub-section of the
-"modules" section should look like:
-
-       modules {
-               ...
-
-               copy_packet {
-               }
-
-               ...
-       }
diff --git a/src/modules/rlm_copy_packet/rlm_copy_packet.c b/src/modules/rlm_copy_packet/rlm_copy_packet.c
deleted file mode 100644 (file)
index 48e536c..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * rlm_copy_packet.c
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004,2006  The FreeRADIUS server project
- * Copyright 2004  Alan DeKok <aland@cladju.com>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-/*
- *     Define a structure for our module configuration.
- *
- *     It doesn't take any configuration right now...
- */
-typedef struct rlm_packet_t {
-       char            *string;
-} rlm_packet_t;
-
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-  { "string",  PW_TYPE_STRING_PTR, offsetof(rlm_packet_t,string), NULL,  NULL},
-
-  { NULL, -1, 0, NULL, NULL }          /* end the list */
-};
-
-
-static int packet_detach(void *instance)
-{
-       free(instance);
-       return 0;
-}
-
-
-/*
- *     Do any per-module initialization that is separate to each
- *     configured instance of the module.  e.g. set up connections
- *     to external databases, read configuration files, set up
- *     dictionary entries, etc.
- *
- *     If configuration information is given in the config section
- *     that must be referenced in later calls, store a handle to it
- *     in *instance otherwise put a null pointer there.
- */
-static int packet_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_packet_t *inst;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       inst = rad_malloc(sizeof(*inst));
-       if (!inst) {
-               return -1;
-       }
-       memset(inst, 0, sizeof(*inst));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, inst, module_config) < 0) {
-               packet_detach(inst);
-               return -1;
-       }
-
-       *instance = inst;
-
-       return 0;
-}
-
-
-/*
- *     Initialize the reply with the request.
- */
-static int packet_authorize(void *instance, REQUEST *request)
-{
-       VALUE_PAIR      *vps;
-
-       instance = instance;    /* -Wunused */
-
-       vps = paircopy(request->packet->vps);
-       pairadd(&(request->reply->vps), vps);
-       return RLM_MODULE_UPDATED;
-}
-
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- *
- *     If the module needs to temporarily modify it's instantiation
- *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
- *     The server will then take care of ensuring that the module
- *     is single-threaded.
- */
-module_t rlm_copy_packet = {
-        RLM_MODULE_INIT,
-       "copy_packet",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       packet_instantiate,             /* instantiation */
-       packet_detach,                  /* detach */
-       {
-               NULL,                   /* authentication */
-               packet_authorize,       /* authorization */
-               NULL,                   /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
-};
diff --git a/src/modules/rlm_counter/acconfig.h b/src/modules/rlm_counter/acconfig.h
new file mode 100644 (file)
index 0000000..376f75b
--- /dev/null
@@ -0,0 +1,5 @@
+/* do we need GDBM_SYNC */
+#undef NEED_GDBM_SYNC
+
+/* do we have gdbm_fdesc */
+#undef HAVE_GDBM_FDESC
index 32fad9e..072ac27 100644 (file)
@@ -1,22 +1,7 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
-
-/* do we have gdbm_fdesc */
-#undef HAVE_GDBM_FDESC
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
 
 /* do we need GDBM_SYNC */
 #undef NEED_GDBM_SYNC
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+/* do we have gdbm_fdesc */
+#undef HAVE_GDBM_FDESC
index c988de6..2c05d8a 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.11 .
+# From configure.in Revision: 1.9 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -901,7 +901,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1821,7 +1821,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1879,7 +1880,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1995,7 +1997,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2049,7 +2052,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2094,7 +2098,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2138,7 +2143,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2451,7 +2457,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2474,8 +2481,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2504,7 +2511,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2582,7 +2590,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2605,8 +2614,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2658,7 +2667,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2681,8 +2691,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2711,7 +2721,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2816,7 +2827,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2839,8 +2851,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -2895,8 +2907,7 @@ _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   $EGREP "found-gdbm-sync" >/dev/null 2>&1; then
 
-
-cat >>confdefs.h <<\_ACEOF
+                       cat >>confdefs.h <<\_ACEOF
 #define NEED_GDBM_SYNC yes
 _ACEOF
 
@@ -2981,7 +2992,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3008,9 +3020,8 @@ echo "${ECHO_T}$ac_cv_func_gdbm_fdesc" >&6
 
        if test "x$ac_cv_func_gdbm_fdesc" = "xyes";
        then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GDBM_FDESC
+               cat >>confdefs.h <<\_ACEOF
+#define HAVE_GDBM_FDESC 1
 _ACEOF
 
        fi
@@ -3830,6 +3841,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3868,12 +3884,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index d513474..4783219 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_counter.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_counter])
@@ -8,8 +7,8 @@ if test x$with_[]modname != xno; then
        AC_PROG_CC
        AC_PROG_CPP
 
-       FR_SMART_CHECK_INCLUDE(gdbm.h)
-       FR_SMART_CHECK_LIB(gdbm, gdbm_open)
+       AC_SMART_CHECK_INCLUDE(gdbm.h)
+       AC_SMART_CHECK_LIB(gdbm, gdbm_open)
        if test "x$ac_cv_lib_gdbm_gdbm_open" != "xyes"; then
                fail="$fail libgdbm"
        fi
@@ -24,7 +23,7 @@ if test x$with_[]modname != xno; then
        not found.  this version must use sync by default.
 #endif
                        ], [
-                       AC_DEFINE(NEED_GDBM_SYNC, yes, [do we need GDBM_SYNC])
+                       AC_DEFINE(NEED_GDBM_SYNC, yes
                        AC_MSG_RESULT(needs it.)
                        ], [
                        AC_MSG_RESULT(SYNCs by default.)
@@ -37,7 +36,7 @@ if test x$with_[]modname != xno; then
        AC_CHECK_FUNC(gdbm_fdesc)
        if test "x$ac_cv_func_gdbm_fdesc" = "xyes";
        then
-               AC_DEFINE(HAVE_GDBM_FDESC, [], [do we have gdbm_fdesc])
+               AC_DEFINE(HAVE_GDBM_FDESC)
        fi
        LIBS=$old_LIBS
 
@@ -52,7 +51,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index b0f9ab8..ccaf8ed 100755 (executable)
@@ -9,28 +9,13 @@ use Getopt::Long;
 
 my $user = '';
 my $divisor = 1;
-my $reset = 0;
 my $match = '.*';
-my $help = 0;
 
 #
 #  This should be fixed...
 #
 $filename = '';
 
-sub show_help {
-    print "Usage: $0 --file=<counter filename> [--reset=<seconds>] [--match=<regexp>]\n";
-    print "[--user=<username>] [--help] [--hours|--minutes|--seconds]\n\n";
-    print "--user=<username>", "\t\t", "Information for specific user\n";
-    print "--file=<filename>", "\t\t", "Counter db filename\n";
-    print "--match=<regexp>", "\t\t", "Information for matching users\n";
-    print "--reset=<number>", "\t\t", "Reset counter to <number>.\n";
-    print "\t\t\t\t", "If divisor is set use it, else <number> means seconds\n";
-    print "--help", "\t\t\t\t", "Show this help screen\n";
-    print "--(hours|minutes|seconds)", "\t", "Specify information divisor\n";
-    exit 0;
-}
-
 #
 #  Print out only one user,
 #
@@ -39,37 +24,27 @@ sub show_help {
 GetOptions ('user=s'  => \$user,
            'match=s' => \$match,
            'file=s'  => \$filename,
-            'reset=i' => \$reset,
-            'help'    => \$help,
            'hours'   => sub { $divisor = 3600 },
            'minutes' => sub { $divisor = 60 },
            'seconds' => sub { $divisor = 1 } );
 
-show_help if ($help || $filename eq '');
+#
+#  For now, this must be specified by hand.
+#
+if ($filename eq '') {
+    die "You MUST specify the DB filename via: --file = <filename>\n";
+}
 
 #
 #  Open the file.
 #
-if ($reset){
-    my $db = tie(%hash, 'GDBM_File', $filename, O_RDWR, 0666) or die "Cannot open $filename: $!\n";
-}else{
-    my $db = tie(%hash, 'GDBM_File', $filename, O_RDONLY, 0666) or die "Cannot open $filename: $!\n";
-}
+my $db = tie(%hash, 'GDBM_File', $filename, O_RDONLY, 0666) or die "Cannot open$filename: $!\n";
 
 #
 #  If given one name, give the seconds
 #
 if ($user ne '') {
-    if (defined($hash{$user})){
-        print $user, "\t\t", int ( unpack('L',$hash{$user}) / $divisor), "\n";
-       if ($reset){
-            my $uniqueid = (unpack('L A32',$hash{$user}))[1];
-            $hash{$user} = pack('L A32',$reset * $divisor,$uniqueid);
-            print $user, "\t\t", "Counter reset to ", $reset * $divisor, "\n";
-        }
-    }else{
-        print $user, "\t\t", "Not found\n";
-    }
+    print $user, "\t\t", int ( unpack('L',$hash{$user}) / $divisor), "\n";
 
     undef $db;
     untie %hash;
@@ -94,11 +69,6 @@ foreach $key (sort keys %hash) {
     #
     #  Print out the names...
     print $key, "\t\t", int ( unpack('L',$hash{$key}) / $divisor), "\n";
-    if ($reset){
-        my $uniqueid = (unpack('L A32',$hash{$key}))[1];
-        $hash{$key} = pack('L A32',$reset * $divisor,$uniqueid);
-        print $key, "\t\t", "Counter reset to ", $reset * $divisor, "\n";
-    }
 }
 undef $db;
 untie %hash;
index 45c70f6..7480475 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2001  Alan DeKok <aland@ox.org>
  * Copyright 2001-3  Kostas Kalevras <kkalev@noc.ntua.gr>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "config.h"
+#include "autoconf.h"
+#include "libradius.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
-#include "config.h"
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 
 #include <gdbm.h>
+#include <time.h>
 
 #ifdef NEEDS_GDBM_SYNC
 #      define GDBM_SYNCOPT GDBM_SYNC
@@ -52,6 +56,8 @@ RCSID("$Id$")
 
 #define UNIQUEID_MAX_LEN 32
 
+static const char rcsid[] = "$Id$";
+
 /*
  *     Define a structure for our module configuration.
  *
@@ -66,14 +72,12 @@ typedef struct rlm_counter_t {
        char *count_attribute;  /* Acct-Session-Time */
        char *counter_name;     /* Daily-Session-Time */
        char *check_name;       /* Daily-Max-Session */
-       char *reply_name;       /* Session-Timeout */
        char *service_type;     /* Service-Type to search for */
        int cache_size;
        int service_val;
        int key_attr;
        int count_attr;
        int check_attr;
-       int reply_attr;
        time_t reset_time;      /* The time of the next reset. */
        time_t last_reset;      /* The time of the last reset. */
        int dict_attr;          /* attribute number for the counter. */
@@ -108,14 +112,13 @@ typedef struct rad_counter {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "filename", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,filename), NULL, NULL },
   { "key", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,key_name), NULL, NULL },
   { "reset", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,reset), NULL,  NULL },
   { "count-attribute", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,count_attribute), NULL, NULL },
   { "counter-name", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,counter_name), NULL,  NULL },
   { "check-name", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,check_name), NULL, NULL },
-  { "reply-name", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,reply_name), NULL, NULL },
   { "allowed-servicetype", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,service_type),NULL, NULL },
   { "cache-size", PW_TYPE_INTEGER, offsetof(rlm_counter_t,cache_size), NULL, "1000" },
   { NULL, -1, 0, NULL, NULL }
@@ -150,7 +153,7 @@ static int counter_cmp(void *instance,
                return RLM_MODULE_NOOP;
        }
 
-       key_datum.dptr = key_vp->vp_strvalue;
+       key_datum.dptr = key_vp->strvalue;
        key_datum.dsize = key_vp->length;
 
        count_datum = gdbm_fetch(data->gdbm, key_datum);
@@ -161,7 +164,7 @@ static int counter_cmp(void *instance,
        memcpy(&counter, count_datum.dptr, sizeof(rad_counter));
        free(count_datum.dptr);
 
-       return counter.user_counter - check->vp_integer;
+       return counter.user_counter - check->lvalue;
 }
 
 
@@ -238,21 +241,21 @@ static int reset_db(rlm_counter_t *data)
 
 static int find_next_reset(rlm_counter_t *data, time_t timeval)
 {
-       int ret = 0;
-       size_t len;
-       unsigned int num = 1;
-       char last = '\0';
+       int ret=0;
+       unsigned int num=1;
+       char last = 0;
        struct tm *tm, s_tm;
        char sCurrentTime[40], sNextTime[40];
 
        tm = localtime_r(&timeval, &s_tm);
-       len = strftime(sCurrentTime, sizeof(sCurrentTime), "%Y-%m-%d %H:%M:%S", tm);
-       if (len == 0) *sCurrentTime = '\0';
+       strftime(sCurrentTime, sizeof(sCurrentTime),"%Y-%m-%d %H:%M:%S",tm);
        tm->tm_sec = tm->tm_min = 0;
 
        if (data->reset == NULL)
                return -1;
        if (isdigit((int) data->reset[0])){
+               unsigned int len=0;
+
                len = strlen(data->reset);
                if (len == 0)
                        return -1;
@@ -294,11 +297,9 @@ static int find_next_reset(rlm_counter_t *data, time_t timeval)
                        data->reset);
                return -1;
        }
-
-       len = strftime(sNextTime, sizeof(sNextTime), "%Y-%m-%d %H:%M:%S", tm);
-       if (len == 0) *sNextTime = '\0';
-       DEBUG2("rlm_counter: Current Time: %li [%s], Next reset %li [%s]",
-               timeval, sCurrentTime, data->reset_time, sNextTime);
+       strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
+       DEBUG2("rlm_counter: Current Time: %d [%s], Next reset %d [%s]",
+               (int)timeval,sCurrentTime,(int)data->reset_time,sNextTime);
 
        return ret;
 }
@@ -383,27 +384,6 @@ static int counter_instantiate(CONF_SECTION *conf, void **instance)
        data->count_attr = dattr->attr;
 
        /*
-        * Discover the attribute number of the reply attribute.
-        */
-       if (data->reply_name != NULL) {
-               dattr = dict_attrbyname(data->reply_name);
-               if (dattr == NULL) {
-                       radlog(L_ERR, "rlm_counter: No such attribute %s",
-                                       data->reply_name);
-                       counter_detach(data);
-                       return -1;
-               }
-               if (dattr->type != PW_TYPE_INTEGER) {
-                       radlog(L_ERR, "rlm_counter: Reply attribute %s is not of type integer",
-                               data->reply_name);
-                       counter_detach(data);
-                       return -1;
-               }
-               data->reply_attr = dattr->attr;
-       }
-
-
-       /*
         *  Create a new attribute for the counter.
         */
        if (data->counter_name == NULL) {
@@ -573,7 +553,7 @@ static int counter_accounting(void *instance, REQUEST *request)
        time_t diff;
 
        if ((key_vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL)
-               acctstatustype = key_vp->vp_integer;
+               acctstatustype = key_vp->lvalue;
        else {
                DEBUG("rlm_counter: Could not find account status type in packet.");
                return RLM_MODULE_NOOP;
@@ -584,7 +564,7 @@ static int counter_accounting(void *instance, REQUEST *request)
        }
        uniqueid_vp = pairfind(request->packet->vps, PW_ACCT_UNIQUE_SESSION_ID);
        if (uniqueid_vp != NULL)
-               DEBUG("rlm_counter: Packet Unique ID = '%s'",uniqueid_vp->vp_strvalue);
+               DEBUG("rlm_counter: Packet Unique ID = '%s'",uniqueid_vp->strvalue);
 
        /*
         *      Before doing anything else, see if we have to reset
@@ -610,7 +590,7 @@ static int counter_accounting(void *instance, REQUEST *request)
                        DEBUG("rlm_counter: Could not find Service-Type attribute in the request. Returning NOOP.");
                        return RLM_MODULE_NOOP;
                }
-               if ((unsigned)proto_vp->vp_integer != data->service_val){
+               if ((unsigned)proto_vp->lvalue != data->service_val){
                        DEBUG("rlm_counter: This Service-Type is not allowed. Returning NOOP.");
                        return RLM_MODULE_NOOP;
                }
@@ -621,8 +601,8 @@ static int counter_accounting(void *instance, REQUEST *request)
         */
        key_vp = pairfind(request->packet->vps, PW_ACCT_DELAY_TIME);
        if (key_vp != NULL){
-               if (key_vp->vp_integer != 0 &&
-                   (request->timestamp - key_vp->vp_integer) < data->last_reset){
+               if (key_vp->lvalue != 0 &&
+                   (request->timestamp - key_vp->lvalue) < data->last_reset){
                        DEBUG("rlm_counter: This packet is too old. Returning NOOP.");
                        return RLM_MODULE_NOOP;
                }
@@ -649,10 +629,10 @@ static int counter_accounting(void *instance, REQUEST *request)
                return RLM_MODULE_NOOP;
        }
 
-       key_datum.dptr = key_vp->vp_strvalue;
+       key_datum.dptr = key_vp->strvalue;
        key_datum.dsize = key_vp->length;
 
-       DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->vp_strvalue);
+       DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->strvalue);
        pthread_mutex_lock(&data->mutex);
        count_datum = gdbm_fetch(data->gdbm, key_datum);
        pthread_mutex_unlock(&data->mutex);
@@ -660,8 +640,7 @@ static int counter_accounting(void *instance, REQUEST *request)
                DEBUG("rlm_counter: Could not find the requested key in the database.");
                counter.user_counter = 0;
                if (uniqueid_vp != NULL)
-                       strlcpy(counter.uniqueid,uniqueid_vp->vp_strvalue,
-                               sizeof(counter.uniqueid));
+                       strncpy(counter.uniqueid,uniqueid_vp->strvalue,UNIQUEID_MAX_LEN - 1);
                else
                        memset((char *)counter.uniqueid,0,UNIQUEID_MAX_LEN);
        }
@@ -673,14 +652,13 @@ static int counter_accounting(void *instance, REQUEST *request)
                        DEBUG("rlm_counter: Counter Unique ID = '%s'",counter.uniqueid);
                if (uniqueid_vp != NULL){
                        if (counter.uniqueid != NULL &&
-                               strncmp(uniqueid_vp->vp_strvalue,counter.uniqueid, UNIQUEID_MAX_LEN - 1) == 0){
+                               strncmp(uniqueid_vp->strvalue,counter.uniqueid, UNIQUEID_MAX_LEN - 1) == 0){
                                DEBUG("rlm_counter: Unique IDs for user match. Droping the request.");
                                return RLM_MODULE_NOOP;
                        }
-                       strlcpy(counter.uniqueid,uniqueid_vp->vp_strvalue,
-                               sizeof(counter.uniqueid));
+                       strncpy(counter.uniqueid,uniqueid_vp->strvalue,UNIQUEID_MAX_LEN - 1);
                }
-               DEBUG("rlm_counter: User=%s, Counter=%d.",request->username->vp_strvalue,counter.user_counter);
+               DEBUG("rlm_counter: User=%s, Counter=%d.",request->username->strvalue,counter.user_counter);
        }
 
        if (data->count_attr == PW_ACCT_SESSION_TIME) {
@@ -695,14 +673,14 @@ static int counter_accounting(void *instance, REQUEST *request)
                 *      day). That is the right thing
                 */
                diff = request->timestamp - data->last_reset;
-               counter.user_counter += (count_vp->vp_integer < diff) ? count_vp->vp_integer : diff;
+               counter.user_counter += (count_vp->lvalue < diff) ? count_vp->lvalue : diff;
 
        } else if (count_vp->type == PW_TYPE_INTEGER) {
                /*
                 *      Integers get counted, without worrying about
                 *      reset dates.
                 */
-               counter.user_counter += count_vp->vp_integer;
+               counter.user_counter += count_vp->lvalue;
 
        } else {
                /*
@@ -712,7 +690,7 @@ static int counter_accounting(void *instance, REQUEST *request)
                counter.user_counter++;
        }
 
-       DEBUG("rlm_counter: User=%s, New Counter=%d.",request->username->vp_strvalue,counter.user_counter);
+       DEBUG("rlm_counter: User=%s, New Counter=%d.",request->username->strvalue,counter.user_counter);
        count_datum.dptr = (char *) &counter;
        count_datum.dsize = sizeof(rad_counter);
 
@@ -788,7 +766,7 @@ static int counter_authorize(void *instance, REQUEST *request)
                return ret;
        }
 
-       key_datum.dptr = key_vp->vp_strvalue;
+       key_datum.dptr = key_vp->strvalue;
        key_datum.dsize = key_vp->length;
 
 
@@ -798,7 +776,7 @@ static int counter_authorize(void *instance, REQUEST *request)
 
        counter.user_counter = 0;
 
-       DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->vp_strvalue);
+       DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->strvalue);
        pthread_mutex_lock(&data->mutex);
        count_datum = gdbm_fetch(data->gdbm, key_datum);
        pthread_mutex_unlock(&data->mutex);
@@ -813,8 +791,8 @@ static int counter_authorize(void *instance, REQUEST *request)
        /*
         * Check if check item > counter
         */
-       DEBUG("rlm_counter: Check item = %d, Count = %d",check_vp->vp_integer,counter.user_counter);
-       res=check_vp->vp_integer - counter.user_counter;
+       DEBUG("rlm_counter: Check item = %d, Count = %d",check_vp->lvalue,counter.user_counter);
+       res=check_vp->lvalue - counter.user_counter;
        if (res > 0) {
                DEBUG("rlm_counter: res is greater than zero");
                if (data->count_attr == PW_ACCT_SESSION_TIME) {
@@ -839,31 +817,22 @@ static int counter_authorize(void *instance, REQUEST *request)
                        *       If we are near a reset then add the next
                        *       limit, so that the user will not need to
                        *       login again
-                       *       Before that set the return value to the time
-                       *       remaining to next reset
                        */
                        if (data->reset_time && (
                                res >= (data->reset_time - request->timestamp))) {
-                               res = data->reset_time - request->timestamp;
-                               res += check_vp->vp_integer;
+                               res += check_vp->lvalue;
                        }
 
                        if ((reply_item = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL) {
-                               if (reply_item->vp_integer > res)
-                                       reply_item->vp_integer = res;
+                               if (reply_item->lvalue > res)
+                                       reply_item->lvalue = res;
                        } else {
-                               reply_item = radius_paircreate(request, &request->reply->vps, PW_SESSION_TIMEOUT, PW_TYPE_INTEGER);
-                               reply_item->vp_integer = res;
-                       }
-               }
-               else if (data->reply_attr) {
-                       if ((reply_item = pairfind(request->reply->vps, data->reply_attr)) != NULL) {
-                               if (reply_item->vp_integer > res)
-                                       reply_item->vp_integer = res;
-                       }
-                       else {
-                               reply_item = radius_paircreate(request, &request->reply->vps, data->reply_attr, PW_TYPE_INTEGER);
-                               reply_item->vp_integer = res;
+                               if ((reply_item = paircreate(PW_SESSION_TIMEOUT, PW_TYPE_INTEGER)) == NULL) {
+                                       radlog(L_ERR|L_CONS, "no memory");
+                                       return RLM_MODULE_NOOP;
+                               }
+                               reply_item->lvalue = res;
+                               pairadd(&request->reply->vps, reply_item);
                        }
                }
 
@@ -871,9 +840,9 @@ static int counter_authorize(void *instance, REQUEST *request)
 
                DEBUG2("rlm_counter: (Check item - counter) is greater than zero");
                DEBUG2("rlm_counter: Authorized user %s, check_item=%d, counter=%d",
-                               key_vp->vp_strvalue,check_vp->vp_integer,counter.user_counter);
+                               key_vp->strvalue,check_vp->lvalue,counter.user_counter);
                DEBUG2("rlm_counter: Sent Reply-Item for user %s, Type=Session-Timeout, value=%d",
-                               key_vp->vp_strvalue,res);
+                               key_vp->strvalue,res);
        }
        else{
                char module_fmsg[MAX_STRING_LEN];
@@ -893,7 +862,7 @@ static int counter_authorize(void *instance, REQUEST *request)
                ret=RLM_MODULE_REJECT;
 
                DEBUG2("rlm_counter: Rejected user %s, check_item=%d, counter=%d",
-                               key_vp->vp_strvalue,check_vp->vp_integer,counter.user_counter);
+                               key_vp->strvalue,check_vp->lvalue,counter.user_counter);
        }
 
        return ret;
@@ -906,6 +875,13 @@ static int counter_detach(void *instance)
        paircompare_unregister(data->dict_attr, counter_cmp);
        if (data->gdbm)
                gdbm_close(data->gdbm);
+       free(data->filename);
+       free(data->reset);
+       free(data->key_name);
+       free(data->count_attribute);
+       free(data->counter_name);
+       free(data->check_name);
+       free(data->service_type);
        pthread_mutex_destroy(&data->mutex);
 
        free(instance);
@@ -922,11 +898,10 @@ static int counter_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_counter = {
-        RLM_MODULE_INIT,
-       "counter",
+       "Counter",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        counter_instantiate,            /* instantiation */
-       counter_detach,                 /* detach */
        {
                NULL,                   /* authentication */
                counter_authorize,      /* authorization */
@@ -937,4 +912,6 @@ module_t rlm_counter = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       counter_detach,                 /* detach */
+       NULL,                           /* destroy */
 };
index 0ccc170..f36d8ef 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  */
 
 /*
  *   (c) 2002 by SANDY (http://www.sandy.ru/) under GPL
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include       "autoconf.h"
+#include       "libradius.h"
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <ctype.h>
 
-#include        <freeradius-devel/md5.h>
+#include       "radiusd.h"
+#include       "modules.h"
 
-#include       <ctype.h>
+#include        "md4.h"
+#include        "md5.h"
+#include        "sha1.h"
 
 
 #define                SM_AUTHTYPE     ((11406<<16)|101)
@@ -127,14 +132,14 @@ static void calc_sha1_digest(char * buffer, const char * challenge, int challen,
 }
 
 
-static int cram_authenticate(UNUSED void * instance, REQUEST *request)
+static int cram_authenticate(void * instance, REQUEST *request)
 {
        VALUE_PAIR *authtype, *challenge, *response, *password;
        char buffer[64];
 
-       password = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
+       password = pairfind(request->config_items, PW_PASSWORD);
        if(!password) {
-               radlog(L_AUTH, "rlm_cram: Cleartext-Password is required for authentication.");
+               radlog(L_AUTH, "rlm_cram: Password is not configured for user");
                return RLM_MODULE_INVALID;
        }
        authtype = pairfind(request->packet->vps, SM_AUTHTYPE);
@@ -152,38 +157,38 @@ static int cram_authenticate(UNUSED void * instance, REQUEST *request)
                radlog(L_AUTH, "rlm_cram: Required attribute Sandy-Mail-Response missed");
                return RLM_MODULE_INVALID;
        }
-       switch(authtype->vp_integer){
+       switch(authtype->lvalue){
                case 2:                         /*      CRAM-MD5        */
                        if(challenge->length < 5 || response->length != 16) {
                                radlog(L_AUTH, "rlm_cram: invalid MD5 challenge/response length");
                                return RLM_MODULE_INVALID;
                        }
-                       calc_md5_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue);
-                       if(!memcmp(buffer, response->vp_strvalue, 16)) return RLM_MODULE_OK;
+                       calc_md5_digest(buffer, challenge->strvalue, challenge->length, password->strvalue);
+                       if(!memcmp(buffer, response->strvalue, 16)) return RLM_MODULE_OK;
                        break;
                case 3:                         /*      APOP    */
                        if(challenge->length < 5 || response->length != 16) {
                                radlog(L_AUTH, "rlm_cram: invalid APOP challenge/response length");
                                return RLM_MODULE_INVALID;
                        }
-                       calc_apop_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue);
-                       if(!memcmp(buffer, response->vp_strvalue, 16)) return RLM_MODULE_OK;
+                       calc_apop_digest(buffer, challenge->strvalue, challenge->length, password->strvalue);
+                       if(!memcmp(buffer, response->strvalue, 16)) return RLM_MODULE_OK;
                        break;
                case 8:                         /*      CRAM-MD4        */
                        if(challenge->length < 5 || response->length != 16) {
                                radlog(L_AUTH, "rlm_cram: invalid MD4 challenge/response length");
                                return RLM_MODULE_INVALID;
                        }
-                       calc_md4_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue);
-                       if(!memcmp(buffer, response->vp_strvalue, 16)) return RLM_MODULE_OK;
+                       calc_md4_digest(buffer, challenge->strvalue, challenge->length, password->strvalue);
+                       if(!memcmp(buffer, response->strvalue, 16)) return RLM_MODULE_OK;
                        break;
                case 9:                         /*      CRAM-SHA1       */
                        if(challenge->length < 5 || response->length != 20) {
                                radlog(L_AUTH, "rlm_cram: invalid MD4 challenge/response length");
                                return RLM_MODULE_INVALID;
                        }
-                       calc_sha1_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue);
-                       if(!memcmp(buffer, response->vp_strvalue, 20)) return RLM_MODULE_OK;
+                       calc_sha1_digest(buffer, challenge->strvalue, challenge->length, password->strvalue);
+                       if(!memcmp(buffer, response->strvalue, 20)) return RLM_MODULE_OK;
                        break;
                default:
                        radlog(L_AUTH, "rlm_cram: unsupported Sandy-Mail-Authtype");
@@ -194,19 +199,20 @@ static int cram_authenticate(UNUSED void * instance, REQUEST *request)
 }
 
 module_t rlm_cram = {
-       RLM_MODULE_INIT,
-       "CRAM",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       NULL,                           /* instantiation */
-       NULL,                           /* detach */
-       {
-               cram_authenticate,      /* authenticate */
-               NULL,                   /* authorize */
-               NULL,                   /* pre-accounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "CRAM",
+  RLM_TYPE_THREAD_SAFE,                                /* type */
+  NULL,                                /* initialize */
+  NULL,                /* instantiation */
+  {
+         cram_authenticate,    /* authenticate */
+         NULL,                 /* authorize */
+         NULL,                 /* pre-accounting */
+         NULL,                 /* accounting */
+         NULL,                 /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  NULL,                                /* detach */
+  NULL,                                /* destroy */
 };
index 3cbf230..2d1554d 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.13 .
+# From configure.in Revision: 1.12 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -907,7 +907,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1827,7 +1827,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1885,7 +1886,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2001,7 +2003,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2055,7 +2058,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2100,7 +2104,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2144,7 +2149,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2498,7 +2504,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2521,8 +2528,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2551,7 +2558,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2629,7 +2637,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2652,8 +2661,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2708,7 +2717,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2731,8 +2741,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2761,7 +2771,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2839,7 +2850,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2862,8 +2874,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2919,7 +2931,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2942,8 +2955,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2972,7 +2985,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3050,7 +3064,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3073,8 +3088,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -3121,7 +3136,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3185,7 +3201,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3208,8 +3225,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -3238,7 +3255,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3343,7 +3361,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3366,8 +3385,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -3420,7 +3439,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3443,8 +3463,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -3473,7 +3493,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3578,7 +3599,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3601,8 +3623,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -3655,7 +3677,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3678,8 +3701,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -3708,7 +3731,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3813,7 +3837,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3836,8 +3861,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -4702,6 +4727,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4740,12 +4770,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 45f1f17..1aa5340 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_dbm.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_dbm])
@@ -41,16 +40,16 @@ if test x$with_[]modname != xno; then
        )
 
        smart_try_dir=$rlm_dbm_include_dir
-       FR_SMART_CHECK_INCLUDE(ndbm.h)
+       AC_SMART_CHECK_INCLUDE(ndbm.h)
        if test "x$ac_cv_header_ndbm_h" = "xyes"; then
           SMART_CFLAGS="${SMART_CFLAGS} -DHAVE_NDBM_H"
        else
-               FR_SMART_CHECK_INCLUDE(gdbm/ndbm.h)
+               AC_SMART_CHECK_INCLUDE(gdbm/ndbm.h)
                if test "x$ac_cv_header_gdbm_ndbm_h" = "xyes"; then
                        SMART_CFLAGS="${SMART_CFLAGS} -DHAVE_GDBM_NDBM_H"
                else
                        ac_cv_header_gdbm_ndbm_h="bad autoconf assumption"
-                       FR_SMART_CHECK_INCLUDE(gdbm-ndbm.h)
+                       AC_SMART_CHECK_INCLUDE(gdbm-ndbm.h)
                        if test "x$ac_cv_header_gdbmmndbm_h" = "xyes"; then
                                SMART_CFLAGS="${SMART_CFLAGS} -DHAVE_GDBMNDBM_H"
                        else
@@ -63,13 +62,13 @@ if test x$with_[]modname != xno; then
                AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
        if test "x$ac_cv_lib_default_dbm_open" != "xyes"; then
                smart_try_dir=$rlm_dbm_lib_dir
-               FR_SMART_CHECK_LIB(ndbm, dbm_open)
+               AC_SMART_CHECK_LIB(ndbm, dbm_open)
                if test "x$ac_cv_lib_ndbm_dbm_open" != "xyes"; then
                        dnl GNU DBM < 1.8.1
-                       FR_SMART_CHECK_LIB(gdbm, dbm_open)
+                       AC_SMART_CHECK_LIB(gdbm, dbm_open)
                        if test "x$ac_cv_lib_gdbm_dbm_open" != "xyes"; then
                                dnl GNU DBM >= 1.8.1
-                               FR_SMART_CHECK_LIB(gdbm_compat, dbm_open)
+                               AC_SMART_CHECK_LIB(gdbm_compat, dbm_open)
                                if test "x$ac_cv_lib_gdbm_compat_dbm_open" != "xyes"; then
                                        fail="$fail (libndbm or libgdbm or libgdbm_compat)"
                                fi
@@ -84,7 +83,7 @@ else
 fi
 
 if test x"$fail" != x""; then
-       AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+       AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
        if test x"${enable_strict_dependencies}" = x"yes"; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
index ed48ff3..9ee2859 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001 Koulik Andrei, Sandy Service
- * Copyright 2006 The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <string.h>
+#include <stdlib.h>
 
 #ifdef HAVE_NDBM_H
 #include <ndbm.h>
@@ -41,10 +37,16 @@ RCSID("$Id$")
 
 #include <fcntl.h>
 
+#include "libradius.h"
+#include "radiusd.h"
+#include "modules.h"
+
 #ifdef SANDY_MOD
 #      include "sandymod.h"
 #endif
 
+static const char rcsid[] = "$Id$";
+
 #define MYDBM  DBM
 #define get_user_content dbm_fetch
 
@@ -70,7 +72,7 @@ typedef struct user_entry {
 } SM_USER_ENTRY;
 
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
         { "usersfile",     PW_TYPE_STRING_PTR,offsetof(struct rlm_dbm_t,userfile),
                NULL, "/etc/uf" },
         { NULL, -1, 0, NULL, NULL }
@@ -132,7 +134,7 @@ static int isfallthrough(VALUE_PAIR *vp) {
   VALUE_PAIR * tmp;
 
   tmp = pairfind(vp, PW_FALL_THROUGH);
-  return tmp ? tmp -> vp_integer : 1; /* if no  FALL_THROUGH - keep looking */
+  return tmp ? tmp -> lvalue : 1; /* if no  FALL_THROUGH - keep looking */
 }
 
 /* sm_parse_user
@@ -197,7 +199,7 @@ static int sm_parse_user(DBM *pdb, const char * username, VALUE_PAIR const* requ
                DEBUG2("parse buffer: <<%s>>\n",beg);
 
                retcod = userparse(beg,&vp);
-               if ( retcod == T_OP_INVALID ) librad_perror("parse error ");
+               if ( retcod == T_INVALID ) librad_perror("parse error ");
 
                switch ( retcod ) {
                        case T_COMMA: break; /* continue parse the current list */
@@ -205,7 +207,7 @@ static int sm_parse_user(DBM *pdb, const char * username, VALUE_PAIR const* requ
                                        if ( parse_state == SMP_PATTERN ) { /* pattern line found */
                                                DEBUG2("process pattern");
                                                /* check pattern against request */
-                                               if ( paircompare(NULL, request, vp, reply ) == 0 ) {
+                                               if ( paircmp(NULL, request, vp, reply ) == 0 ) {
                                                        DEBUG2("rlm_dbm: Pattern matched, look for request");
                                                        pairmove(&tmp_config, &vp);
                                                        pairfree(&vp);
@@ -223,9 +225,9 @@ static int sm_parse_user(DBM *pdb, const char * username, VALUE_PAIR const* requ
                                                join_attr = vp;
                                                while( (join_attr = pairfind(join_attr,SM_JOIN_ATTR) ) != NULL ) {
                                                        DEBUG2("rlm_dbm: Proccess nested record: username %s",
-                                                               (char *)join_attr->vp_strvalue);
+                                                               (char *)join_attr->strvalue);
                                                        /* res =  RLM_MODULE_NOTFOUND; */
-                                                       res =  sm_parse_user(pdb, (char *)join_attr->vp_strvalue, request, &tmp_config,
+                                                       res =  sm_parse_user(pdb, (char *)join_attr->strvalue, request, &tmp_config,
                                                                        &nu_reply, ulist);
                                                        DEBUG("rlm_dbm: recived: %d\n",res);
                                                        switch ( res ) {
@@ -322,7 +324,7 @@ static int rlm_dbm_authorize(void *instance, REQUEST *request)
          *      Grab the canonical user name.
          */
         namepair = request->username;
-        name = namepair ? (char *) namepair->vp_strvalue : "NONE";
+        name = namepair ? (char *) namepair->strvalue : "NONE";
 
        DEBUG2("rlm_dbm: try open database file: %s\n",inst -> userfile);
 
@@ -358,6 +360,7 @@ static int rlm_dbm_authorize(void *instance, REQUEST *request)
 static int rlm_dbm_detach(void *instance)
 {
        struct rlm_dbm_t *inst = instance;
+       free(inst -> userfile);
        free(inst);
        return 0;
 }
@@ -365,11 +368,10 @@ static int rlm_dbm_detach(void *instance)
 
 /* globally exported name */
 module_t rlm_dbm = {
-       RLM_MODULE_INIT,
         "dbm",
         0,                              /* type: reserved */
+        NULL,                           /* initialization */
         rlm_dbm_instantiate,            /* instantiation */
-        rlm_dbm_detach,                 /* detach */
         {
                 NULL,                   /* authentication */
                 rlm_dbm_authorize,      /* authorization */
@@ -380,4 +382,6 @@ module_t rlm_dbm = {
                 NULL,                  /* post-proxy */
                 NULL                   /* post-auth */
        },
+        rlm_dbm_detach,                 /* detach */
+       NULL                            /* destroy */
 };
index bdc13d5..ca02ee1 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001 Koulik Andrei, Sandy Service
  */
 
-#include <freeradius-devel/libradius.h>
+#include "autoconf.h"
 #include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #ifdef HAVE_NDBM_H
 #include <ndbm.h>
@@ -35,6 +38,7 @@
 #include <gdbm-ndbm.h>
 #endif
 
+#include <unistd.h>
 #include <ctype.h>
 
 #define LOTSTUP        20
@@ -65,11 +69,7 @@ static void dump_record(datum key,datum data)
        putchar('\n');
 }
 
-#ifdef __GNUC__
-static void __attribute__((noreturn)) usage(void)
-#else
 static void usage(void)
-#endif
 {
        fprintf(stderr, "Usage: %s: [-f file] [-w] [-i number] [-l number] [-v]\n\n",progname);
 
index 2bed25a..5053db4 100644 (file)
@@ -15,7 +15,7 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001 Koulik Andrei, Sandy Service
  */
 char sccsid[] =
 "$Id$ sandy module project\n Copyright 2001 Sandy Service\nCopyright 2001 Koulik Andrei";
 
-#include <freeradius-devel/radiusd.h>
+#include "autoconf.h"
 #include <fcntl.h>
 
+#include <stdlib.h>
+
 #ifdef HAVE_NDBM_H
 #include <ndbm.h>
 #endif
@@ -39,10 +41,15 @@ char sccsid[] =
 #include <gdbm-ndbm.h>
 #endif
 
+#include <stdio.h>
 #include <ctype.h>
+#include <string.h>
+
+#include "conf.h"
+#include "radpaths.h"
+#include "missing.h"
 
-#include <freeradius-devel/conf.h>
-#include <freeradius-devel/radpaths.h>
+#include "radiusd.h"
 
 #define        MAX_BUFF_SIZE   1024
 
@@ -72,13 +79,14 @@ unsigned long       st_errors = 0,
 
 /*  test
 
-int dumplist(VALUE_PAIR *vp)
-{
-       char buffer[1024];
+int dumplist(VALUE_PAIR *vp) {
+
        while (vp != NULL) {
-               vp_prints(buffer, sizeof(buffer), vp);
 
-               printf("\t%s\n", buffer);
+               printf("VP: name: %s\nattribute: %d\ntype: %d\nlvalue: %lu"
+                       "\noperator %d\naddport: %d\nValue: %s\n",
+                       vp -> name, vp -> attribute, vp -> type, vp -> lvalue,
+                       vp -> operator, vp -> addport, (char*)vp -> strvalue);
                vp = vp -> next;
        }
        return 0;
index f4eec15..2aa3820 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
 #include       <sys/stat.h>
+#include       <sys/select.h>
+
+#include       <stdlib.h>
+#include       <string.h>
 #include       <ctype.h>
 #include       <fcntl.h>
 
+#include       "radiusd.h"
+#include       "modules.h"
 #define        DIRLEN  8192
 
 static const char *packet_codes[] = {
@@ -62,31 +66,21 @@ struct detail_instance {
        /* last made directory */
        char *last_made_directory;
 
-       /* timestamp & stuff */
-       char *header;
-
        /* if we want file locking */
        int locking;
 
-       /* log src/dst information */
-       int log_srcdst;
-
        lrad_hash_table_t *ht;
 };
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        { "detailfile",    PW_TYPE_STRING_PTR,
          offsetof(struct detail_instance,detailfile), NULL, "%A/%{Client-IP-Address}/detail" },
-       { "header",    PW_TYPE_STRING_PTR,
-         offsetof(struct detail_instance,header), NULL, "%t" },
        { "detailperm",    PW_TYPE_INTEGER,
          offsetof(struct detail_instance,detailperm), NULL, "0600" },
        { "dirperm",       PW_TYPE_INTEGER,
          offsetof(struct detail_instance,dirperm),    NULL, "0755" },
        { "locking",       PW_TYPE_BOOLEAN,
          offsetof(struct detail_instance,locking),    NULL, "no" },
-       { "log_packet_header",       PW_TYPE_BOOLEAN,
-         offsetof(struct detail_instance,log_srcdst),    NULL, "no" },
        { NULL, -1, 0, NULL, NULL }
 };
 
@@ -97,7 +91,10 @@ static const CONF_PARSER module_config[] = {
 static int detail_detach(void *instance)
 {
         struct detail_instance *inst = instance;
+       free((char *) inst->detailfile);
+
        free((char*) inst->last_made_directory);
+
        if (inst->ht) lrad_hash_table_free(inst->ht);
 
         free(inst);
@@ -105,15 +102,21 @@ static int detail_detach(void *instance)
 }
 
 
-static uint32_t detail_hash(const void *data)
+/*
+ *     Hash callback functions.  Copied from src/lib/dict.c
+ */
+static uint32_t dict_attr_value_hash(const void *data)
 {
-       const DICT_ATTR *da = data;
-       return lrad_hash(&(da->attr), sizeof(da->attr));
+       return lrad_hash(&((const DICT_ATTR *)data)->attr,
+                        sizeof(((const DICT_ATTR *)data)->attr));
 }
 
-static int detail_cmp(const void *a, const void *b)
+static int dict_attr_value_cmp(const void *one, const void *two)
 {
-       return ((const DICT_ATTR *)a)->attr - ((const DICT_ATTR *)b)->attr;
+       const DICT_ATTR *a = one;
+       const DICT_ATTR *b = two;
+
+       return a->attr - b->attr;
 }
 
 
@@ -145,7 +148,8 @@ static int detail_instantiate(CONF_SECTION *conf, void **instance)
        if (cs) {
                CONF_ITEM       *ci;
 
-               inst->ht = lrad_hash_table_create(detail_hash, detail_cmp,
+               inst->ht = lrad_hash_table_create(dict_attr_value_hash,
+                                                 dict_attr_value_cmp,
                                                  NULL);
 
                for (ci = cf_item_find_next(cs, NULL);
@@ -155,7 +159,7 @@ static int detail_instantiate(CONF_SECTION *conf, void **instance)
                        DICT_ATTR       *da;
 
                        if (!cf_item_is_pair(ci)) continue;
-
+                                               
                        attr = cf_pair_attr(cf_itemtopair(ci));
                        if (!attr) continue; /* pair-anoia */
 
@@ -165,12 +169,6 @@ static int detail_instantiate(CONF_SECTION *conf, void **instance)
                                continue;
                        }
 
-                       /*
-                        *      For better distribution we should really
-                        *      hash the attribute number or name.  But
-                        *      since the suppression list will usually
-                        *      be small, it doesn't matter.
-                        */
                        if (!lrad_hash_table_insert(inst->ht, da)) {
                                radlog(L_ERR, "rlm_detail: Failed trying to remember %s", attr);
                                detail_detach(inst);
@@ -192,13 +190,14 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
 {
        int             outfd;
        FILE            *outfp;
-       char            timestamp[256];
        char            buffer[DIRLEN];
        char            *p;
        struct stat     st;
        int             locked;
        int             lock_count;
        struct timeval  tv;
+       REALM           *proxy_realm;
+       char            proxy_buffer[16];
        VALUE_PAIR      *pair;
 
        struct detail_instance *inst = instance;
@@ -245,7 +244,15 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
                 */
                if ((inst->last_made_directory == NULL) ||
                    (strcmp(inst->last_made_directory, buffer) != 0)) {
-                       free((char *) inst->last_made_directory);
+
+                       /*
+                        *      Free any previously cached name.
+                        */
+                       if (inst->last_made_directory != NULL) {
+                               free((char *) inst->last_made_directory);
+                               inst->last_made_directory = NULL;
+                       }
+
                        inst->last_made_directory = strdup(buffer);
                }
 
@@ -264,24 +271,25 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
                *p = '/';
        } /* else there was no directory delimiter. */
 
+       /*
+        *      Open & create the file, with the given permissions.
+        */
+       if ((outfd = open(buffer, O_WRONLY | O_APPEND | O_CREAT,
+                         inst->detailperm)) < 0) {
+               radlog(L_ERR, "rlm_detail: Couldn't open file %s: %s",
+                      buffer, strerror(errno));
+               return RLM_MODULE_FAIL;
+       }
+
+       /*
+        *      If we're not using locking, we'll just pass straight though
+        *      the while loop.
+        *      If we fail to aquire the filelock in 80 tries (approximately
+        *      two seconds) we bail out.
+        */
        locked = 0;
        lock_count = 0;
        do {
-               /*
-                *      Open & create the file, with the given
-                *      permissions.
-                */
-               if ((outfd = open(buffer, O_WRONLY | O_APPEND | O_CREAT,
-                                 inst->detailperm)) < 0) {
-                       radlog(L_ERR, "rlm_detail: Couldn't open file %s: %s",
-                              buffer, strerror(errno));
-                       return RLM_MODULE_FAIL;
-               }
-
-               /*
-                *      If we fail to aquire the filelock in 80 tries
-                *      (approximately two seconds) we bail out.
-                */
                if (inst->locking) {
                        lseek(outfd, 0L, SEEK_SET);
                        if (rad_lockfd_nonblock(outfd, 0) < 0) {
@@ -290,37 +298,16 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
                                tv.tv_usec = 25000;
                                select(0, NULL, NULL, NULL, &tv);
                                lock_count++;
-                               continue;
-                       }
-
-                       /*
-                        *      The file might have been deleted by
-                        *      radrelay while we tried to acquire
-                        *      the lock (race condition)
-                        */
-                       if (fstat(outfd, &st) != 0) {
-                               radlog(L_ERR, "rlm_detail: Couldn't stat file %s: %s",
-                                      buffer, strerror(errno));
-                               close(outfd);
-                               return RLM_MODULE_FAIL;
-                       }
-                       if (st.st_nlink == 0) {
-                               DEBUG("rlm_detail: File %s removed by another program, retrying",
-                                     buffer);
-                               close(outfd);
-                               lock_count = 0;
-                               continue;
+                       } else {
+                               DEBUG("rlm_detail: Acquired filelock, tried %d time(s)",
+                                     lock_count + 1);
+                               locked = 1;
                        }
-
-                       DEBUG("rlm_detail: Acquired filelock, tried %d time(s)",
-                             lock_count + 1);
-                       locked = 1;
                }
-       } while (inst->locking && !locked && lock_count < 80);
+       } while (!locked && inst->locking && lock_count < 80);
 
-       if (inst->locking && !locked) {
-               close(outfd);
-               radlog(L_ERR, "rlm_detail: Failed to acquire filelock for %s, giving up",
+       if (!locked && inst->locking && lock_count >= 80) {
+               radlog(L_ERR, "rlm_detail: Failed to aquire filelock for %s, giving up",
                       buffer);
                return RLM_MODULE_FAIL;
        }
@@ -337,19 +324,12 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
                        rad_unlockfd(outfd, 0);
                        DEBUG("rlm_detail: Released filelock");
                }
-               close(outfd);   /* automatically releases the lock */
+               close(outfd);
 
                return RLM_MODULE_FAIL;
        }
 
        /*
-        *      Post a timestamp
-        */
-       fseek(outfp, 0L, SEEK_END);
-       radius_xlat(timestamp, sizeof(timestamp), inst->header, request, NULL);
-       fprintf(outfp, "%s\n", timestamp);
-
-       /*
         *      Write the information to the file.
         */
        if (!compat) {
@@ -359,78 +339,28 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
                 */
                if ((packet->code > 0) &&
                    (packet->code <= PW_ACCESS_CHALLENGE)) {
-                       fprintf(outfp, "\tPacket-Type = %s\n",
+                       fprintf(outfp, "Packet-Type = %s\n",
                                packet_codes[packet->code]);
                } else {
-                       fprintf(outfp, "\tPacket-Type = %d\n", packet->code);
+                       fprintf(outfp, "Packet-Type = %d\n", packet->code);
                }
        }
 
-       if (inst->log_srcdst) {
-               VALUE_PAIR src_vp, dst_vp;
-
-               src_vp.name[0] = dst_vp.name[0] = '\0'; /* for vp_prints() */
-               src_vp.operator = dst_vp.operator = T_OP_EQ;
-
-               switch (packet->src_ipaddr.af) {
-               case AF_INET:
-                       src_vp.type = PW_TYPE_IPADDR;
-                       src_vp.attribute = PW_PACKET_SRC_IP_ADDRESS;
-                       src_vp.vp_ipaddr = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
-                       dst_vp.type = PW_TYPE_IPADDR;
-                       dst_vp.attribute = PW_PACKET_DST_IP_ADDRESS;
-                       dst_vp.vp_ipaddr = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
-                       break;
-               case AF_INET6:
-                       src_vp.type = PW_TYPE_IPV6ADDR;
-                       src_vp.attribute = PW_PACKET_SRC_IPV6_ADDRESS;
-                       memcpy(src_vp.vp_strvalue,
-                              &packet->src_ipaddr.ipaddr.ip6addr,
-                              sizeof(packet->src_ipaddr.ipaddr.ip6addr));
-                       dst_vp.type = PW_TYPE_IPV6ADDR;
-                       dst_vp.attribute = PW_PACKET_DST_IPV6_ADDRESS;
-                       memcpy(dst_vp.vp_strvalue,
-                              &packet->dst_ipaddr.ipaddr.ip6addr,
-                              sizeof(packet->dst_ipaddr.ipaddr.ip6addr));
-                       break;
-               default:
-                       break;
-               }
-
-               fputs("\t", outfp);
-               vp_print(outfp, &src_vp);
-               fputs("\n", outfp);
-               fputs("\t", outfp);
-               vp_print(outfp, &dst_vp);
-               fputs("\n", outfp);
-
-               src_vp.attribute = PW_PACKET_SRC_PORT;
-               src_vp.type = PW_TYPE_INTEGER;
-               src_vp.vp_integer = packet->src_port;
-               dst_vp.attribute = PW_PACKET_DST_PORT;
-               dst_vp.type = PW_TYPE_INTEGER;
-               dst_vp.vp_integer = packet->dst_port;
-
-               fputs("\t", outfp);
-               vp_print(outfp, &src_vp);
-               fputs("\n", outfp);
-               fputs("\t", outfp);
-               vp_print(outfp, &dst_vp);
-               fputs("\n", outfp);
-       }
+       /*
+        *      Post a timestamp
+        */
+       fseek(outfp, 0L, SEEK_END);
+       fputs(CTIME_R(&request->timestamp, buffer, DIRLEN), outfp);
 
        /* Write each attribute/value to the log file */
        for (pair = packet->vps; pair != NULL; pair = pair->next) {
-               DICT_ATTR da;
-               da.attr = pair->attribute;
-
                if (inst->ht &&
-                   lrad_hash_table_finddata(inst->ht, &da)) continue;
+                   lrad_hash_table_finddata(inst->ht, pair)) continue;
 
                /*
                 *      Don't print passwords in old format...
                 */
-               if (compat && (pair->attribute == PW_USER_PASSWORD)) continue;
+               if (compat && (pair->attribute == PW_PASSWORD)) continue;
 
                /*
                 *      Print all of the attributes.
@@ -444,26 +374,25 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
         *      Add non-protocol attibutes.
         */
        if (compat) {
-               if (request->proxy) {
-                       char proxy_buffer[128];
-
-                       inet_ntop(request->proxy->dst_ipaddr.af,
-                                 &request->proxy->dst_ipaddr.ipaddr,
-                                 proxy_buffer, sizeof(proxy_buffer));
-                       fprintf(outfp, "\tFreeradius-Proxied-To = %s\n",
+               if ((pair = pairfind(request->config_items,
+                                    PW_PROXY_TO_REALM)) != NULL) {
+                       proxy_realm = realm_find(pair->strvalue, TRUE);
+                       if (proxy_realm) {
+                               memset((char *) proxy_buffer, 0, 16);
+                               ip_ntoa(proxy_buffer, proxy_realm->acct_ipaddr);
+                               fprintf(outfp, "\tFreeradius-Proxied-To = %s\n",
                                        proxy_buffer);
-                               DEBUG("rlm_detail: Freeradius-Proxied-To = %s",
+                               DEBUG("rlm_detail: Freeradius-Proxied-To set to %s",
                                      proxy_buffer);
+                       }
                }
-
                fprintf(outfp, "\tTimestamp = %ld\n",
                        (unsigned long) request->timestamp);
 
-               /*
-                *      We no longer permit Accounting-Request packets
-                *      with an authenticator of zero.
-                */
-               fputs("\tRequest-Authenticator = Verified\n", outfp);
+               if (request->packet->verified == 2)
+                       fputs("\tRequest-Authenticator = Verified\n", outfp);
+               else if (request->packet->verified == 1)
+                       fputs("\tRequest-Authenticator = None\n", outfp);
        }
 
        fputs("\n", outfp);
@@ -488,10 +417,6 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
  */
 static int detail_accounting(void *instance, REQUEST *request)
 {
-       if (request->listener->type == RAD_LISTEN_DETAIL) {
-               DEBUG2("  rlm_detail: Suppressing writes to detail file as the request was just read from a detail file.");
-               return RLM_MODULE_NOOP;
-       }
 
        return do_detail(instance,request,request->packet, TRUE);
 }
@@ -537,28 +462,16 @@ static int detail_post_proxy(void *instance, REQUEST *request)
                return do_detail(instance,request,request->proxy_reply, FALSE);
        }
 
-       /*
-        *      No reply: we must be doing Post-Proxy-Type = Fail.
-        *
-        *      Note that we just call the normal accounting function,
-        *      to minimize the amount of code, and to highlight that
-        *      it's doing normal accounting.
-        */
-       if (!request->proxy_reply) {
-               return detail_accounting(instance, request);
-       }
-
        return RLM_MODULE_NOOP;
 }
 
 
 /* globally exported name */
 module_t rlm_detail = {
-       RLM_MODULE_INIT,
        "detail",
        RLM_TYPE_THREAD_UNSAFE,        /* type: reserved */
+       NULL,                           /* initialization */
        detail_instantiate,             /* instantiation */
-       detail_detach,                  /* detach */
        {
                NULL,                   /* authentication */
                detail_authorize,       /* authorization */
@@ -569,5 +482,7 @@ module_t rlm_detail = {
                detail_post_proxy,      /* post-proxy */
                detail_postauth         /* post-auth */
        },
+       detail_detach,                  /* detach */
+       NULL                            /* destroy */
 };
 
index 794b7ab..8e85159 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
 
 static int digest_authorize(void *instance, REQUEST *request)
 {
@@ -97,10 +103,10 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        return RLM_MODULE_INVALID;
                }
        } else {
-               passwd = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
+               passwd = pairfind(request->config_items, PW_PASSWORD);
        }
        if (!passwd) {
-               radlog(L_AUTH, "rlm_digest: Cleartext-Password or Digest-HA1 is required for authentication.");
+               radlog(L_AUTH, "rlm_digest: Configuration item \"User-Password\" or Digest-HA1 is required for authentication.");
                return RLM_MODULE_INVALID;
        }
 
@@ -120,7 +126,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
        while (vp) {
                int length = vp->length;
                int attrlen;
-               uint8_t *p = &vp->vp_octets[0];
+               uint8_t *p = &vp->strvalue[0];
                VALUE_PAIR *sub;
 
                /*
@@ -159,11 +165,13 @@ static int digest_authenticate(void *instance, REQUEST *request)
                         *
                         *      Didn't they know that VSA's exist?
                         */
-                       sub = radius_paircreate(request, &request->packet->vps,
-                                               PW_DIGEST_REALM - 1 + p[0],
-                                               PW_TYPE_STRING);
-                       memcpy(&sub->vp_octets[0], &p[2], attrlen - 2);
-                       sub->vp_octets[attrlen - 2] = '\0';
+                       sub = paircreate(PW_DIGEST_REALM - 1 + p[0],
+                                        PW_TYPE_STRING);
+                       if (!sub) {
+                               return RLM_MODULE_FAIL; /* out of memory */
+                       }
+                       memcpy(&sub->strvalue[0], &p[2], attrlen - 2);
+                       sub->strvalue[attrlen - 2] = '\0';
                        sub->length = attrlen - 2;
 
                        if (debug_flag) {
@@ -173,6 +181,11 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        }
 
                        /*
+                        *      And add it to the request pairs.
+                        */
+                       pairadd(&request->packet->vps, sub);
+
+                       /*
                         *      FIXME: Check for the existence
                         *      of the necessary attributes!
                         */
@@ -204,7 +217,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-User-Name: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a1[0], &vp->vp_octets[0], vp->length);
+       memcpy(&a1[0], &vp->strvalue[0], vp->length);
        a1_len = vp->length;
 
        a1[a1_len] = ':';
@@ -215,14 +228,14 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-Realm: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a1[a1_len], &vp->vp_octets[0], vp->length);
+       memcpy(&a1[a1_len], &vp->strvalue[0], vp->length);
        a1_len += vp->length;
 
        a1[a1_len] = ':';
        a1_len++;
 
-       if (passwd->attribute == PW_CLEARTEXT_PASSWORD) {
-               memcpy(&a1[a1_len], &passwd->vp_octets[0], passwd->length);
+       if (passwd->attribute == PW_USER_PASSWORD) {
+               memcpy(&a1[a1_len], &passwd->strvalue[0], passwd->length);
                a1_len += passwd->length;
                a1[a1_len] = '\0';
                DEBUG2("A1 = %s", a1);
@@ -237,30 +250,30 @@ static int digest_authenticate(void *instance, REQUEST *request)
         *      Assume MD5 if no Digest-Algorithm attribute received
         */
        algo = pairfind(request->packet->vps, PW_DIGEST_ALGORITHM);
-       if ((algo == NULL) ||
-           (strcasecmp(algo->vp_strvalue, "MD5") == 0)) {
+       if ((algo == NULL) || 
+           (strcasecmp(algo->strvalue, "MD5") == 0)) {
                /*
                 *      Set A1 to Digest-HA1 if no User-Password found
                 */
                if (passwd->attribute == PW_DIGEST_HA1) {
-                       if (lrad_hex2bin(passwd->vp_strvalue, &a1[0], 16) != 16) {
+                       if (lrad_hex2bin(passwd->strvalue, &a1[0], 16) != 16) {
                                DEBUG2("rlm_digest: Invalid text in Digest-HA1");
                                return RLM_MODULE_INVALID;
                        }
                }
 
-       } else if (strcasecmp(algo->vp_strvalue, "MD5-sess") == 0) {
+       } else if (strcasecmp(algo->strvalue, "MD5-sess") == 0) {
                /*
                 *      K1 = H(A1) : Digest-Nonce ... : H(A2)
                 *
                 *      If we find Digest-HA1, we assume it contains
                 *      H(A1).
                 */
-               if (passwd->attribute == PW_CLEARTEXT_PASSWORD) {
+               if (passwd->attribute == PW_USER_PASSWORD) {
                        librad_md5_calc(hash, &a1[0], a1_len);
-                       lrad_bin2hex(hash, (char *) &a1[0], 16);
+                       lrad_bin2hex(hash, &a1[0], 16);
                } else {        /* MUST be Digest-HA1 */
-                       memcpy(&a1[0], passwd->vp_strvalue, 32);
+                       memcpy(&a1[0], passwd->strvalue, 32);
                }
                a1_len = 32;
 
@@ -274,7 +287,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: Received Digest-Nonce hex string with invalid length: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&a1[a1_len], &nonce->vp_octets[0], nonce->length);
+               memcpy(&a1[a1_len], &nonce->strvalue[0], nonce->length);
                a1_len += nonce->length;
 
                a1[a1_len] = ':';
@@ -293,16 +306,16 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: Received Digest-CNonce hex string with invalid length: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&a1[a1_len], &vp->vp_octets[0], vp->length);
+               memcpy(&a1[a1_len], &vp->strvalue[0], vp->length);
                a1_len += vp->length;
 
        } else if ((algo != NULL) &&
-                  (strcasecmp(algo->vp_strvalue, "MD5") != 0)) {
+                  (strcasecmp(algo->strvalue, "MD5") != 0)) {
                /*
                 *      We check for "MD5-sess" and "MD5".
                 *      Anything else is an error.
                 */
-               DEBUG("ERROR: Unknown Digest-Algorithm \"%s\": Cannot perform Digest authentication", vp->vp_strvalue);
+               DEBUG("ERROR: Unknown Digest-Algorithm \"%s\": Cannot perform Digest authentication", vp->strvalue);
                return RLM_MODULE_INVALID;
        }
 
@@ -314,7 +327,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-Method: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a2[0], &vp->vp_octets[0], vp->length);
+       memcpy(&a2[0], &vp->strvalue[0], vp->length);
        a2_len = vp->length;
 
        a2[a2_len] = ':';
@@ -325,7 +338,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-URI: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a2[a2_len], &vp->vp_octets[0], vp->length);
+       memcpy(&a2[a2_len], &vp->strvalue[0], vp->length);
        a2_len += vp->length;
 
        /*
@@ -333,7 +346,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
         */
        qop = pairfind(request->packet->vps, PW_DIGEST_QOP);
        if ((qop != NULL) &&
-           (strcasecmp(qop->vp_strvalue, "auth-int") == 0)) {
+           (strcasecmp(qop->strvalue, "auth-int") == 0)) {
                VALUE_PAIR *body;
 
                /*
@@ -356,12 +369,12 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        return RLM_MODULE_INVALID;
                }
 
-               memcpy(a2 + a2_len, body->vp_octets, body->length);
+               memcpy(a2 + a2_len, body->strvalue, body->length);
                a2_len += body->length;
 
        } else if ((qop != NULL) &&
-                  (strcasecmp(qop->vp_strvalue, "auth") != 0)) {
-               DEBUG("ERROR: Unknown Digest-QOP \"%s\": Cannot perform Digest authentication", qop->vp_strvalue);
+                  (strcasecmp(qop->strvalue, "auth") != 0)) {
+               DEBUG("ERROR: Unknown Digest-QOP \"%s\": Cannot perform Digest authentication", qop->strvalue);
                return RLM_MODULE_INVALID;
        }
 
@@ -373,15 +386,15 @@ static int digest_authenticate(void *instance, REQUEST *request)
         *     Compute MD5 if Digest-Algorithm == "MD5-Sess",
         *     or if we found a User-Password.
         */
-       if (((algo != NULL) &&
-            (strcasecmp(algo->vp_strvalue, "MD5-Sess") == 0)) ||
-           (passwd->attribute == PW_CLEARTEXT_PASSWORD)) {
-               a1[a1_len] = '\0';
+       if (((algo != NULL) && 
+            (strcasecmp(algo->strvalue, "MD5-Sess") == 0)) ||
+           (passwd->attribute == PW_USER_PASSWORD)) {
+         a1[a1_len] = '\0';
                librad_md5_calc(&hash[0], &a1[0], a1_len);
        } else {
                memcpy(&hash[0], &a1[0], a1_len);
        }
-       lrad_bin2hex(hash, (char *) kd, sizeof(hash));
+       lrad_bin2hex(hash, kd, sizeof(hash));
 
 #ifndef NDEBUG
        if (debug_flag) {
@@ -397,7 +410,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
        kd[kd_len] = ':';
        kd_len++;
 
-       memcpy(&kd[kd_len], nonce->vp_octets, nonce->length);
+       memcpy(&kd[kd_len], nonce->strvalue, nonce->length);
        kd_len += nonce->length;
 
        /*
@@ -421,7 +434,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: No Digest-Nonce-Count: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&kd[kd_len], &vp->vp_octets[0], vp->length);
+               memcpy(&kd[kd_len], &vp->strvalue[0], vp->length);
                kd_len += vp->length;
 
                kd[kd_len] = ':';
@@ -432,13 +445,13 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: No Digest-CNonce: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&kd[kd_len], &vp->vp_octets[0], vp->length);
+               memcpy(&kd[kd_len], &vp->strvalue[0], vp->length);
                kd_len += vp->length;
 
                kd[kd_len] = ':';
                kd_len++;
 
-               memcpy(&kd[kd_len], &qop->vp_octets[0], qop->length);
+               memcpy(&kd[kd_len], &qop->strvalue[0], qop->length);
                kd_len += qop->length;
        }
 
@@ -450,7 +463,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
 
        librad_md5_calc(&hash[0], &a2[0], a2_len);
 
-       lrad_bin2hex(hash, (char *) kd + kd_len, sizeof(hash));
+       lrad_bin2hex(hash, kd + kd_len, sizeof(hash));
 
 #ifndef NDEBUG
        if (debug_flag) {
@@ -482,7 +495,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                return RLM_MODULE_INVALID;
        }
 
-       if (lrad_hex2bin(&vp->vp_strvalue[0], &hash[0], vp->length >> 1) != (vp->length >> 1)) {
+       if (lrad_hex2bin(&vp->strvalue[0], &hash[0], vp->length >> 1) != (vp->length >> 1)) {
                DEBUG2("rlm_digest: Invalid text in Digest-Response");
                return RLM_MODULE_INVALID;
        }
@@ -524,11 +537,10 @@ static int digest_authenticate(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_digest = {
-       RLM_MODULE_INIT,
-       "digest",
+       "DIGEST",
        0,                              /* type */
+       NULL,                           /* initialization */
        NULL,                           /* instantiation */
-       NULL,                           /* detach */
        {
                digest_authenticate,    /* authentication */
                digest_authorize,       /* authorization */
@@ -539,4 +551,6 @@ module_t rlm_digest = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       NULL,                           /* detach */
+       NULL,                           /* destroy */
 };
index 5a5bf45..22508b9 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.5 .
+# From configure.in Revision: 1.4 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -897,7 +897,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1820,7 +1820,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1878,7 +1879,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1994,7 +1996,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2048,7 +2051,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2093,7 +2097,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2137,7 +2142,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3068,6 +3074,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3106,12 +3117,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
@@ -3343,7 +3348,7 @@ echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
    { (exit 1); exit 1; }; }
     fi
 
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
index eed6432..a8b9ba7 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_eap.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_eap])
@@ -26,9 +25,9 @@ if test x$with_[]modname != xno; then
        AC_CONFIG_SUBDIRS($eapsubdirs)
        rm install-sh
 
-       dnl #
+       dnl # 
        dnl # Don't bother looking for errors in the child directories
-       dnl #
+       dnl # 
 
        targetname=modname
 else
@@ -43,10 +42,10 @@ if test x"$fail" != x""; then
                AC_MSG_WARN([silently not building ]modname[.])
                AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.])
                if test x"$headersuggestion" != x; then
-                       AC_MSG_WARN([$headersuggestion])
+                       AC_MSG_WARN([$headersuggestion]) 
                fi
                if test x"$libsuggestion" != x; then
-                       AC_MSG_WARN([$libsuggestion])
+                       AC_MSG_WARN([$libsuggestion]) 
                fi
                targetname=""
            eapsubdirs=""
index b66b12c..e9322ef 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000-2003,2006  The FreeRADIUS server project
+ * Copyright 2000-2003  The FreeRADIUS server project
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
  */
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include "rlm_eap.h"
 
+static const char rcsid[] = "$Id$";
+
 static const char *eap_codes[] = {
   "",                          /* 0 is invalid */
   "request",
@@ -120,10 +119,6 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
                free(node);
                return -1;
        }
-       DEBUG("  eap: Linked to sub-module %s", buffer);
-
-       DEBUG("  eap: Instantiating eap-%s", eaptype_name);
-
        if ((node->type->attach) &&
            ((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
 
@@ -134,6 +129,7 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
                return -1;
        }
 
+       DEBUG("rlm_eap: Loaded and initialized type %s", eaptype_name);
        *type = node;
        return 0;
 }
@@ -219,7 +215,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                 */
                vp = pairfind(handler->request->config_items,
                              PW_EAP_TYPE);
-               if (vp) default_eap_type = vp->vp_integer;
+               if (vp) default_eap_type = vp->lvalue;
 
        do_initiate:
                /*
@@ -255,7 +251,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                 *      We don't do TLS inside of TLS, as it's a bad
                 *      idea...
                 */
-               if ((handler->request->packet->dst_port == 0) &&
+               if (((handler->request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) &&
                    (default_eap_type == PW_EAP_TLS)) {
                        DEBUG2(" rlm_eap: Unable to tunnel TLS inside of TLS");
                        return EAP_INVALID;
@@ -330,11 +326,11 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                 */
                vp = pairfind(handler->request->config_items,
                              PW_EAP_TYPE);
-               if (vp && (vp->vp_integer != default_eap_type)) {
+               if (vp && (vp->lvalue != default_eap_type)) {
                        char    mynamebuf[64];
                        DEBUG2("  rlm_eap: Client wants %s, while we require %s, rejecting the user.",
                               eaptype_name,
-                              eaptype_type2name(vp->vp_integer,
+                              eaptype_type2name(vp->lvalue,
                                                 mynamebuf,
                                                 sizeof(mynamebuf)));
                        return EAP_INVALID;
@@ -543,7 +539,7 @@ int eap_compose(EAP_HANDLER *handler)
                 * This memory gets freed up when request is freed up
                 */
                eap_msg = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);
-               memcpy(eap_msg->vp_octets, ptr, len);
+               memcpy(eap_msg->strvalue, ptr, len);
                eap_msg->length = len;
                pairadd(&(request->reply->vps), eap_msg);
                ptr += len;
@@ -560,7 +556,7 @@ int eap_compose(EAP_HANDLER *handler)
        vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR);
        if (!vp) {
                vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
-               memset(vp->vp_octets, 0, AUTH_VECTOR_LEN);
+               memset(vp->strvalue, 0, AUTH_VECTOR_LEN);
                vp->length = AUTH_VECTOR_LEN;
                pairadd(&(request->reply->vps), vp);
        }
@@ -625,7 +621,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      this allows you to NOT do EAP for some users.
         */
        vp = pairfind(request->packet->vps, PW_EAP_TYPE);
-       if (vp && vp->vp_integer == 0) {
+       if (vp && vp->lvalue == 0) {
                DEBUG2("  rlm_eap: Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");
                return EAP_NOOP;
        }
@@ -648,8 +644,8 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                 *      If it's a LOCAL realm, then we're not proxying
                 *      to it.
                 */
-               realm = realm_find(proxy->vp_strvalue);
-               if (realm && (realm->auth_pool == NULL)) {
+               realm = realm_find(proxy->strvalue, 0);
+               if (realm && (realm->ipaddr == htonl(INADDR_NONE))) {
                        proxy = NULL;
                }
        }
@@ -674,16 +670,16 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                 */
                if (proxy) {
                do_proxy:
-                       DEBUG2("  rlm_eap: Request is supposed to be proxied to Realm %s.  Not doing EAP.", proxy->vp_strvalue);
+                       DEBUG2("  rlm_eap: Request is supposed to be proxied to Realm %s.  Not doing EAP.", proxy->strvalue);
                        return EAP_NOOP;
                }
-
+               
                DEBUG2("  rlm_eap: Got EAP_START message");
                if ((eap_ds = eap_ds_alloc()) == NULL) {
                        DEBUG2("  rlm_eap: EAP Start failed in allocation");
                        return EAP_FAIL;
                }
-
+               
                /*
                 *      It's an EAP-Start packet.  Tell them to stop wasting
                 *      our time, and give us an EAP-Identity packet.
@@ -693,7 +689,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                 */
                eap_ds->request->code = PW_EAP_REQUEST;
                eap_ds->request->type.type = PW_EAP_IDENTITY;
-
+               
                /*
                 *      We don't have a handler, but eap_compose needs one,
                 *      (for various reasons), so we fake it out here.
@@ -701,9 +697,9 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                memset(&handler, 0, sizeof(handler));
                handler.request = request;
                handler.eap_ds = eap_ds;
-
+               
                eap_compose(&handler);
-
+               
                eap_ds_free(&eap_ds);
                return EAP_FOUND;
        } /* end of handling EAP-Start */
@@ -726,7 +722,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         */
        vp = paircreate(PW_EAP_TYPE, PW_TYPE_INTEGER);
        if (vp) {
-               vp->vp_integer = eap_msg->vp_octets[4];
+               vp->lvalue = eap_msg->strvalue[4];
                pairadd(&(request->packet->vps), vp);
        }
 
@@ -748,13 +744,13 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      We're allowed only a few codes.  Request, Response,
         *      Success, or Failure.
         */
-       if ((eap_msg->vp_octets[0] == 0) ||
-           (eap_msg->vp_octets[0] > PW_EAP_MAX_CODES)) {
+       if ((eap_msg->strvalue[0] == 0) ||
+           (eap_msg->strvalue[0] > PW_EAP_MAX_CODES)) {
                DEBUG2("  rlm_eap: Unknown EAP packet");
        } else {
                DEBUG2("  rlm_eap: EAP packet type %s id %d length %d",
-                      eap_codes[eap_msg->vp_octets[0]],
-                      eap_msg->vp_octets[1],
+                      eap_codes[eap_msg->strvalue[0]],
+                      eap_msg->strvalue[1],
                       eap_msg->length);
        }
 
@@ -764,8 +760,8 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      sending success/fail packets to us, as it doesn't make
         *      sense.
         */
-       if ((eap_msg->vp_octets[0] != PW_EAP_REQUEST) &&
-           (eap_msg->vp_octets[0] != PW_EAP_RESPONSE)) {
+       if ((eap_msg->strvalue[0] != PW_EAP_REQUEST) &&
+           (eap_msg->strvalue[0] != PW_EAP_RESPONSE)) {
                DEBUG2("  rlm_eap: Ignoring EAP packet which we don't know how to handle.");
                return EAP_FAIL;
        }
@@ -778,15 +774,15 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      EAP-Identity, Notification, and NAK are all handled
         *      internally, so they never have handlers.
         */
-       if ((eap_msg->vp_octets[4] >= PW_EAP_MD5) &&
+       if ((eap_msg->strvalue[4] >= PW_EAP_MD5) &&
            inst->ignore_unknown_eap_types &&
-           ((eap_msg->vp_octets[4] == 0) ||
-            (eap_msg->vp_octets[4] > PW_EAP_MAX_TYPES) ||
-            (inst->types[eap_msg->vp_octets[4]] == NULL))) {
+           ((eap_msg->strvalue[4] == 0) ||
+            (eap_msg->strvalue[4] > PW_EAP_MAX_TYPES) ||
+            (inst->types[eap_msg->strvalue[4]] == NULL))) {
                DEBUG2("  rlm_eap:  Ignoring Unknown EAP type");
                return EAP_NOOP;
        }
-
+               
        /*
         *      They're NAKing the EAP type we wanted to use, and
         *      asking for one which we don't support.
@@ -802,22 +798,16 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      returns NOOP, and another module may choose to proxy
         *      the request.
         */
-       if ((eap_msg->vp_octets[4] == PW_EAP_NAK) &&
+       if ((eap_msg->strvalue[4] == PW_EAP_NAK) &&
            (eap_msg->length >= (EAP_HEADER_LEN + 2)) &&
            inst->ignore_unknown_eap_types &&
-           ((eap_msg->vp_octets[5] == 0) ||
-            (eap_msg->vp_octets[5] > PW_EAP_MAX_TYPES) ||
-            (inst->types[eap_msg->vp_octets[5]] == NULL))) {
+           ((eap_msg->strvalue[5] == 0) ||
+            (eap_msg->strvalue[5] > PW_EAP_MAX_TYPES) ||
+            (inst->types[eap_msg->strvalue[5]] == NULL))) {
                DEBUG2("  rlm_eap: Ignoring NAK with request for unknown EAP type");
                return EAP_NOOP;
        }
 
-       if ((eap_msg->vp_octets[4] == PW_EAP_TTLS) ||
-           (eap_msg->vp_octets[4] == PW_EAP_PEAP)) {
-               DEBUG2("  rlm_eap: Continuing tunnel setup.");
-               return EAP_OK;
-       }
-
        /*
         *      Later EAP messages are longer than the 'start'
         *      message, so if everything is OK, this function returns
@@ -1056,7 +1046,7 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                         *      request as the NAS is doing something
                         *      funny.
                        */
-                       if (strncmp(handler->identity, vp->vp_strvalue,
+                       if (strncmp(handler->identity, vp->strvalue,
                                   MAX_STRING_LEN) != 0) {
                                radlog(L_ERR, "rlm_eap: Identity does not match User-Name.  Authentication failed.");
                                free(*eap_packet_p);
@@ -1112,7 +1102,7 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                         *      identity, the NAS is doing something
                         *      funny, so reject the request.
                        */
-                       if (strncmp(handler->identity, vp->vp_strvalue,
+                       if (strncmp(handler->identity, vp->strvalue,
                                   MAX_STRING_LEN) != 0) {
                                radlog(L_ERR, "rlm_eap: Identity does not match User-Name, setting from EAP Identity.");
                                free(*eap_packet_p);
index 63847a1..2c0c8f9 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
 #ifndef _EAP_H
 #define _EAP_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_h, "$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/rad_assert.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "radiusd.h"
+#include "modules.h"
+
+#include "rad_assert.h"
 
 #include "eap_types.h"
 
@@ -92,7 +102,7 @@ typedef enum operation_t {
 typedef struct _eap_handler {
        struct _eap_handler *prev, *next;
        uint8_t         state[EAP_STATE_LEN];
-       lrad_ipaddr_t   src_ipaddr;
+       uint32_t        src_ipaddr;
        unsigned int    eap_id;
        unsigned int    eap_type;
 
index 011d285..7f04e96 100644 (file)
@@ -12,7 +12,7 @@ SRCS          += cb.c eap_tls.c mppe_keys.c tls.c
 endif
 LT_OBJS                = $(SRCS:.c=.lo)
 INCLUDES       = eap_types.h eap_tls.h
-CFLAGS         += -DEAPLIB -I. -I.. -I$(top_builddir)/src $(OPENSSL_INCLUDE)
+CFLAGS         += -DEAPLIB -I. -I.. -I$(top_builddir)/src/include $(OPENSSL_INCLUDE)
 ifeq ($(USE_SHARED_LIBS),yes)
 LINK_MODE      = -export-dynamic
 else
index ef8d74b..a29504a 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
- * Copyright 2006  The FreeRADIUS server project
  */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include "eap_tls.h"
 
 #ifndef NO_OPENSSL
@@ -42,11 +37,11 @@ void cbtls_info(const SSL *s, int where, int ret)
        state = state ? state : "NULL";
 
        if (where & SSL_CB_LOOP) {
-               if (debug_flag) radlog(L_INFO, "%s: %s\n", str, state);
+               DEBUG2("%s: %s\n", str, state);
        } else if (where & SSL_CB_HANDSHAKE_START) {
-               if (debug_flag) radlog(L_INFO, "%s: %s\n", str, state);
+               DEBUG2("%s: %s\n", str, state);
        } else if (where & SSL_CB_HANDSHAKE_DONE) {
-               radlog(L_INFO, "%s: %s\n", str, state);
+               DEBUG2("%s: %s\n", str, state);
        } else if (where & SSL_CB_ALERT) {
                str=(where & SSL_CB_READ)?"read":"write";
                radlog(L_ERR,"TLS Alert %s:%s:%s\n", str,
@@ -114,7 +109,7 @@ RSA *cbtls_rsa(SSL *s UNUSED, int is_export UNUSED, int keylength)
        static RSA *rsa_tmp=NULL;
 
        if (rsa_tmp == NULL) {
-               radlog(L_INFO, "Generating temp (%d bit) RSA key...", keylength);
+               DEBUG2("Generating temp (%d bit) RSA key...", keylength);
                rsa_tmp=RSA_generate_key(keylength, RSA_F4, NULL, NULL);
        }
        return(rsa_tmp);
index 3f577af..e813485 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
- * Copyright 2006  The FreeRADIUS server project
  *
  */
 #ifndef _EAP_SIM_H
 #define _EAP_SIM_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_sim_h, "$Id$")
-
 #include "eap_types.h"
 
 #define EAP_SIM_VERSION 0x0001
@@ -38,17 +34,17 @@ RCSIDH(eap_sim_h, "$Id$")
 #define ATTRIBUTE_EAP_SIM_RAND1         1201
 #define ATTRIBUTE_EAP_SIM_RAND2         1202
 #define ATTRIBUTE_EAP_SIM_RAND3         1203
-
+                                       
 #define ATTRIBUTE_EAP_SIM_SRES1         1204
 #define ATTRIBUTE_EAP_SIM_SRES2         1205
 #define ATTRIBUTE_EAP_SIM_SRES3         1206
-
+                                       
 #define ATTRIBUTE_EAP_SIM_STATE         1207
 #define ATTRIBUTE_EAP_SIM_IMSI          1208
 #define ATTRIBUTE_EAP_SIM_HMAC          1209
 #define ATTRIBUTE_EAP_SIM_KEY           1210
 #define ATTRIBUTE_EAP_SIM_EXTRA         1211
-
+                                       
 #define ATTRIBUTE_EAP_SIM_KC1           1212
 #define ATTRIBUTE_EAP_SIM_KC2           1213
 #define ATTRIBUTE_EAP_SIM_KC3           1214
index db14838..3c24e94 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
 
 /*
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 #include <assert.h>
 #include "eap_tls.h"
 
@@ -336,11 +332,12 @@ static eaptls_status_t eaptls_verify(EAP_HANDLER *handler)
            ((eap_ds->response->length == EAP_HEADER_LEN + 2) &&
             ((eaptls_packet->flags & 0xc0) == 0x00))) {
 
-               if (prev_eap_ds->request->id == eap_ds->response->id) {
+               if (prev_eap_ds &&
+                   (prev_eap_ds->request->id == eap_ds->response->id)) {
                        /*
                         *      Run the ACK handler directly from here.
                         */
-                       radlog(L_INFO, "rlm_eap_tls: Received EAP-TLS ACK message");
+                       DEBUG2("rlm_eap_tls: Received EAP-TLS ACK message");
                        return eaptls_ack_handler(handler);
                } else {
                        radlog(L_ERR, "rlm_eap_tls: Received Invalid EAP-TLS ACK message");
@@ -382,22 +379,22 @@ static eaptls_status_t eaptls_verify(EAP_HANDLER *handler)
                            (eaptls_prev == NULL) ||
                            !TLS_MORE_FRAGMENTS(eaptls_prev->flags)) {
 
-                               radlog(L_INFO, "rlm_eap_tls:  Received EAP-TLS First Fragment of the message");
+                               DEBUG2("rlm_eap_tls:  Received EAP-TLS First Fragment of the message");
                                return EAPTLS_FIRST_FRAGMENT;
                        } else {
 
-                               radlog(L_INFO, "rlm_eap_tls:  More Fragments with length included");
+                               DEBUG2("rlm_eap_tls:  More Fragments with length included");
                                return EAPTLS_MORE_FRAGMENTS_WITH_LENGTH;
                        }
                } else {
 
-                       radlog(L_INFO, "rlm_eap_tls:  Length Included");
+                       DEBUG2("rlm_eap_tls:  Length Included");
                        return EAPTLS_LENGTH_INCLUDED;
                }
        }
 
        if (TLS_MORE_FRAGMENTS(eaptls_packet->flags)) {
-               radlog(L_INFO, "rlm_eap_tls:  More fragments to follow");
+               DEBUG2("rlm_eap_tls:  More fragments to follow");
                return EAPTLS_MORE_FRAGMENTS;
        }
 
index 1a00043..7103073 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
 #ifndef _EAP_TLS_H
 #define _EAP_TLS_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_tls_h, "$Id$")
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -155,7 +151,7 @@ typedef struct _tls_session_t {
                                       unsigned int size);
        unsigned int    (*record_minus)(record_t *buf, void *ptr,
                                        unsigned int size);
-
+       
 
        /*
         * Framed-MTU attribute in RADIUS,
index 09a3285..8d787f7 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
 #ifndef _EAP_TYPES_H
 #define _EAP_TYPES_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_types_h, "$Id$")
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "radiusd.h"
+#include "modules.h"
 
 #define PW_EAP_REQUEST         1
 #define PW_EAP_RESPONSE                2
@@ -41,7 +48,8 @@ RCSIDH(eap_types_h, "$Id$")
 /* base for dictionary values */
 #define ATTRIBUTE_EAP_ID        1020
 #define ATTRIBUTE_EAP_CODE      1021
-#define ATTRIBUTE_EAP_BASE      1280
+#define ATTRIBUTE_EAP_MD5_PASSWORD 1022
+#define ATTRIBUTE_EAP_BASE      (5*256)
 
 #define PW_EAP_IDENTITY                1
 #define PW_EAP_NOTIFICATION    2
index bfbd978..12418a5 100644 (file)
@@ -17,9 +17,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000-2003,2006  The FreeRADIUS server project
+ * Copyright 2000-2003  The FreeRADIUS server project
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
-#include <freeradius-devel/missing.h>
-#include <freeradius-devel/libradius.h>
+#include "libradius.h"
 #include "eap_types.h"
 
+static const char rcsid[] = "$Id$";
+
 static const char *eap_types[] = {
   "",
   "identity",
@@ -265,7 +262,7 @@ int eap_basic_compose(RADIUS_PACKET *packet, EAP_PACKET *reply)
                 * This memory gets freed up when packet is freed up
                 */
                eap_msg = paircreate(PW_EAP_MESSAGE, PW_TYPE_OCTETS);
-               memcpy(eap_msg->vp_strvalue, ptr, len);
+               memcpy(eap_msg->strvalue, ptr, len);
                eap_msg->length = len;
                pairadd(&(packet->vps), eap_msg);
                ptr += len;
@@ -282,7 +279,7 @@ int eap_basic_compose(RADIUS_PACKET *packet, EAP_PACKET *reply)
        vp = pairfind(packet->vps, PW_MESSAGE_AUTHENTICATOR);
        if (!vp) {
                vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
-               memset(vp->vp_strvalue, 0, AUTH_VECTOR_LEN);
+               memset(vp->strvalue, 0, AUTH_VECTOR_LEN);
                vp->length = AUTH_VECTOR_LEN;
                pairadd(&(packet->vps), vp);
        }
@@ -336,14 +333,14 @@ void map_eap_types(RADIUS_PACKET *req)
        if(vp == NULL) {
                id = ((int)getpid() & 0xff);
        } else {
-               id = vp->vp_integer;
+               id = vp->lvalue;
        }
 
        vp = pairfind(req->vps, ATTRIBUTE_EAP_CODE);
        if(vp == NULL) {
                eapcode = PW_EAP_REQUEST;
        } else {
-               eapcode = vp->vp_integer;
+               eapcode = vp->lvalue;
        }
 
 
@@ -389,7 +386,7 @@ void map_eap_types(RADIUS_PACKET *req)
                ep.type.type = eap_type;
                ep.type.length = vp->length;
                ep.type.data = malloc(vp->length);
-               memcpy(ep.type.data,vp->vp_octets, vp->length);
+               memcpy(ep.type.data,vp->strvalue, vp->length);
                eap_basic_compose(req, &ep);
        }
 }
@@ -430,7 +427,7 @@ eap_packet_t *eap_attribute(VALUE_PAIR *vps)
         *      Get the Actual length from the EAP packet
         *      First EAP-Message contains the EAP packet header
         */
-       memcpy(&len, first->vp_strvalue + 2, sizeof(len));
+       memcpy(&len, first->strvalue + 2, sizeof(len));
        len = ntohs(len);
 
        /*
@@ -478,7 +475,7 @@ eap_packet_t *eap_attribute(VALUE_PAIR *vps)
 
        /* RADIUS ensures order of attrs, so just concatenate all */
        for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE)) {
-               memcpy(ptr, vp->vp_strvalue, vp->length);
+               memcpy(ptr, vp->strvalue, vp->length);
                ptr += vp->length;
        }
 
@@ -504,11 +501,11 @@ void unmap_eap_types(RADIUS_PACKET *rep)
 
        /* create EAP-ID and EAP-CODE attributes to start */
        eap1 = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);
-       eap1->vp_integer = e->id;
+       eap1->lvalue = e->id;
        pairadd(&(rep->vps), eap1);
 
        eap1 = paircreate(ATTRIBUTE_EAP_CODE, PW_TYPE_INTEGER);
-       eap1->vp_integer = e->code;
+       eap1->lvalue = e->code;
        pairadd(&(rep->vps), eap1);
 
        switch(e->code)
@@ -533,6 +530,7 @@ void unmap_eap_types(RADIUS_PACKET *rep)
                /* verify the length is big enough to hold type */
                if(len < 5)
                {
+                       free(e);
                        return;
                }
 
@@ -546,12 +544,13 @@ void unmap_eap_types(RADIUS_PACKET *rep)
                }
 
                eap1 = paircreate(type, PW_TYPE_OCTETS);
-               memcpy(eap1->vp_strvalue, &e->data[1], len);
+               memcpy(eap1->strvalue, &e->data[1], len);
                eap1->length = len;
                pairadd(&(rep->vps), eap1);
                break;
        }
 
+       free(e);
        return;
 }
 
index d0fe491..18e65db 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "eap_types.h"
 #include "eap_sim.h"
-#include <freeradius-devel/sha1.h>
+#include "sha1.h"
 
 void eapsim_calculate_keys(struct eapsim_keys *ek)
 {
index 23e6dbc..f36e6ea 100644 (file)
@@ -20,9 +20,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000-2003,2006  The FreeRADIUS server project
+ * Copyright 2000-2003  The FreeRADIUS server project
  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
  */
 
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
-#include <freeradius-devel/missing.h>
-#include <freeradius-devel/libradius.h>
+#include "libradius.h"
 #include "eap_types.h"
 #include "eap_sim.h"
-#include <freeradius-devel/sha1.h>
+#include "sha1.h"
+
+static const char rcsid[] = "$Id$";
 
 /*
  * given a radius request with many attribues in the EAP-SIM range, build
@@ -89,7 +86,7 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, EAP_PACKET *ep)
        }
        else
        {
-               subtype = vp->vp_integer;
+               subtype = vp->lvalue;
        }
 
        vp = pairfind(r->vps, ATTRIBUTE_EAP_ID);
@@ -99,7 +96,7 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, EAP_PACKET *ep)
        }
        else
        {
-               id = vp->vp_integer;
+               id = vp->lvalue;
        }
 
        vp = pairfind(r->vps, ATTRIBUTE_EAP_CODE);
@@ -109,7 +106,7 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, EAP_PACKET *ep)
        }
        else
        {
-               eapcode = vp->vp_integer;
+               eapcode = vp->lvalue;
        }
 
 
@@ -228,13 +225,13 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, EAP_PACKET *ep)
                        roundedlen = 20;
                        memset(&attr[2], 0, 18);
                        macspace = &attr[4];
-                       append = vp->vp_octets;
+                       append = vp->strvalue;
                        appendlen = vp->length;
                }
                else {
                        roundedlen = (vp->length + 2 + 3) & ~3;
                        memset(attr, 0, roundedlen);
-                       memcpy(&attr[2], vp->vp_strvalue, vp->length);
+                       memcpy(&attr[2], vp->strvalue, vp->length);
                }
                attr[0] = vp->attribute - ATTRIBUTE_EAP_SIM_BASE;
                attr[1] = roundedlen >> 2;
@@ -285,7 +282,7 @@ int map_eapsim_basictypes(RADIUS_PACKET *r, EAP_PACKET *ep)
 
                /* HMAC it! */
                lrad_hmac_sha1(buffer, hmaclen,
-                              vp->vp_octets, vp->length,
+                              vp->strvalue, vp->length,
                               sha1digest);
 
                /* done with the buffer, free it */
@@ -347,7 +344,7 @@ int unmap_eapsim_basictypes(RADIUS_PACKET *r,
 
        newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
        if (!newvp) return 0;
-       newvp->vp_integer = attr[0];
+       newvp->lvalue = attr[0];
        newvp->length = 1;
        pairadd(&(r->vps), newvp);
 
@@ -382,7 +379,7 @@ int unmap_eapsim_basictypes(RADIUS_PACKET *r,
                }
 
                newvp = paircreate(eapsim_attribute+ATTRIBUTE_EAP_SIM_BASE, PW_TYPE_OCTETS);
-               memcpy(newvp->vp_strvalue, &attr[2], eapsim_len-2);
+               memcpy(newvp->strvalue, &attr[2], eapsim_len-2);
                newvp->length = eapsim_len-2;
                pairadd(&(r->vps), newvp);
                newvp = NULL;
@@ -405,7 +402,7 @@ int unmap_eapsim_types(RADIUS_PACKET *r)
                return 0;
        }
 
-       return unmap_eapsim_basictypes(r, esvp->vp_octets, esvp->length);
+       return unmap_eapsim_basictypes(r, esvp->strvalue, esvp->length);
 }
 
 /*
@@ -492,7 +489,7 @@ eapsim_checkmac(VALUE_PAIR *rvps,
                       key, 16,
                       calcmac);
 
-       if(memcmp(&mac->vp_strvalue[2], calcmac, 16) == 0)      {
+       if(memcmp(&mac->strvalue[2], calcmac, 16) == 0) {
                ret = 1;
        } else {
                ret = 0;
@@ -645,8 +642,8 @@ main(int argc, char *argv[])
 
                        memset(calcmac, 0, sizeof(calcmac));
                        printf("Confirming MAC...");
-                       if(eapsim_checkmac(req2->vps, vpkey->vp_strvalue,
-                                          vpextra->vp_strvalue, vpextra->length,
+                       if(eapsim_checkmac(req2->vps, vpkey->strvalue,
+                                          vpextra->strvalue, vpextra->length,
                                           calcmac)) {
                                printf("succeed\n");
                        } else {
index 1b5b73f..52abbae 100644 (file)
@@ -23,7 +23,7 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * BSD notice:
  *
  *    from this software without specific prior written permission.
  *
  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
- * Copyright 2006  The FreeRADIUS server project
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,7 +61,7 @@ RCSID("$Id$")
 #include <inttypes.h>
 #endif
 
-#include <freeradius-devel/sha1.h>
+#include "sha1.h"
 
 /*
  * we do it in 8-bit chunks, because we have to keep the numbers
@@ -263,3 +259,34 @@ main(int argc, char *argv[])
        printf("\n");
 }
 #endif
+
+
+
+/*
+ * $Log$
+ * Revision 1.3.2.1.2.1  2006-05-19 14:19:15  nbk
+ *     Don't use rad_assert in libeap, it's a server-only function.
+ *
+ * Revision 1.3.2.1  2005/08/24 14:37:52  nbk
+ *     Fix compilation warnings with gcc 4.0
+ *
+ *     Patch from Steven Simon <simon.s@apple.com>
+ *
+ * Revision 1.3  2004/02/26 19:04:30  aland
+ *     perl -i -npe "s/[ \t]+$//g" `find src -name "*.[ch]" -print`
+ *
+ *     Whitespace changes only, from a fresh checkout.
+ *
+ *     For bug # 13
+ *
+ * Revision 1.2  2003/11/06 15:37:24  aland
+ *     Update includes to work a little better
+ *
+ * Revision 1.1  2003/10/29 02:49:19  mcr
+ *     initial commit of eap-sim
+ *
+ *
+ * Local Variables:
+ * c-style: bsd
+ * End:
+ */
index ef80fdc..7bd321c 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2002  Axis Communications AB
- * Copyright 2006  The FreeRADIUS server project
  * Authors: Henrik Eriksson <henriken@axis.com> & Lars Viklund <larsv@axis.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <openssl/hmac.h>
 #include "eap_tls.h"
 
@@ -32,7 +28,7 @@ RCSID("$Id$")
  * Add value pair to reply
  */
 static void add_reply(VALUE_PAIR** vp,
-                     const char* name, const uint8_t * value, int len)
+                     const char* name, const char* value, int len)
 {
        VALUE_PAIR *reply_attr;
        reply_attr = pairmake(name, "", T_OP_EQ);
@@ -43,7 +39,7 @@ static void add_reply(VALUE_PAIR** vp,
                return;
        }
 
-       memcpy(reply_attr->vp_octets, value, len);
+       memcpy(reply_attr->strvalue, value, len);
        reply_attr->length = len;
        pairadd(vp, reply_attr);
 }
index 0ae9d23..07bf8ad 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include "eap_tls.h"
 
 /* record */
@@ -211,7 +206,7 @@ int tls_handshake_recv(tls_session_t *ssn)
                        return 0;
                }
        } else {
-               radlog(L_INFO, "rlm_eap_tls: Application Data");
+               DEBUG2("rlm_eap_tls: Application Data");
                /* Its clean application data, do whatever we want */
                record_init(&ssn->clean_out);
        }
index ec528a2..be3f7ac 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2001,2006  The FreeRADIUS server project
+ * Copyright 2000,2001  The FreeRADIUS server project
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <stdio.h>
 #include "rlm_eap.h"
 
+static const char rcsid[] = "$Id$";
+
 /*
  * Allocate a new EAP_PACKET
  */
@@ -175,7 +173,7 @@ int eaplist_add(rlm_eap_t *inst, EAP_HANDLER *handler)
 {
        int             status;
        VALUE_PAIR      *state;
-
+       
        rad_assert(handler != NULL);
        rad_assert(handler->request != NULL);
 
@@ -199,7 +197,7 @@ int eaplist_add(rlm_eap_t *inst, EAP_HANDLER *handler)
        handler->timestamp = handler->request->timestamp;
        handler->status = 1;
 
-       memcpy(handler->state, state->vp_strvalue, sizeof(handler->state));
+       memcpy(handler->state, state->strvalue, sizeof(handler->state));
        handler->src_ipaddr = handler->request->packet->src_ipaddr;
        handler->eap_id = handler->eap_ds->request->id;
 
@@ -279,7 +277,7 @@ EAP_HANDLER *eaplist_find(rlm_eap_t *inst, REQUEST *request,
 
        myHandler.src_ipaddr = request->packet->src_ipaddr;
        myHandler.eap_id = eap_packet->id;
-       memcpy(myHandler.state, state->vp_strvalue, sizeof(myHandler.state));
+       memcpy(myHandler.state, state->strvalue, sizeof(myHandler.state));
 
        /*
         *      Playing with a data structure shared among threads
@@ -301,7 +299,7 @@ EAP_HANDLER *eaplist_find(rlm_eap_t *inst, REQUEST *request,
                        node = rbtree_find(inst->session_tree, handler);
                        rad_assert(node != NULL);
                        rbtree_delete(inst->session_tree, node);
-
+                       
                        inst->session_head = handler->next;
                        if (handler->next) handler->next->prev = NULL;
                        eap_handler_free(handler);
@@ -374,6 +372,6 @@ EAP_HANDLER *eaplist_find(rlm_eap_t *inst, REQUEST *request,
        eap_ds_free(&(handler->prev_eapds));
        handler->prev_eapds = handler->eap_ds;
        handler->eap_ds = NULL;
-
+       
        return handler;
 }
index 3811cf9..f71e016 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/libradius.h>
+#include <stdio.h>
+#include <stdlib.h>
 
+#if HAVE_UNISTD_H
+#      include <unistd.h>
+#endif
+
+#include <string.h>
 #include <ctype.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+#if HAVE_NETINET_IN_H
+#      include <netinet/in.h>
+#endif
+
+#if HAVE_SYS_SELECT_H
+#      include <sys/select.h>
+#endif
 
 #if HAVE_GETOPT_H
 #      include <getopt.h>
 #endif
 
-#include <freeradius-devel/conf.h>
-#include <freeradius-devel/radpaths.h>
-#include <freeradius-devel/md5.h>
+#include "conf.h"
+#include "radpaths.h"
+#include "missing.h"
+#include "../../include/md5.h"
 
 #include "eap_types.h"
 #include "eap_sim.h"
@@ -153,17 +170,12 @@ static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
                         *      which we did NOT send a request to,
                         *      then complain.
                         */
-                       if (((*rep)->src_ipaddr.af != req->dst_ipaddr.af) ||
-                           (memcmp(&(*rep)->src_ipaddr.ipaddr,
-                                   &req->dst_ipaddr.ipaddr,
-                                   ((req->dst_ipaddr.af == AF_INET ? /* AF_INET6? */
-                                     sizeof(req->dst_ipaddr.ipaddr.ip4addr) : /* FIXME: AF_INET6 */
-                                     sizeof(req->dst_ipaddr.ipaddr.ip6addr)))) != 0) ||
+                       if (((*rep)->src_ipaddr != req->dst_ipaddr) ||
                            ((*rep)->src_port != req->dst_port)) {
-                               char src[128], dst[128];
+                               char src[64], dst[64];
 
-                               ip_ntoh(&(*rep)->src_ipaddr, src, sizeof(src));
-                               ip_ntoh(&req->dst_ipaddr, dst, sizeof(dst));
+                               ip_ntoa(src, (*rep)->src_ipaddr);
+                               ip_ntoa(dst, req->dst_ipaddr);
                                fprintf(stderr, "radclient: ERROR: Sent request to host %s port %d, got response from host %s port %d\n!",
                                        dst, req->dst_port,
                                        src, (*rep)->src_port);
@@ -187,7 +199,7 @@ static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
         *
         *      Hmm... we should really be using eapol_test, which does
         *      a lot more than radeapclient.
-                */
+        */
        if (rad_verify(*rep, req, secret) != 0) {
                librad_perror("rad_verify");
                exit(1);
@@ -264,7 +276,7 @@ static int process_eap_start(RADIUS_PACKET *req,
                return 0;
        }
 
-       versions = (uint16_t *)vp->vp_strvalue;
+       versions = (uint16_t *)vp->strvalue;
 
        /* verify that the attribute length is big enough for a length field */
        if(vp->length < 4)
@@ -336,13 +348,13 @@ static int process_eap_start(RADIUS_PACKET *req,
 
        /* mark the subtype as being EAP-SIM/Response/Start */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
-       newvp->vp_integer = eapsim_start;
+       newvp->lvalue = eapsim_start;
        pairreplace(&(rep->vps), newvp);
 
        /* insert selected version into response. */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_SELECTED_VERSION,
                           PW_TYPE_OCTETS);
-       versions = (uint16_t *)newvp->vp_strvalue;
+       versions = (uint16_t *)newvp->strvalue;
        versions[0] = htons(selectedversion);
        newvp->length = 2;
        pairreplace(&(rep->vps), newvp);
@@ -359,15 +371,15 @@ static int process_eap_start(RADIUS_PACKET *req,
                 */
                newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_NONCE_MT,
                                   PW_TYPE_OCTETS);
-               newvp->vp_octets[0]=0;
-               newvp->vp_octets[1]=0;
+               newvp->strvalue[0]=0;
+               newvp->strvalue[1]=0;
                newvp->length = 18;  /* 16 bytes of nonce + padding */
 
                nonce[0]=lrad_rand();
                nonce[1]=lrad_rand();
                nonce[2]=lrad_rand();
                nonce[3]=lrad_rand();
-               memcpy(&newvp->vp_octets[2], nonce, 16);
+               memcpy(&newvp->strvalue[2], nonce, 16);
                pairreplace(&(rep->vps), newvp);
 
                /* also keep a copy of the nonce! */
@@ -388,16 +400,16 @@ static int process_eap_start(RADIUS_PACKET *req,
                }
                newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_IDENTITY,
                                   PW_TYPE_OCTETS);
-               idlen = strlen(vp->vp_strvalue);
-               pidlen = (uint16_t *)newvp->vp_strvalue;
+               idlen = strlen(vp->strvalue);
+               pidlen = (uint16_t *)newvp->strvalue;
                *pidlen = htons(idlen);
                newvp->length = idlen + 2;
 
-               memcpy(&newvp->vp_strvalue[2], vp->vp_strvalue, idlen);
+               memcpy(&newvp->strvalue[2], vp->strvalue, idlen);
                pairreplace(&(rep->vps), newvp);
 
                /* record it */
-               memcpy(eapsim_mk.identity, vp->vp_strvalue, idlen);
+               memcpy(eapsim_mk.identity, vp->strvalue, idlen);
                eapsim_mk.identitylen = idlen;
        }
 
@@ -426,7 +438,7 @@ static int process_eap_challenge(RADIUS_PACKET *req,
        /* look for the AT_MAC and the challenge data */
        mac   = pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC);
        randvp= pairfind(req->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_RAND);
-       if(mac == NULL || rand == NULL) {
+       if(mac == NULL || randvp == NULL) {
                fprintf(stderr, "radeapclient: challenge message needs to contain RAND and MAC\n");
                return 0;
        }
@@ -439,9 +451,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
          VALUE_PAIR *randcfgvp[3];
          unsigned char *randcfg[3];
 
-         randcfg[0] = &randvp->vp_strvalue[2];
-         randcfg[1] = &randvp->vp_strvalue[2+EAPSIM_RAND_SIZE];
-         randcfg[2] = &randvp->vp_strvalue[2+EAPSIM_RAND_SIZE*2];
+         randcfg[0] = &randvp->strvalue[2];
+         randcfg[1] = &randvp->strvalue[2+EAPSIM_RAND_SIZE];
+         randcfg[2] = &randvp->strvalue[2+EAPSIM_RAND_SIZE*2];
 
          randcfgvp[0] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND1);
          randcfgvp[1] = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_RAND2);
@@ -454,9 +466,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
            return 0;
          }
 
-         if(memcmp(randcfg[0], randcfgvp[0]->vp_strvalue, EAPSIM_RAND_SIZE)!=0 ||
-            memcmp(randcfg[1], randcfgvp[1]->vp_strvalue, EAPSIM_RAND_SIZE)!=0 ||
-            memcmp(randcfg[2], randcfgvp[2]->vp_strvalue, EAPSIM_RAND_SIZE)!=0) {
+         if(memcmp(randcfg[0], randcfgvp[0]->strvalue, EAPSIM_RAND_SIZE)!=0 ||
+            memcmp(randcfg[1], randcfgvp[1]->strvalue, EAPSIM_RAND_SIZE)!=0 ||
+            memcmp(randcfg[2], randcfgvp[2]->strvalue, EAPSIM_RAND_SIZE)!=0) {
            int rnum,i,j;
 
            fprintf(stderr, "radeapclient: one of rand 1,2,3 didn't match\n");
@@ -481,7 +493,7 @@ static int process_eap_challenge(RADIUS_PACKET *req,
                }
                j++;
 
-               fprintf(stderr, "%02x", randcfgvp[rnum]->vp_strvalue[i]);
+               fprintf(stderr, "%02x", randcfgvp[rnum]->strvalue[i]);
              }
              fprintf(stderr, "\n");
            }
@@ -506,9 +518,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
                fprintf(stderr, "radeapclient: needs to have sres1, 2 and 3 set.\n");
                return 0;
        }
-       memcpy(eapsim_mk.sres[0], sres1->vp_strvalue, sizeof(eapsim_mk.sres[0]));
-       memcpy(eapsim_mk.sres[1], sres2->vp_strvalue, sizeof(eapsim_mk.sres[1]));
-       memcpy(eapsim_mk.sres[2], sres3->vp_strvalue, sizeof(eapsim_mk.sres[2]));
+       memcpy(eapsim_mk.sres[0], sres1->strvalue, sizeof(eapsim_mk.sres[0]));
+       memcpy(eapsim_mk.sres[1], sres2->strvalue, sizeof(eapsim_mk.sres[1]));
+       memcpy(eapsim_mk.sres[2], sres3->strvalue, sizeof(eapsim_mk.sres[2]));
 
        Kc1 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC1);
        Kc2 = pairfind(rep->vps, ATTRIBUTE_EAP_SIM_KC2);
@@ -520,9 +532,9 @@ static int process_eap_challenge(RADIUS_PACKET *req,
                fprintf(stderr, "radeapclient: needs to have Kc1, 2 and 3 set.\n");
                return 0;
        }
-       memcpy(eapsim_mk.Kc[0], Kc1->vp_strvalue, sizeof(eapsim_mk.Kc[0]));
-       memcpy(eapsim_mk.Kc[1], Kc2->vp_strvalue, sizeof(eapsim_mk.Kc[1]));
-       memcpy(eapsim_mk.Kc[2], Kc3->vp_strvalue, sizeof(eapsim_mk.Kc[2]));
+       memcpy(eapsim_mk.Kc[0], Kc1->strvalue, sizeof(eapsim_mk.Kc[0]));
+       memcpy(eapsim_mk.Kc[1], Kc2->strvalue, sizeof(eapsim_mk.Kc[1]));
+       memcpy(eapsim_mk.Kc[2], Kc3->strvalue, sizeof(eapsim_mk.Kc[2]));
 
        /* all set, calculate keys */
        eapsim_calculate_keys(&eapsim_mk);
@@ -558,7 +570,7 @@ static int process_eap_challenge(RADIUS_PACKET *req,
 
        /* mark the subtype as being EAP-SIM/Response/Start */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
-       newvp->vp_integer = eapsim_challenge;
+       newvp->lvalue = eapsim_challenge;
        pairreplace(&(rep->vps), newvp);
 
        /*
@@ -567,14 +579,14 @@ static int process_eap_challenge(RADIUS_PACKET *req,
         */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC,
                           PW_TYPE_OCTETS);
-       memcpy(newvp->vp_strvalue+EAPSIM_SRES_SIZE*0, sres1->vp_strvalue, EAPSIM_SRES_SIZE);
-       memcpy(newvp->vp_strvalue+EAPSIM_SRES_SIZE*1, sres2->vp_strvalue, EAPSIM_SRES_SIZE);
-       memcpy(newvp->vp_strvalue+EAPSIM_SRES_SIZE*2, sres3->vp_strvalue, EAPSIM_SRES_SIZE);
+       memcpy(newvp->strvalue+EAPSIM_SRES_SIZE*0, sres1->strvalue, EAPSIM_SRES_SIZE);
+       memcpy(newvp->strvalue+EAPSIM_SRES_SIZE*1, sres2->strvalue, EAPSIM_SRES_SIZE);
+       memcpy(newvp->strvalue+EAPSIM_SRES_SIZE*2, sres3->strvalue, EAPSIM_SRES_SIZE);
        newvp->length = EAPSIM_SRES_SIZE*3;
        pairreplace(&(rep->vps), newvp);
 
        newvp = paircreate(ATTRIBUTE_EAP_SIM_KEY, PW_TYPE_OCTETS);
-       memcpy(newvp->vp_strvalue,    eapsim_mk.K_aut, EAPSIM_AUTH_SIZE);
+       memcpy(newvp->strvalue,    eapsim_mk.K_aut, EAPSIM_AUTH_SIZE);
        newvp->length = EAPSIM_AUTH_SIZE;
        pairreplace(&(rep->vps), newvp);
 
@@ -613,10 +625,10 @@ static int respond_eap_sim(RADIUS_PACKET *req,
        {
                /* must be initial request */
                statevp = paircreate(ATTRIBUTE_EAP_SIM_STATE, PW_TYPE_INTEGER);
-               statevp->vp_integer = eapsim_client_init;
+               statevp->lvalue = eapsim_client_init;
                pairreplace(&(resp->vps), statevp);
        }
-       state = statevp->vp_integer;
+       state = statevp->lvalue;
 
        /*
         * map the attributes, and authenticate them.
@@ -630,7 +642,7 @@ static int respond_eap_sim(RADIUS_PACKET *req,
        {
                return 0;
        }
-       subtype = vp->vp_integer;
+       subtype = vp->lvalue;
 
        /*
         * look for the appropriate state, and process incoming message
@@ -690,7 +702,7 @@ static int respond_eap_sim(RADIUS_PACKET *req,
        /* copy the radius state object in */
        pairreplace(&(resp->vps), radstate);
 
-       statevp->vp_integer = newstate;
+       statevp->lvalue = newstate;
        return 1;
 }
 
@@ -718,7 +730,7 @@ static int respond_eap_md5(RADIUS_PACKET *req,
                fprintf(stderr, "radeapclient: no EAP-ID attribute found\n");
                return 0;
        }
-       identifier = id->vp_integer;
+       identifier = id->lvalue;
 
        if ((vp = pairfind(req->vps, ATTRIBUTE_EAP_BASE+PW_EAP_MD5)) == NULL)
        {
@@ -727,9 +739,9 @@ static int respond_eap_md5(RADIUS_PACKET *req,
        }
 
        /* got the details of the MD5 challenge */
-       valuesize = vp->vp_octets[0];
-       value = &vp->vp_octets[1];
-       name  = &vp->vp_octets[valuesize+1];
+       valuesize = vp->strvalue[0];
+       value = &vp->strvalue[1];
+       name  = &vp->strvalue[valuesize+1];
        namesize = vp->length - (valuesize + 1);
 
        /* sanitize items */
@@ -744,15 +756,15 @@ static int respond_eap_md5(RADIUS_PACKET *req,
         * buffer. We could also call rad_chap_encode, but it wants
         * a CHAP-Challenge, which we don't want to bother with.
         */
-       lrad_MD5Init(&context);
-       lrad_MD5Update(&context, &identifier, 1);
-       lrad_MD5Update(&context, password, strlen(password));
-       lrad_MD5Update(&context, value, valuesize);
-       lrad_MD5Final(response, &context);
+       librad_MD5Init(&context);
+       librad_MD5Update(&context, &identifier, 1);
+       librad_MD5Update(&context, password, strlen(password));
+       librad_MD5Update(&context, value, valuesize);
+       librad_MD5Final(response, &context);
 
        vp = paircreate(ATTRIBUTE_EAP_BASE+PW_EAP_MD5, PW_TYPE_OCTETS);
-       vp->vp_octets[0]=16;
-       memcpy(&vp->vp_strvalue[1], response, 16);
+       vp->strvalue[0]=16;
+       memcpy(&vp->strvalue[1], response, 16);
        vp->length = 17;
 
        pairreplace(&(rep->vps), vp);
@@ -776,16 +788,16 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
        /*
         *      Keep a copy of the the User-Password attribute.
         */
-       if ((vp = pairfind(rep->vps, PW_CLEARTEXT_PASSWORD)) != NULL) {
-               strlcpy(password, (char *)vp->vp_strvalue, sizeof(vp->vp_strvalue));
+       if ((vp = pairfind(rep->vps, ATTRIBUTE_EAP_MD5_PASSWORD)) != NULL) {
+               strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
 
-       } else  if ((vp = pairfind(rep->vps, PW_USER_PASSWORD)) != NULL) {
-               strlcpy(password, (char *)vp->vp_strvalue, sizeof(vp->vp_strvalue));
+       } else  if ((vp = pairfind(rep->vps, PW_PASSWORD)) != NULL) {
+               strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
                /*
                 *      Otherwise keep a copy of the CHAP-Password attribute.
                 */
        } else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {
-               strlcpy(password, (char *)vp->vp_strvalue, sizeof(vp->vp_strvalue));
+               strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));
        } else {
                *password = '\0';
        }
@@ -821,10 +833,10 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
                case PW_DIGEST_NONCE_COUNT:
                case PW_DIGEST_USER_NAME:
                        /* overlapping! */
-                       memmove(&vp->vp_strvalue[2], &vp->vp_octets[0], vp->length);
-                       vp->vp_octets[0] = vp->attribute - PW_DIGEST_REALM + 1;
+                       memmove(&vp->strvalue[2], &vp->strvalue[0], vp->length);
+                       vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
                        vp->length += 2;
-                       vp->vp_octets[1] = vp->length;
+                       vp->strvalue[1] = vp->length;
                        vp->attribute = PW_DIGEST_ATTRIBUTES;
                        break;
                }
@@ -844,19 +856,15 @@ static int sendrecv_eap(RADIUS_PACKET *rep)
                        sizeof(rep->vector));
 
        if (*password != '\0') {
-               if ((vp = pairfind(rep->vps, PW_CLEARTEXT_PASSWORD)) != NULL) {
-                       strlcpy((char *)vp->vp_strvalue, password, sizeof(vp->vp_strvalue));
-                       vp->length = strlen(password);
-
-               } else if ((vp = pairfind(rep->vps, PW_USER_PASSWORD)) != NULL) {
-                       strlcpy((char *)vp->vp_strvalue, password, sizeof(vp->vp_strvalue));
+               if ((vp = pairfind(rep->vps, PW_PASSWORD)) != NULL) {
+                       strNcpy((char *)vp->strvalue, password, strlen(password) + 1);
                        vp->length = strlen(password);
 
                } else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {
-                       strlcpy((char *)vp->vp_strvalue, password, sizeof(vp->vp_strvalue));
+                       strNcpy((char *)vp->strvalue, password, strlen(password) + 1);
                        vp->length = strlen(password);
 
-                       rad_chap_encode(rep, (char *) vp->vp_strvalue, rep->id, vp);
+                       rad_chap_encode(rep, (char *) vp->strvalue, rep->id, vp);
                        vp->length = 17;
                }
        } /* there WAS a password */
@@ -1087,7 +1095,8 @@ int main(int argc, char **argv)
         *      Resolve hostname.
         */
        req->dst_port = port;
-       if (ip_hton(argv[1], AF_INET, &req->dst_ipaddr) < 0) {
+       req->dst_ipaddr = ip_getaddr(argv[1]);
+       if (req->dst_ipaddr == INADDR_NONE) {
                fprintf(stderr, "radclient: Failed to find IP address for host %s\n", argv[1]);
                exit(1);
        }
index e2ee0f9..4f9a848 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000-2003,2006  The FreeRADIUS server project
+ * Copyright 2000-2003  The FreeRADIUS server project
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
+#include "autoconf.h"
 #include "rlm_eap.h"
+#include "modules.h"
+
+static const char rcsid[] = "$Id$";
 
 static const CONF_PARSER module_config[] = {
        { "default_eap_type", PW_TYPE_STRING_PTR,
@@ -64,6 +62,7 @@ static int eap_detach(void *instance)
 
        pthread_mutex_destroy(&(inst->session_mutex));
 
+       if (inst->default_eap_type_name) free(inst->default_eap_type_name);
        free(inst);
 
        return 0;
@@ -75,16 +74,14 @@ static int eap_detach(void *instance)
  */
 static int eap_handler_cmp(const void *a, const void *b)
 {
-       int rcode;
        const EAP_HANDLER *one = a;
        const EAP_HANDLER *two = b;
 
-
        if (one->eap_id < two->eap_id) return -1;
        if (one->eap_id > two->eap_id) return +1;
 
-       rcode = lrad_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr);
-       if (rcode != 0) return rcode;
+       if (one->src_ipaddr < two->src_ipaddr) return -1;
+       if (one->src_ipaddr > two->src_ipaddr) return +1;
 
        return memcmp(one->state, two->state, sizeof(one->state));
 }
@@ -116,7 +113,7 @@ static int eap_instantiate(CONF_SECTION *cs, void **instance)
                scs != NULL;
                scs=cf_subsection_find_next(cs, scs, NULL)) {
 
-               const char      *auth_type;
+               char    *auth_type;
 
                auth_type = cf_section_name1(scs);
 
@@ -130,27 +127,6 @@ static int eap_instantiate(CONF_SECTION *cs, void **instance)
                        return -1;
                }
 
-#ifdef NO_OPENSSL
-               /*
-                *      This allows the default configuration to be
-                *      shipped with EAP-TLS, etc. enabled.  If the
-                *      system doesn't have OpenSSL, they will be
-                *      ignored.
-                *
-                *      If the system does have OpenSSL, then this
-                *      code will not be used.  The administrator will
-                *      then have to delete the tls,
-                *      etc. configurations from eap.conf in order to
-                *      have EAP without the TLS types.
-                */
-               if ((eap_type == PW_EAP_TLS) ||
-                   (eap_type == PW_EAP_TTLS) ||
-                   (eap_type == PW_EAP_PEAP)) {
-                       DEBUG2("rlm_eap: Ignoring EAP-Type/%s because we do not have OpenSSL support.", auth_type);
-                       continue;
-               }
-#endif
-
                /*
                 *      If we're asked to load TTLS or PEAP, ensure
                 *      that we've first loaded TLS.
@@ -261,7 +237,7 @@ static int eap_authenticate(void *instance, REQUEST *request)
         *      If it's a recursive request, then disallow
         *      TLS, TTLS, and PEAP, inside of the TLS tunnel.
         */
-       if (request->packet->dst_port == 0) {
+       if ((request->options & RAD_REQUEST_OPTION_FAKE_REQUEST) != 0) {
                switch(handler->eap_ds->response->type.type) {
                case PW_EAP_TLS:
                case PW_EAP_TTLS:
@@ -346,7 +322,7 @@ static int eap_authenticate(void *instance, REQUEST *request)
                                pairadd(&(request->proxy->vps), vp);
                        }
                }
-
+                       
                /*
                 *      Delete the "proxied to" attribute, as it's
                 *      set to 127.0.0.1 for tunneled requests, and
@@ -408,7 +384,7 @@ static int eap_authenticate(void *instance, REQUEST *request)
                 */
                vp = pairfind(request->reply->vps, PW_USER_NAME);
                if (!vp) {
-                       vp = pairmake("User-Name", request->username->vp_strvalue,
+                       vp = pairmake("User-Name", request->username->strvalue,
                                      T_OP_EQ);
                        rad_assert(vp != NULL);
                        pairadd(&(request->reply->vps), vp);
@@ -419,8 +395,8 @@ static int eap_authenticate(void *instance, REQUEST *request)
                 *      terminated string in Access-Accept.
                 */
                if ((inst->cisco_accounting_username_bug) &&
-                   (vp->length < (int) sizeof(vp->vp_strvalue))) {
-                       vp->vp_strvalue[vp->length] = '\0';
+                   (vp->length < (int) sizeof(vp->strvalue))) {
+                       vp->strvalue[vp->length] = '\0';
                        vp->length++;
                }
        }
@@ -466,7 +442,6 @@ static int eap_authorize(void *instance, REQUEST *request)
                return RLM_MODULE_FAIL;
        case EAP_FOUND:
                return RLM_MODULE_HANDLED;
-       case EAP_OK:
        case EAP_NOTFOUND:
        default:
                break;
@@ -483,7 +458,7 @@ static int eap_authorize(void *instance, REQUEST *request)
 
        vp = pairfind(request->config_items, PW_AUTH_TYPE);
        if ((!vp) ||
-           (vp->vp_integer != PW_AUTHTYPE_REJECT)) {
+           (vp->lvalue != PW_AUTHTYPE_REJECT)) {
                vp = pairmake("Auth-Type", "EAP", T_OP_EQ);
                if (!vp) {
                        return RLM_MODULE_FAIL;
@@ -491,8 +466,6 @@ static int eap_authorize(void *instance, REQUEST *request)
                pairadd(&request->config_items, vp);
        }
 
-       if (status == EAP_OK) return RLM_MODULE_OK;
-
        return RLM_MODULE_UPDATED;
 }
 
@@ -570,7 +543,7 @@ static int eap_post_proxy(void *inst, REQUEST *request)
                         */
                        vp = pairfind(request->reply->vps, PW_USER_NAME);
                        if (!vp) {
-                               vp = pairmake("User-Name", request->username->vp_strvalue,
+                               vp = pairmake("User-Name", request->username->strvalue,
                                              T_OP_EQ);
                                rad_assert(vp != NULL);
                                pairadd(&(request->reply->vps), vp);
@@ -604,7 +577,7 @@ static int eap_post_proxy(void *inst, REQUEST *request)
                 *
                 *      The format is VERY specific!
                 */
-               if (strncasecmp(vp->vp_strvalue, "leap:session-key=", 17) == 0) {
+               if (strncasecmp(vp->strvalue, "leap:session-key=", 17) == 0) {
                        break;
                }
 
@@ -627,8 +600,8 @@ static int eap_post_proxy(void *inst, REQUEST *request)
         *      Decrypt the session key, using the proxy data.
         */
        i = 34;                 /* starts off with 34 octets */
-       len = rad_tunnel_pwdecode(vp->vp_strvalue + 17, &i,
-                                 request->home_server->secret,
+       len = rad_tunnel_pwdecode(vp->strvalue + 17, &i,
+                                 request->proxysecret,
                                  request->proxy->vector);
 
        /*
@@ -638,8 +611,8 @@ static int eap_post_proxy(void *inst, REQUEST *request)
        /*
         *      Encrypt the session key again, using the request data.
         */
-       rad_tunnel_pwencode(vp->vp_strvalue + 17, &len,
-                           request->client->secret,
+       rad_tunnel_pwencode(vp->strvalue + 17, &len,
+                           request->secret,
                            request->packet->vector);
 
        return RLM_MODULE_UPDATED;
@@ -651,11 +624,10 @@ static int eap_post_proxy(void *inst, REQUEST *request)
  *     That is, everything else should be 'static'.
  */
 module_t rlm_eap = {
-       RLM_MODULE_INIT,
        "eap",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        eap_instantiate,                /* instantiation */
-       eap_detach,                     /* detach */
        {
                eap_authenticate,       /* authentication */
                eap_authorize,          /* authorization */
@@ -666,4 +638,6 @@ module_t rlm_eap = {
                eap_post_proxy,         /* post-proxy */
                NULL                    /* post-auth */
        },
+       eap_detach,                     /* detach */
+       NULL,                           /* destroy */
 };
index 67ea755..3d33c77 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
 #ifndef _RLM_EAP_H
 #define _RLM_EAP_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rlm_eap_h, "$Id$")
-
 #include <ltdl.h>
 #include "eap.h"
 #include "eap_types.h"
index 13cc7ec..3e165b5 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
- * Copyright 2006  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include "rlm_eap.h"
 
+static const char rcsid[] = "$Id$";
+
 /*
  *     Global key to generate & verify State
  *
@@ -148,8 +146,8 @@ VALUE_PAIR *generate_state(time_t timestamp)
                radlog(L_ERR, "rlm_eap: out of memory");
                return NULL;
        }
-       memcpy(state->vp_strvalue, challenge, sizeof(challenge));
-       memcpy(state->vp_strvalue + sizeof(challenge), hmac,
+       memcpy(state->strvalue, challenge, sizeof(challenge));
+       memcpy(state->strvalue + sizeof(challenge), hmac,
               EAP_USE_OF_HMAC);
 
        state->length = sizeof(challenge) + EAP_USE_OF_HMAC;
@@ -176,7 +174,7 @@ int verify_state(VALUE_PAIR *state, time_t timestamp)
         *      The first 16 octets of the State attribute constains
         *      the random challenge.
         */
-       memcpy(value, state->vp_strvalue, EAP_CHALLENGE_LEN);
+       memcpy(value, state->strvalue, EAP_CHALLENGE_LEN);
        memcpy(value + EAP_CHALLENGE_LEN, &timestamp, sizeof(timestamp));
 
        /* Generate hmac.  */
@@ -187,7 +185,7 @@ int verify_state(VALUE_PAIR *state, time_t timestamp)
         *      Compare the hmac we calculated to the one in the
         *      packet.
         */
-       return memcmp(hmac, state->vp_strvalue + EAP_CHALLENGE_LEN,
+       return memcmp(hmac, state->strvalue + EAP_CHALLENGE_LEN,
                      EAP_USE_OF_HMAC);
 }
 
index 09879ff..aff91fd 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "eap.h"
 
-#include <freeradius-devel/rad_assert.h>
+#include <rad_assert.h>
 
 /*
  *     EAP-GTC is just ASCII data carried inside of the EAP session.
@@ -61,6 +58,8 @@ static int gtc_detach(void *arg)
 {
        rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) arg;
 
+       if (inst->challenge) free(inst->challenge);
+       if (inst->auth_type_name) free(inst->auth_type_name);
 
        free(inst);
 
@@ -156,7 +155,7 @@ static int gtc_authenticate(void *type_data, EAP_HANDLER *handler)
        rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) type_data;
 
        /*
-        *      Get the Cleartext-Password for this user.
+        *      Get the User-Password for this user.
         */
        rad_assert(handler->request != NULL);
        rad_assert(handler->stage == AUTHENTICATE);
@@ -192,9 +191,9 @@ static int gtc_authenticate(void *type_data, EAP_HANDLER *handler)
                /*
                 *      For now, do clear-text password authentication.
                 */
-               vp = pairfind(handler->request->config_items, PW_CLEARTEXT_PASSWORD);
+               vp = pairfind(handler->request->config_items, PW_PASSWORD);
                if (!vp) {
-                       DEBUG2("  rlm_eap_gtc: ERROR: Cleartext-Password is required for authentication.");
+                       DEBUG2("  rlm_eap_gtc: ERROR: Clear-test User-Password is required for authentication.");
                        eap_ds->request->code = PW_EAP_FAILURE;
                        return 0;
                }
@@ -206,7 +205,7 @@ static int gtc_authenticate(void *type_data, EAP_HANDLER *handler)
                }
 
                if (memcmp(eap_ds->response->type.data,
-                          vp->vp_strvalue, vp->length) != 0) {
+                          vp->strvalue, vp->length) != 0) {
                        DEBUG2("  rlm_eap_gtc: ERROR: Passwords are different");
                        eap_ds->request->code = PW_EAP_FAILURE;
                        return 0;
@@ -223,7 +222,7 @@ static int gtc_authenticate(void *type_data, EAP_HANDLER *handler)
                 *      If there was a User-Password in the request,
                 *      why the heck are they using EAP-GTC?
                 */
-               pairdelete(&handler->request->packet->vps, PW_USER_PASSWORD);
+               rad_assert(handler->request->password == NULL);
 
                vp = pairmake("User-Password", "", T_OP_EQ);
                if (!vp) {
@@ -231,8 +230,8 @@ static int gtc_authenticate(void *type_data, EAP_HANDLER *handler)
                        return 0;
                }
                vp->length = eap_ds->response->type.length;
-               memcpy(vp->vp_strvalue, eap_ds->response->type.data, vp->length);
-               vp->vp_strvalue[vp->length] = 0;
+               memcpy(vp->strvalue, eap_ds->response->type.data, vp->length);
+               vp->strvalue[vp->length] = 0;
 
                /*
                 *      Add the password to the request, and allow
index 1595f23..f3b624d 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003 Alan DeKok <aland@freeradius.org>
- * Copyright 2006 The FreeRADIUS server project
  */
 
 /*
@@ -44,9 +43,6 @@
  *  The LEAP type (0x11) is *not* included in the type data...
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <stdio.h>
 #include <stdlib.h>
 #include "eap.h"
@@ -214,7 +210,7 @@ static int eapleap_ntpwdhash(unsigned char *ntpwdhash, VALUE_PAIR *password)
                         *  Yes, the *even* bytes have the values,
                         *  and the *odd* bytes are zero.
                         */
-                       unicode[(i << 1)] = password->vp_strvalue[i];
+                       unicode[(i << 1)] = password->strvalue[i];
                }
 
                /*
@@ -224,8 +220,8 @@ static int eapleap_ntpwdhash(unsigned char *ntpwdhash, VALUE_PAIR *password)
 
        } else {                /* MUST be NT-Password */
                if (password->length == 32) {
-                       password->length = lrad_hex2bin(password->vp_strvalue,
-                                                       password->vp_octets,
+                       password->length = lrad_hex2bin(password->strvalue,
+                                                       password->strvalue,
                                                        16);
                }
                if (password->length != 16) {
@@ -233,7 +229,7 @@ static int eapleap_ntpwdhash(unsigned char *ntpwdhash, VALUE_PAIR *password)
                        return 0;
                }
 
-               memcpy(ntpwdhash, password->vp_strvalue, 16);
+               memcpy(ntpwdhash, password->strvalue, 16);
        }
        return 1;
 }
@@ -285,7 +281,7 @@ LEAP_PACKET *eapleap_stage6(LEAP_PACKET *packet, REQUEST *request,
        unsigned char ntpwdhash[16], ntpwdhashhash[16];
        unsigned char buffer[256];
        LEAP_PACKET *reply;
-       unsigned char *p;
+       char *p;
        VALUE_PAIR *vp;
 
        /*
@@ -322,7 +318,7 @@ LEAP_PACKET *eapleap_stage6(LEAP_PACKET *packet, REQUEST *request,
        /*
         *      Copy the name over, and ensure it's NUL terminated.
         */
-       memcpy(reply->name, user_name->vp_strvalue, user_name->length);
+       memcpy(reply->name, user_name->strvalue, user_name->length);
        reply->name[user_name->length] = '\0';
        reply->name_len = user_name->length;
 
@@ -371,13 +367,13 @@ LEAP_PACKET *eapleap_stage6(LEAP_PACKET *packet, REQUEST *request,
         */
        librad_md5_calc(ntpwdhash, buffer, 16 + 8 + 24 + 8 + 24);
 
-       memcpy(vp->vp_strvalue + vp->length, ntpwdhash, 16);
-       memset(vp->vp_strvalue + vp->length + 16, 0,
-              sizeof(vp->vp_strvalue) - (vp->length + 16));
+       memcpy(vp->strvalue + vp->length, ntpwdhash, 16);
+       memset(vp->strvalue + vp->length + 16, 0,
+              sizeof(vp->strvalue) - (vp->length + 16));
 
        i = 16;
-       rad_tunnel_pwencode(vp->vp_strvalue + vp->length, &i,
-                           request->client->secret, request->packet->vector);
+       rad_tunnel_pwencode(vp->strvalue + vp->length, &i,
+                           request->secret, request->packet->vector);
        vp->length += i;
        pairadd(reply_vps, vp);
 
@@ -432,7 +428,7 @@ LEAP_PACKET *eapleap_initiate(UNUSED EAP_DS *eap_ds, VALUE_PAIR *user_name)
        /*
         *      Copy the name over, and ensure it's NUL terminated.
         */
-       memcpy(reply->name, user_name->vp_strvalue, user_name->length);
+       memcpy(reply->name, user_name->strvalue, user_name->length);
        reply->name[user_name->length] = '\0';
        reply->name_len = user_name->length;
 
index eb23f57..c35202c 100644 (file)
@@ -1,9 +1,6 @@
 #ifndef _EAP_LEAP_H
 #define _EAP_LEAP_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_leap_h, "$Id$")
-
 #include "eap.h"
 
 #define PW_LEAP_CHALLENGE      1
index 6321706..d492aba 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003 Alan DeKok <aland@freeradius.org>
- * Copyright 2006 The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -40,7 +36,7 @@ RCSID("$Id$")
  * len = header + type + leap_typedata
  * leap_typedata = value_size + value
  */
-static int leap_initiate(UNUSED void *instance, EAP_HANDLER *handler)
+static int leap_initiate(void *instance, EAP_HANDLER *handler)
 {
        leap_session_t  *session;
        LEAP_PACKET     *reply;
@@ -90,7 +86,7 @@ static int leap_initiate(UNUSED void *instance, EAP_HANDLER *handler)
        return 1;
 }
 
-static int leap_authenticate(UNUSED void *instance, EAP_HANDLER *handler)
+static int leap_authenticate(void *instance, EAP_HANDLER *handler)
 {
        int             rcode;
        leap_session_t  *session;
@@ -112,16 +108,16 @@ static int leap_authenticate(UNUSED void *instance, EAP_HANDLER *handler)
        if (!(packet = eapleap_extract(handler->eap_ds)))
                return 0;
 
-       username = (char *)handler->request->username->vp_strvalue;
+       username = (char *)handler->request->username->strvalue;
 
        /*
         *      The password is never sent over the wire.
         *      Always get the configured password, for each user.
         */
-       password = pairfind(handler->request->config_items, PW_CLEARTEXT_PASSWORD);
+       password = pairfind(handler->request->config_items, PW_PASSWORD);
        if (!password) password = pairfind(handler->request->config_items, PW_NT_PASSWORD);
        if (!password) {
-               radlog(L_INFO, "rlm_eap_leap: No Cleartext-Password or NT-Password configured for this user");
+               radlog(L_INFO, "rlm_eap_leap: No User-Password or NT-Password configured for this user");
                eapleap_free(&packet);
                return 0;
        }
@@ -134,6 +130,7 @@ static int leap_authenticate(UNUSED void *instance, EAP_HANDLER *handler)
        case 4:                 /* Verify NtChallengeResponse */
                DEBUG2("  rlm_eap_leap: Stage 4");
                rcode = eapleap_stage4(packet, password, session);
+               eapleap_free(&packet);
                session->stage = 6;
 
                /*
@@ -142,7 +139,6 @@ static int leap_authenticate(UNUSED void *instance, EAP_HANDLER *handler)
                 */
                if (!rcode) {
                        handler->eap_ds->request->code = PW_EAP_FAILURE;
-                       eapleap_free(&packet);
                        return 0;
                }
 
index c753f1c..b7ccc4d 100644 (file)
@@ -5,7 +5,6 @@
    SMB authentication protocol
 
    Copyright (C) Andrew Tridgell 1998
-   Copyright 2006 The FreeRADIUS server project
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    should confirm it for yourself (and maybe let me know if you come
    up with a different answer to the one above)
 */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
+#include "libradius.h"
 #include <string.h>
 #include <ctype.h>
-#include "eap_leap.h"
+
 
 #define uchar unsigned char
 
@@ -1,13 +1,11 @@
 #
-# Makefile
-#
-# Version:     $Id$
+# $Id$
 #
 
-TARGET      = rlm_eap_md5
+TARGET      = @targetname@
 SRCS        = rlm_eap_md5.c eap_md5.c
 HEADERS     = eap_md5.h
-RLM_CFLAGS  = $(INCLTDL) -I../.. -I../../libeap
+RLM_CFLAGS  = -I../.. -I../../libeap $(INCLTDL)
 RLM_INSTALL =
 
 RLM_DIR=../../
similarity index 53%
rename from src/modules/rlm_acctlog/configure
rename to src/modules/rlm_eap/types/rlm_eap_md5/configure
index 904ed0f..39dfd93 100755 (executable)
@@ -1,10 +1,9 @@
 #! /bin/sh
-# From configure.in 0.1.
+# From configure.in Revision: 1.1 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.60.
+# Generated by GNU Autoconf 2.59.
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 ## --------------------- ##
@@ -18,35 +17,11 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -55,43 +30,8 @@ else
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""       $as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
 # Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
+$as_unset ENV MAIL MAILPATH
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -105,19 +45,18 @@ do
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
@@ -125,386 +64,157 @@ fi
 
 
 # Name of the executable.
-as_me=`$as_basename -- "$0" ||
+as_me=`$as_basename "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
-  if (eval ":") 2>/dev/null; then
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-
-  if test $as_have_required = yes &&    (eval ":
-(as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
 
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
 
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
 fi
 
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
 
-test \$exitcode = 0) || { (exit 1); exit 1; }
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
 
-(
-  as_lineno_1=\$LINENO
-  as_lineno_2=\$LINENO
-  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
-  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
-  :
-else
-  as_candidate_shells=
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
     as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  case $as_dir in
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
         /*)
-          for as_base in sh bash ksh sh5; do
-            as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
-          done;;
-       esac
-done
-IFS=$as_save_IFS
-
-
-      for as_shell in $as_candidate_shells $SHELL; do
-        # Try only shells that exist, to save several forks.
-        if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-               { ("$as_shell") 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-_ASEOF
-}; then
-  CONFIG_SHELL=$as_shell
-              as_have_required=yes
-              if { "$as_shell" 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-(as_func_return () {
-  (exit $1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
-  break
-fi
-
-fi
-
-      done
-
-      if test "x$CONFIG_SHELL" != x; then
-  for as_var in BASH_ENV ENV
-        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-        done
-        export CONFIG_SHELL
-        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
-    if test $as_have_required = no; then
-  echo This script requires a shell more modern than all the
-      echo shells that I found on your system.  Please install a
-      echo modern shell, or manually run the script under such a
-      echo shell if you do have one.
-      { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
-  echo No shell found that supports shell functions.
-  echo Please tell autoconf@gnu.org about your system,
-  echo including any error possibly output before this
-  echo message
-}
-
-
-
+          if ("$as_dir/$as_base" -c '
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
 
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
     sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
       N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
       t loop
-      s/-\n.*//
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
     ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
+  chmod +x $as_me.lineno ||
     { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
   # Exit status is that of the last command.
   exit
 }
 
 
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
     as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
+rm -f conf$$ conf$$.exe conf$$.file
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -513,19 +223,7 @@ else
   as_mkdir_p=false
 fi
 
-# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  as_executable_p="test -x"
-else
-  as_executable_p=:
-fi
-rm -f conf$$.file
+as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -534,27 +232,39 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
 
-exec 7<&0 </dev/null 6>&1
 
 # Name of the host.
 # hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
+exec 6>&1
+
 #
 # Initializations.
 #
 ac_default_prefix=/usr/local
-ac_clean_files=
 ac_config_libobj_dir=.
-LIBOBJS=
 cross_compiling=no
 subdirs=
 MFLAGS=
 MAKEFLAGS=
 SHELL=${CONFIG_SHELL-/bin/sh}
 
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
 # Identity of this package.
 PACKAGE_NAME=
 PACKAGE_TARNAME=
@@ -562,7 +272,7 @@ PACKAGE_VERSION=
 PACKAGE_STRING=
 PACKAGE_BUGREPORT=
 
-ac_unique_file="rlm_acctlog.c"
+ac_unique_file="rlm_eap_md5.c"
 # Factoring default headers for most tests.
 ac_includes_default="\
 #include <stdio.h>
@@ -591,76 +301,17 @@ ac_includes_default="\
 #endif
 #if HAVE_INTTYPES_H
 # include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
 #endif
 #if HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-CPP
-GREP
-EGREP
-acctlog_cflags
-acctlog_ldflags
-targetname
-LIBOBJS
-LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP eap_md5_cflags eap_md5_ldflags targetname LIBOBJS LTLIBOBJS'
 ac_subst_files=''
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-CPP'
-
 
 # Initialize some variables set by options.
 ac_init_help=
@@ -687,48 +338,34 @@ x_libraries=NONE
 # and all the variables that are supposed to be based on exec_prefix
 # by default will actually change.
 # Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
 bindir='${exec_prefix}/bin'
 sbindir='${exec_prefix}/sbin'
 libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
+datadir='${prefix}/share'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
 
 ac_prev=
-ac_dashdash=
 for ac_option
 do
   # If the previous option needs an argument, assign it.
   if test -n "$ac_prev"; then
-    eval $ac_prev=\$ac_option
+    eval "$ac_prev=\$ac_option"
     ac_prev=
     continue
   fi
 
-  case $ac_option in
-  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)   ac_optarg=yes ;;
-  esac
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
 
-  case $ac_dashdash$ac_option in
-  --)
-    ac_dashdash=yes ;;
+  case $ac_option in
 
   -bindir | --bindir | --bindi | --bind | --bin | --bi)
     ac_prev=bindir ;;
@@ -750,18 +387,12 @@ do
   --config-cache | -C)
     cache_file=config.cache ;;
 
-  -datadir | --datadir | --datadi | --datad)
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
     ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
     datadir=$ac_optarg ;;
 
-  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
-  | --dataroo | --dataro | --datar)
-    ac_prev=datarootdir ;;
-  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
-  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
-    datarootdir=$ac_optarg ;;
-
   -disable-* | --disable-*)
     ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
@@ -769,17 +400,7 @@ do
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
     ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval enable_$ac_feature=no ;;
-
-  -docdir | --docdir | --docdi | --doc | --do)
-    ac_prev=docdir ;;
-  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
-    docdir=$ac_optarg ;;
-
-  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
-    ac_prev=dvidir ;;
-  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
-    dvidir=$ac_optarg ;;
+    eval "enable_$ac_feature=no" ;;
 
   -enable-* | --enable-*)
     ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
@@ -788,7 +409,11 @@ do
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
     ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval enable_$ac_feature=\$ac_optarg ;;
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -815,12 +440,6 @@ do
   -host=* | --host=* | --hos=* | --ho=*)
     host_alias=$ac_optarg ;;
 
-  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
-    ac_prev=htmldir ;;
-  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
-  | --ht=*)
-    htmldir=$ac_optarg ;;
-
   -includedir | --includedir | --includedi | --included | --include \
   | --includ | --inclu | --incl | --inc)
     ac_prev=includedir ;;
@@ -845,16 +464,13 @@ do
   | --libexe=* | --libex=* | --libe=*)
     libexecdir=$ac_optarg ;;
 
-  -localedir | --localedir | --localedi | --localed | --locale)
-    ac_prev=localedir ;;
-  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
-    localedir=$ac_optarg ;;
-
   -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst | --locals)
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
     ac_prev=localstatedir ;;
   -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
     localstatedir=$ac_optarg ;;
 
   -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -919,16 +535,6 @@ do
   | --progr-tra=* | --program-tr=* | --program-t=*)
     program_transform_name=$ac_optarg ;;
 
-  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
-    ac_prev=pdfdir ;;
-  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
-    pdfdir=$ac_optarg ;;
-
-  -psdir | --psdir | --psdi | --psd | --ps)
-    ac_prev=psdir ;;
-  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
-    psdir=$ac_optarg ;;
-
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
@@ -985,7 +591,11 @@ do
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
     ac_package=`echo $ac_package| sed 's/-/_/g'`
-    eval with_$ac_package=\$ac_optarg ;;
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
 
   -without-* | --without-*)
     ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
@@ -994,7 +604,7 @@ do
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
     ac_package=`echo $ac_package | sed 's/-/_/g'`
-    eval with_$ac_package=no ;;
+    eval "with_$ac_package=no" ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -1025,7 +635,8 @@ Try \`$0 --help' for more information." >&2
     expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
    { (exit 1); exit 1; }; }
-    eval $ac_envvar=\$ac_optarg
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
     export $ac_envvar ;;
 
   *)
@@ -1045,19 +656,27 @@ if test -n "$ac_prev"; then
    { (exit 1); exit 1; }; }
 fi
 
-# Be sure to have absolute directory names.
-for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
-               datadir sysconfdir sharedstatedir localstatedir includedir \
-               oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
 do
-  eval ac_val=\$$ac_var
+  eval ac_val=$`echo $ac_var`
   case $ac_val in
-    [\\/$]* | ?:[\\/]* )  continue;;
-    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
   esac
-  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; }
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1084,76 +703,74 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias-
 test "$silent" = yes && exec 6>/dev/null
 
 
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  { echo "$as_me: error: Working directory cannot be determined" >&2
-   { (exit 1); exit 1; }; }
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  { echo "$as_me: error: pwd does not report name of working directory" >&2
-   { (exit 1); exit 1; }; }
-
-
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$0" ||
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
 $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$0" : 'X\(//\)[^/]' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$0" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r "$srcdir/$ac_unique_file"; then
+  if test ! -r $srcdir/$ac_unique_file; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r "$srcdir/$ac_unique_file"; then
-  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
    { (exit 1); exit 1; }; }
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
-       cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
    { (exit 1); exit 1; }; }
-       pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
-  srcdir=.
+  fi
 fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
-  eval ac_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_env_${ac_var}_value=\$${ac_var}
-  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
 
 #
 # Report the --help message.
@@ -1182,6 +799,9 @@ Configuration:
   -n, --no-create         do not create output files
       --srcdir=DIR        find the sources in DIR [configure dir or \`..']
 
+_ACEOF
+
+  cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
@@ -1199,22 +819,15 @@ Fine tuning of the installation directories:
   --bindir=DIR           user executables [EPREFIX/bin]
   --sbindir=DIR          system admin executables [EPREFIX/sbin]
   --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
   --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
   --libdir=DIR           object code libraries [EPREFIX/lib]
   --includedir=DIR       C header files [PREFIX/include]
   --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR          info documentation [DATAROOTDIR/info]
-  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR           man documentation [DATAROOTDIR/man]
-  --docdir=DIR           documentation root [DATAROOTDIR/doc/PACKAGE]
-  --htmldir=DIR          html documentation [DOCDIR]
-  --dvidir=DIR           dvi documentation [DOCDIR]
-  --pdfdir=DIR           pdf documentation [DOCDIR]
-  --psdir=DIR            ps documentation [DOCDIR]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
 _ACEOF
 
   cat <<\_ACEOF
@@ -1230,94 +843,126 @@ Some influential environment variables:
   CFLAGS      C compiler flags
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
   CPP         C preprocessor
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
 _ACEOF
-ac_status=$?
 fi
 
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" || continue
+    test -d $ac_dir || continue
     ac_builddir=.
 
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
+if test "$ac_dir" != .; then
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
 
 case $srcdir in
-  .)  # We are building in place.
+  .)  # No --srcdir option.  We are building in place.
     ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
 esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
+    fi
+    cd $ac_popdir
   done
 fi
 
-test -n "$ac_init_help" && exit $ac_status
+test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.60
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
-  exit
+  exit 0
 fi
-cat >config.log <<_ACEOF
+exec 5>config.log
+cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
 
 _ACEOF
-exec 5>>config.log
 {
 cat <<_ASUNAME
 ## --------- ##
@@ -1336,7 +981,7 @@ uname -v = `(uname -v) 2>/dev/null || echo unknown`
 /bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
 /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
 /bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
 /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
@@ -1350,7 +995,6 @@ do
   test -z "$as_dir" && as_dir=.
   echo "PATH: $as_dir"
 done
-IFS=$as_save_IFS
 
 } >&5
 
@@ -1372,6 +1016,7 @@ _ACEOF
 ac_configure_args=
 ac_configure_args0=
 ac_configure_args1=
+ac_sep=
 ac_must_keep_next=false
 for ac_pass in 1 2
 do
@@ -1382,7 +1027,7 @@ do
     -q | -quiet | --quiet | --quie | --qui | --qu | --q \
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
-    *\'*)
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
       ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
@@ -1404,7 +1049,9 @@ do
          -* ) ac_must_keep_next=true ;;
        esac
       fi
-      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
       ;;
     esac
   done
@@ -1415,8 +1062,8 @@ $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
 trap 'exit_status=$?
   # Save into config.log some information that might help in debugging.
   {
@@ -1429,34 +1076,20 @@ trap 'exit_status=$?
 _ASBOX
     echo
     # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
+{
   (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
       sed -n \
-       "s/'\''/'\''\\\\'\'''\''/g;
-         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
     *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
-    esac |
-    sort
-)
+    esac;
+}
     echo
 
     cat <<\_ASBOX
@@ -1467,28 +1100,22 @@ _ASBOX
     echo
     for ac_var in $ac_subst_vars
     do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      echo "$ac_var='\''$ac_val'\''"
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
       cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
+## ------------- ##
+## Output files. ##
+## ------------- ##
 _ASBOX
       echo
       for ac_var in $ac_subst_files
       do
-       eval ac_val=\$$ac_var
-       case $ac_val in
-       *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-       esac
-       echo "$ac_var='\''$ac_val'\''"
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
       done | sort
       echo
     fi
@@ -1500,24 +1127,26 @@ _ASBOX
 ## ----------- ##
 _ASBOX
       echo
-      cat confdefs.h
+      sed "/^$/d" confdefs.h | sort
       echo
     fi
     test "$ac_signal" != 0 &&
       echo "$as_me: caught signal $ac_signal"
     echo "$as_me: exit $exit_status"
   } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
-' 0
+     ' 0
 for ac_signal in 1 2 13 15; do
   trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
 done
 ac_signal=0
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
 
 # Predefined preprocessor variables.
 
@@ -1548,17 +1177,14 @@ _ACEOF
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
-  set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
-  set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
-  set x "$ac_default_prefix/share/config.site" \
-       "$ac_default_prefix/etc/config.site"
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
 fi
-shift
-for ac_site_file
-do
+for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
     { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
 echo "$as_me: loading site script $ac_site_file" >&6;}
@@ -1574,8 +1200,8 @@ if test -r "$cache_file"; then
     { echo "$as_me:$LINENO: loading cache $cache_file" >&5
 echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
     esac
   fi
 else
@@ -1587,11 +1213,12 @@ fi
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
   eval ac_old_set=\$ac_cv_env_${ac_var}_set
   eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
   case $ac_old_set,$ac_new_set in
     set,)
       { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
@@ -1616,7 +1243,8 @@ echo "$as_me:   current value: $ac_new_val" >&2;}
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
@@ -1633,6 +1261,12 @@ echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start ov
    { (exit 1); exit 1; }; }
 fi
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 
 
 
@@ -1649,18 +1283,15 @@ fi
 
 
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
 
 
-if test x$with_rlm_acctlog != xno; then
+if test x$with_rlm_eap_md5 != xno; then
 
+       ## We may need more complex checking here.  Assume for now that
+       ## everyone has it.
        ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -1669,8 +1300,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1683,34 +1314,32 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
 fi
 if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1723,51 +1352,36 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
+  CC=$ac_ct_CC
 else
   CC="$ac_cv_prog_CC"
 fi
 
 if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1780,34 +1394,74 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
   fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
 fi
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1821,7 +1475,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
@@ -1832,7 +1486,6 @@ do
   fi
 done
 done
-IFS=$as_save_IFS
 
 if test $ac_prog_rejected = yes; then
   # We found a bogon in the path, so make sure we never use it.
@@ -1850,23 +1503,22 @@ fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
 fi
 if test -z "$CC"; then
   if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
+  for ac_prog in cl
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1879,38 +1531,36 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
     test -n "$CC" && break
   done
 fi
 if test -z "$CC"; then
   ac_ct_CC=$CC
-  for ac_prog in cl.exe
+  for ac_prog in cl
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1923,45 +1573,29 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
   test -n "$ac_ct_CC" && break
 done
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
+  CC=$ac_ct_CC
 fi
 
 fi
@@ -1974,35 +1608,21 @@ See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 
 # Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
@@ -2027,70 +1647,46 @@ ac_clean_files="$ac_clean_files a.out a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-#
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort.  b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
-#
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions.  Remove them first so a
-# subsequent execution test works.
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { (ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link_default") 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
 do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
        ;;
     [ab].out )
        # We found the default executable, but exeext='' is most
        # certainly right.
        break;;
     *.* )
-        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-       then :; else
-          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       fi
-       # We set ac_cv_exeext here because the later test for it is not
-       # safe: cross compilers may not add the suffix if given an `-o'
-       # argument, so we may need to know it at that point already.
-       # Even if this section looks crufty: it has the advantage of
-       # actually working.
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
        break;;
     * )
        break;;
   esac
 done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
@@ -2103,23 +1699,19 @@ See \`config.log' for more details." >&2;}
 fi
 
 ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
 
-# Check that the compiler produces executables we can run.  If not, either
+# Check the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0
 # If not cross compiling, check that we can run a simple program.
 if test "$cross_compiling" != yes; then
   if { ac_try='./$ac_file'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2138,27 +1730,22 @@ See \`config.log' for more details." >&2;}
     fi
   fi
 fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
 
 rm -f a.out a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
+# Check the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
@@ -2169,8 +1756,9 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 for ac_file in conftest.exe conftest conftest.*; do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
          break;;
     * ) break;;
   esac
@@ -2184,14 +1772,14 @@ See \`config.log' for more details." >&2;}
 fi
 
 rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
 if test "${ac_cv_objext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2211,20 +1799,14 @@ main ()
 }
 _ACEOF
 rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
     *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
        break;;
   esac
@@ -2242,12 +1824,12 @@ fi
 
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
 if test "${ac_cv_c_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2270,36 +1852,24 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2308,139 +1878,24 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_compiler_gnu=no
+ac_compiler_gnu=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
 GCC=`test $ac_compiler_gnu = yes && echo yes`
 ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
 if test "${ac_cv_prog_cc_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       CFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_c_werror_flag=$ac_save_c_werror_flag
-        CFLAGS="-g"
-        cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2456,36 +1911,24 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2494,20 +1937,12 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_prog_cc_g=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
@@ -2523,12 +1958,12 @@ else
     CFLAGS=
   fi
 fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_prog_cc_c89=no
+  ac_cv_prog_cc_stdc=no
 ac_save_CC=$CC
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -2562,17 +1997,12 @@ static char *f (char * (*g) (char **, int), char **p, ...)
 /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
    function prototypes and stuff, but not '\xHH' hex character constants.
    These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
+   as 'x'.  The following induces an error, until -std1 is added to get
    proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
    array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
+   that's true only with -std1.  */
 int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
 int test (int i, double x);
 struct s1 {int (*f) (int a);};
 struct s2 {int (*f) (double a);};
@@ -2587,137 +2017,264 @@ return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
   return 0;
 }
 _ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
   rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_prog_cc_c89=$ac_arg
+  ac_cv_prog_cc_stdc=$ac_arg
+break
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
+rm -f conftest.err conftest.$ac_objext
 done
-rm -f conftest.$ac_ext
+rm -f conftest.$ac_ext conftest.$ac_objext
 CC=$ac_save_CC
 
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
   *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
 esac
 
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
 #endif
-                    Syntax error
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
     ac_cpp_err=
   fi
 else
@@ -2732,10 +2289,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
   # Broken: fails on valid input.
 continue
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
+  # OK, works on sane cases.  Now check whether non-existent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -2745,13 +2301,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -2778,7 +2329,6 @@ sed 's/^/| /' conftest.$ac_ext >&5
 ac_preproc_ok=:
 break
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -2796,8 +2346,8 @@ fi
 else
   ac_cv_prog_CPP=$CPP
 fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
@@ -2820,13 +2370,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 #endif
                     Syntax error
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -2851,10 +2396,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
   # Broken: fails on valid input.
 continue
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
+  # OK, works on sane cases.  Now check whether non-existent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -2864,13 +2408,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -2897,7 +2436,6 @@ sed 's/^/| /' conftest.$ac_ext >&5
 ac_preproc_ok=:
 break
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -2920,172 +2458,23 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in grep ggrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
-    # Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_GREP_found && break 3
-  done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in egrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
-    # Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
     fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_EGREP_found && break 3
-  done
-done
-
-done
-IFS=$as_save_IFS
-
-
-fi
-
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-else
-  ac_cv_path_EGREP=$EGREP
-fi
-
-
-   fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
 
 
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
 if test "${ac_cv_header_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3109,36 +2498,24 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3147,10 +2524,9 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_header_stdc=no
+ac_cv_header_stdc=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
@@ -3206,7 +2582,6 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ctype.h>
-#include <stdlib.h>
 #if ((' ' & 0x0FF) == 0x020)
 # define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
 # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
@@ -3226,27 +2601,18 @@ main ()
   for (i = 0; i < 256; i++)
     if (XOR (islower (i), ISLOWER (i))
        || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
+      exit(2);
+  exit (0);
 }
 _ACEOF
 rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3259,14 +2625,12 @@ sed 's/^/| /' conftest.$ac_ext >&5
 ( exit $ac_status )
 ac_cv_header_stdc=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
-
-
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
 if test $ac_cv_header_stdc = yes; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -3289,9 +2653,9 @@ for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
                  inttypes.h stdint.h unistd.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -3305,36 +2669,24 @@ $ac_includes_default
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3343,14 +2695,12 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_Header=no"
+eval "$as_ac_Header=no"
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
@@ -3361,18 +2711,22 @@ fi
 done
 
 
-if test "${ac_cv_header_stdio_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for stdio.h" >&5
-echo $ECHO_N "checking for stdio.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdio_h+set}" = set; then
+
+for ac_header in malloc.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdio_h" >&5
-echo "${ECHO_T}$ac_cv_header_stdio_h" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking stdio.h usability" >&5
-echo $ECHO_N "checking stdio.h usability... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -3380,39 +2734,27 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <stdio.h>
+#include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3421,31 +2763,25 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
+ac_header_compiler=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking stdio.h presence" >&5
-echo $ECHO_N "checking stdio.h presence... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdio.h>
+#include <$ac_header>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -3469,72 +2805,79 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
   ac_header_preproc=no
 fi
-
 rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
 
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: stdio.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: stdio.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: stdio.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: stdio.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: stdio.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: stdio.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: stdio.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: stdio.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: stdio.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: stdio.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: stdio.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: stdio.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: stdio.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: stdio.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: stdio.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: stdio.h: in the future, the compiler will take precedence" >&2;}
-
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for stdio.h" >&5
-echo $ECHO_N "checking for stdio.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdio_h+set}" = set; then
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_stdio_h=$ac_header_preproc
+  eval "$as_ac_Header=\$ac_header_preproc"
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdio_h" >&5
-echo "${ECHO_T}$ac_cv_header_stdio_h" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 
 fi
-if test $ac_cv_header_stdio_h = yes; then
-   slog_cflags="$acctlog_cflags -I/usr/include"
-else
-   fail=$fail" stdio.h"
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
 
 fi
 
+done
 
 
-       targetname=rlm_acctlog
+       targetname=rlm_eap_md5     # keep this!  Don't change!
 else
-       targetname=
-       echo \*\*\* module rlm_acctlog is disabled.
+       targetname=            # keep this!  Don't change!
+       echo \*\*\* module rlm_eap_md5 is disabled.  # keep this!  Don't change!
 fi
 
 if test x"$fail" != x""; then
        if test x"${enable_strict_dependencies}" = x"yes"; then
-               { { echo "$as_me:$LINENO: error: set --without-rlm_acctlog to disable it explicitly." >&5
-echo "$as_me: error: set --without-rlm_acctlog to disable it explicitly." >&2;}
+               { { echo "$as_me:$LINENO: error: set --without-rlm_eap_md5 to disable it explicitly." >&5
+echo "$as_me: error: set --without-rlm_eap_md5 to disable it explicitly." >&2;}
    { (exit 1); exit 1; }; }
        else
-               { echo "$as_me:$LINENO: WARNING: silently not building rlm_acctlog." >&5
-echo "$as_me: WARNING: silently not building rlm_acctlog." >&2;}
-               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_acctlog requires: $fail." >&5
-echo "$as_me: WARNING: FAILURE: rlm_acctlog requires: $fail." >&2;};
+               { echo "$as_me:$LINENO: WARNING: silently not building rlm_eap_md5." >&5
+echo "$as_me: WARNING: silently not building rlm_eap_md5." >&2;}
+               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_eap_md5 requires: $fail." >&5
+echo "$as_me: WARNING: FAILURE: rlm_eap_md5 requires: $fail." >&2;};
                targetname=""
        fi
 fi
@@ -3543,10 +2886,8 @@ fi
 
 
 
-
-
-ac_config_files="$ac_config_files Makefile"
-
+  # keep this!  Don't change!
+          ac_config_files="$ac_config_files Makefile"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -3565,58 +2906,39 @@ _ACEOF
 
 # The following way of writing the cache mishandles newlines in values,
 # but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
+# So, don't put newlines in cache variables' values.
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
-(
-  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
-
+{
   (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
       # `set' does not quote correctly, so add quotes (double-quote
       # substitution turns \\\\ into \\, and sed turns \\ into \).
       sed -n \
        "s/'/'\\\\''/g;
          s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;; #(
+      ;;
     *)
       # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
-    esac |
-    sort
-) |
+    esac;
+} |
   sed '
-     /^ac_cv_env_/b end
      t clear
-     :clear
+     : clear
      s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
      t end
-     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
-  if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
-      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
     cat confcache >$cache_file
   else
-    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    echo "not updating unwritable cache $cache_file"
   fi
 fi
 rm -f confcache
@@ -3625,48 +2947,63 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
 # Transform confdefs.h into DEFS.
 # Protect against shell expansion while executing Makefile rules.
 # Protect against Makefile macro expansion.
 #
 # If the first sed substitution is executed (which looks for macros that
-# take arguments), then branch to the quote section.  Otherwise,
+# take arguments), then we branch to the quote section.  Otherwise,
 # look for a macro that doesn't take arguments.
-ac_script='
+cat >confdef2opt.sed <<\_ACEOF
 t clear
-:clear
-s/^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\)/-D\1=\2/g
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
 t quote
-s/^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)/-D\1=\2/g
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
 t quote
-b any
-:quote
-s/[     `~#$^&*(){}\\|;'\''"<>?]/\\&/g
-s/\[/\\&/g
-s/\]/\\&/g
-s/\$/$$/g
-H
-:any
-${
-       g
-       s/^\n//
-       s/\n/ /g
-       p
-}
-'
-DEFS=`sed -n "$ac_script" confdefs.h`
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
 
 
 ac_libobjs=
 ac_ltlibobjs=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
-  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`echo "$ac_i" | sed "$ac_script"`
-  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
-  #    will be set to the directory where LIBOBJS objects are built.
-  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -3704,35 +3041,11 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -3741,43 +3054,8 @@ else
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""       $as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
 # Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
+$as_unset ENV MAIL MAILPATH
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -3791,19 +3069,18 @@ do
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
 
 
 # Name of the executable.
-as_me=`$as_basename -- "$0" ||
+as_me=`$as_basename "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
 
-# CDPATH.
-$as_unset CDPATH
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
 
 
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
 
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
 
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
     sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
       N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
       t loop
-      s/-\n.*//
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
     ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
   # Exit status is that of the last command.
   exit
 }
 
 
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
     as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
+rm -f conf$$ conf$$.exe conf$$.file
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -3933,19 +3249,7 @@ else
   as_mkdir_p=false
 fi
 
-# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  as_executable_p="test -x"
-else
-  as_executable_p=:
-fi
-rm -f conf$$.file
+as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -3954,14 +3258,31 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
 exec 6>&1
 
-# Save the log message, to keep $[0] and so on meaningful, and to
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -3969,18 +3290,30 @@ generated by GNU Autoconf 2.60.  Invocation command line was
   CONFIG_COMMANDS = $CONFIG_COMMANDS
   $ $0 $@
 
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
 _ACEOF
 
-cat >>$CONFIG_STATUS <<_ACEOF
 # Files that config.status was made for.
-config_files="$ac_config_files"
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
 
-_ACEOF
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
 
 cat >>$CONFIG_STATUS <<\_ACEOF
+
 ac_cs_usage="\
 \`$as_me' instantiates files from templates according to the
 current configuration.
@@ -3999,20 +3332,18 @@ Configuration files:
 $config_files
 
 Report bugs to <bug-autoconf@gnu.org>."
-
 _ACEOF
+
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.60,
-  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
-Copyright (C) 2006 Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
+srcdir=$srcdir
 _ACEOF
 
 cat >>$CONFIG_STATUS <<\_ACEOF
@@ -4023,42 +3354,60 @@ while test $# != 0
 do
   case $1 in
   --*=*)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
     ac_shift=:
     ;;
-  *)
+  -*)
     ac_option=$1
     ac_optarg=$2
     ac_shift=shift
     ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
   esac
 
   case $ac_option in
   # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
-  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    echo "$ac_cs_version"; exit ;;
-  --debug | --debu | --deb | --de | --d | -d )
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     CONFIG_FILES="$CONFIG_FILES $ac_optarg"
     ac_need_defaults=false;;
-  --he | --h |  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit ;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
    { (exit 1); exit 1; }; } ;;
 
-  *) ac_config_targets="$ac_config_targets $1"
-     ac_need_defaults=false ;;
+  *) ac_config_targets="$ac_config_targets $1" ;;
 
   esac
   shift
@@ -4074,42 +3423,28 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 if \$ac_cs_recheck; then
-  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  CONFIG_SHELL=$SHELL
-  export CONFIG_SHELL
-  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-  echo "$ac_log"
-} >&5
 
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
 
-# Handling of arguments.
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
 for ac_config_target in $ac_config_targets
 do
-  case $ac_config_target in
-    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
    { (exit 1); exit 1; }; };;
   esac
 done
 
-
 # If the user did not use the arguments to specify the items to instantiate,
 # then the envvar interface is used.  Set only those that are not.
 # We use the long form for the default assignment because of an extremely
@@ -4119,362 +3454,294 @@ if $ac_need_defaults; then
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
+# simply because there is no reason to put it here, and in addition,
 # creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
+# Create a temporary directory, and hook for its removal unless debugging.
 $debug ||
 {
-  tmp=
-  trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
   trap '{ (exit 1); exit 1; }' 1 2 13 15
 }
+
 # Create a (secure) tmp directory for tmp files.
 
 {
-  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
   test -n "$tmp" && test -d "$tmp"
 }  ||
 {
-  tmp=./conf$$-$RANDOM
-  (umask 077 && mkdir "$tmp")
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
 } ||
 {
    echo "$me: cannot create a temporary directory in ." >&2
    { (exit 1); exit 1; }
 }
 
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
 #
-# Set up the sed scripts for CONFIG_FILES section.
+# CONFIG_FILES section.
 #
 
 # No need to generate the scripts if there are no CONFIG_FILES.
 # This happens for instance when ./config.status config.h
-if test -n "$CONFIG_FILES"; then
-
-_ACEOF
-
-
-
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
-  cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CPP!$CPP$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-acctlog_cflags!$acctlog_cflags$ac_delim
-acctlog_ldflags!$acctlog_ldflags$ac_delim
-targetname!$targetname$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
-
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 52; then
-    break
-  elif $ac_last_try; then
-    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
-   { (exit 1); exit 1; }; }
-  else
-    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@eap_md5_cflags@,$eap_md5_cflags,;t t
+s,@eap_md5_ldflags@,$eap_md5_ldflags,;t t
+s,@targetname@,$targetname,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
   fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
-  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
-  ac_eof=`expr $ac_eof + 1`
-fi
+fi # test -n "$CONFIG_FILES"
 
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
 _ACEOF
-
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[         ]*VPATH[        ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[    ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[      ]*$//
-}'
-fi
-
 cat >>$CONFIG_STATUS <<\_ACEOF
-fi # test -n "$CONFIG_FILES"
-
-
-for ac_tag in  :F $CONFIG_FILES
-do
-  case $ac_tag in
-  :[FHLC]) ac_mode=$ac_tag; continue;;
-  esac
-  case $ac_mode$ac_tag in
-  :[FHL]*:*);;
-  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
-   { (exit 1); exit 1; }; };;
-  :[FH]-) ac_tag=-:-;;
-  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
-  esac
-  ac_save_IFS=$IFS
-  IFS=:
-  set x $ac_tag
-  IFS=$ac_save_IFS
-  shift
-  ac_file=$1
-  shift
-
-  case $ac_mode in
-  :L) ac_source=$1;;
-  :[FH])
-    ac_file_inputs=
-    for ac_f
-    do
-      case $ac_f in
-      -) ac_f="$tmp/stdin";;
-      *) # Look for the file first in the build tree, then in the source tree
-        # (if the path is not absolute).  The absolute path cannot be DOS-style,
-        # because $ac_f cannot contain `:'.
-        test -f "$ac_f" ||
-          case $ac_f in
-          [\\/$]*) false;;
-          *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
-          esac ||
-          { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
-   { (exit 1); exit 1; }; };;
-      esac
-      ac_file_inputs="$ac_file_inputs $ac_f"
-    done
-
-    # Let's still pretend it is `configure' which instantiates (i.e., don't
-    # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
-    configure_input="Generated from "`IFS=:
-         echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
-    if test x"$ac_file" != x-; then
-      configure_input="$ac_file.  $configure_input"
-      { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    fi
-
-    case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin";;
-    esac
-    ;;
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
   esac
 
-  ac_dir=`$as_dirname -- "$ac_file" ||
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$ac_file" : 'X\(//\)[^/]' \| \
         X"$ac_file" : 'X\(//\)$' \| \
-        X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-  { as_dir="$ac_dir"
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
     as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
-        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-      test -d "$as_dir" && break
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
     done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
    { (exit 1); exit 1; }; }; }
+
   ac_builddir=.
 
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
+if test "$ac_dir" != .; then
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
 
 case $srcdir in
-  .)  # We are building in place.
+  .)  # No --srcdir option.  We are building in place.
     ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
 esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
 
-  case $ac_mode in
-  :F)
-  #
-  # CONFIG_FILE
-  #
-
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
 
-case `sed -n '/datarootdir/ {
-  p
-  q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-  ac_datarootdir_hack='
-  s&@datadir@&$datadir&g
-  s&@docdir@&$docdir&g
-  s&@infodir@&$infodir&g
-  s&@localedir@&$localedir&g
-  s&@mandir@&$mandir&g
-    s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
 _ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
 $extrasub
@@ -4482,39 +3749,28 @@ _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
-  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
-
-  rm -f "$tmp/stdin"
-  case $ac_file in
-  -) cat "$tmp/out"; rm -f "$tmp/out";;
-  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
-  esac
- ;;
-
-
-
-  esac
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
 
-done # for ac_tag
+done
+_ACEOF
 
+cat >>$CONFIG_STATUS <<\_ACEOF
 
 { (exit 0); exit 0; }
 _ACEOF
@@ -4542,4 +3798,4 @@ if test "$no_create" != yes; then
   # would make configure fail if this is the last instruction.
   $ac_cs_success || { (exit 1); exit 1; }
 fi
-
+  # keep this!  Don't change!
diff --git a/src/modules/rlm_eap/types/rlm_eap_md5/configure.in b/src/modules/rlm_eap/types/rlm_eap_md5/configure.in
new file mode 100644 (file)
index 0000000..a5c9e85
--- /dev/null
@@ -0,0 +1,34 @@
+AC_INIT(rlm_eap_md5.c)
+AC_REVISION($Revision$)
+AC_DEFUN(modname,[rlm_eap_md5])
+
+if test x$with_[]modname != xno; then
+
+       ## We may need more complex checking here.  Assume for now that 
+       ## everyone has it.
+       AC_CHECK_HEADERS(malloc.h)
+
+       targetname=modname     # keep this!  Don't change!
+else
+       targetname=            # keep this!  Don't change!
+       echo \*\*\* module modname is disabled.  # keep this!  Don't change!
+fi
+
+dnl  Don't change this section.
+if test x"$fail" != x""; then
+       if test x"${enable_strict_dependencies}" = x"yes"; then
+               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
+       else
+               AC_MSG_WARN([silently not building ]modname[.])
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
+               targetname=""
+       fi
+fi
+
+AC_SUBST(eap_md5_cflags)
+AC_SUBST(eap_md5_ldflags)
+
+dnl AC_CONFIG_HEADER(config.h)
+
+AC_SUBST(targetname)  # keep this!  Don't change!
+AC_OUTPUT(Makefile)  # keep this!  Don't change!
index 09cc167..2411d4b 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2001,2006  The FreeRADIUS server project
+ * Copyright 2000,2001  The FreeRADIUS server project
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  */
 
@@ -35,9 +35,6 @@
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <stdio.h>
 #include <stdlib.h>
 #include "eap.h"
@@ -187,7 +184,7 @@ int eapmd5_verify(MD5_PACKET *packet, VALUE_PAIR* password,
         */
        *ptr++ = packet->id;
        len++;
-       memcpy(ptr, password->vp_strvalue, password->length);
+       memcpy(ptr, password->strvalue, password->length);
        ptr += password->length;
        len += password->length;
 
@@ -225,6 +222,7 @@ int eapmd5_compose(EAP_DS *eap_ds, MD5_PACKET *reply)
                eap_ds->request->type.type = PW_EAP_MD5;
 
                rad_assert(reply->length > 0);
+               rad_assert(reply->value_size < 256);
 
                eap_ds->request->type.data = malloc(reply->length);
                if (eap_ds->request->type.data == NULL) {
index a7936eb..698aab4 100644 (file)
@@ -1,9 +1,6 @@
 #ifndef _EAP_MD5_H
 #define _EAP_MD5_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_md5_h, "$Id$")
-
 #include "eap.h"
 
 #define PW_MD5_CHALLENGE       1
index 12b04bc..7abdb30 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2001,2006  The FreeRADIUS server project
+ * Copyright 2000,2001  The FreeRADIUS server project
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "eap_md5.h"
 
-#include <freeradius-devel/rad_assert.h>
+#include <rad_assert.h>
 
 /*
  *     Initiate the EAP-MD5 session by sending a challenge to the peer.
@@ -107,21 +104,21 @@ static int md5_initiate(void *type_data, EAP_HANDLER *handler)
 /*
  *     Authenticate a previously sent challenge.
  */
-static int md5_authenticate(UNUSED void *arg, EAP_HANDLER *handler)
+static int md5_authenticate(void *arg, EAP_HANDLER *handler)
 {
        MD5_PACKET      *packet;
        MD5_PACKET      *reply;
        VALUE_PAIR      *password;
 
        /*
-        *      Get the Cleartext-Password for this user.
+        *      Get the User-Password for this user.
         */
        rad_assert(handler->request != NULL);
        rad_assert(handler->stage == AUTHENTICATE);
 
-       password = pairfind(handler->request->config_items, PW_CLEARTEXT_PASSWORD);
+       password = pairfind(handler->request->config_items, PW_PASSWORD);
        if (password == NULL) {
-               radlog(L_INFO, "rlm_eap_md5: Cleartext-Password is required for EAP-MD5 authentication");
+               radlog(L_INFO, "rlm_eap_md5: User-Password is required for EAP-MD5 authentication");
                return 0;
        }
 
@@ -136,6 +133,7 @@ static int md5_authenticate(UNUSED void *arg, EAP_HANDLER *handler)
         */
        reply = eapmd5_alloc();
        if (!reply) {
+               eapmd5_free(&packet);
                return 0;
        }
        reply->id = handler->eap_ds->request->id;
@@ -148,6 +146,7 @@ static int md5_authenticate(UNUSED void *arg, EAP_HANDLER *handler)
        if (eapmd5_verify(packet, password, handler->opaque)) {
                reply->code = PW_MD5_SUCCESS;
        } else {
+               DEBUG2("  rlm_eap_md5: Passwords do not match");
                reply->code = PW_MD5_FAILURE;
        }
 
@@ -1,13 +1,11 @@
 #
-# Makefile
-#
-# Version:     $Id$
+# $Id$
 #
 
-TARGET      = rlm_eap_mschapv2
+TARGET      = @targetname@
 SRCS        = rlm_eap_mschapv2.c
 HEADERS     = eap_mschapv2.h
-RLM_CFLAGS  = $(INCLTDL) -I../.. -I../../libeap
+RLM_CFLAGS  = -I../.. -I../../libeap $(INCLTDL)
 RLM_INSTALL =
 
 RLM_DIR=../../
diff --git a/src/modules/rlm_eap/types/rlm_eap_mschapv2/configure b/src/modules/rlm_eap/types/rlm_eap_mschapv2/configure
new file mode 100755 (executable)
index 0000000..64d267b
--- /dev/null
@@ -0,0 +1,3801 @@
+#! /bin/sh
+# From configure.in Revision: 1.1 .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="rlm_eap_mschapv2.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP eap_mschapv2_cflags eap_mschapv2_ldflags targetname LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test x$with_rlm_eap_mschapv2 != xno; then
+
+       ## We may need more complex checking here.  Assume for now that
+       ## everyone has it.
+       ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in malloc.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+       targetname=rlm_eap_mschapv2     # keep this!  Don't change!
+else
+       targetname=            # keep this!  Don't change!
+       echo \*\*\* module rlm_eap_mschapv2 is disabled.  # keep this!  Don't change!
+fi
+
+if test x"$fail" != x""; then
+       if test x"${enable_strict_dependencies}" = x"yes"; then
+               { { echo "$as_me:$LINENO: error: set --without-rlm_eap_mschapv2 to disable it explicitly." >&5
+echo "$as_me: error: set --without-rlm_eap_mschapv2 to disable it explicitly." >&2;}
+   { (exit 1); exit 1; }; }
+       else
+               { echo "$as_me:$LINENO: WARNING: silently not building rlm_eap_mschapv2." >&5
+echo "$as_me: WARNING: silently not building rlm_eap_mschapv2." >&2;}
+               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_eap_mschapv2 requires: $fail." >&5
+echo "$as_me: WARNING: FAILURE: rlm_eap_mschapv2 requires: $fail." >&2;};
+               targetname=""
+       fi
+fi
+
+
+
+
+
+  # keep this!  Don't change!
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@eap_mschapv2_cflags@,$eap_mschapv2_cflags,;t t
+s,@eap_mschapv2_ldflags@,$eap_mschapv2_ldflags,;t t
+s,@targetname@,$targetname,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+  # keep this!  Don't change!
diff --git a/src/modules/rlm_eap/types/rlm_eap_mschapv2/configure.in b/src/modules/rlm_eap/types/rlm_eap_mschapv2/configure.in
new file mode 100644 (file)
index 0000000..5a84548
--- /dev/null
@@ -0,0 +1,34 @@
+AC_INIT(rlm_eap_mschapv2.c)
+AC_REVISION($Revision$)
+AC_DEFUN(modname,[rlm_eap_mschapv2])
+
+if test x$with_[]modname != xno; then
+
+       ## We may need more complex checking here.  Assume for now that 
+       ## everyone has it.
+       AC_CHECK_HEADERS(malloc.h)
+
+       targetname=modname     # keep this!  Don't change!
+else
+       targetname=            # keep this!  Don't change!
+       echo \*\*\* module modname is disabled.  # keep this!  Don't change!
+fi
+
+dnl  Don't change this section.
+if test x"$fail" != x""; then
+       if test x"${enable_strict_dependencies}" = x"yes"; then
+               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
+       else
+               AC_MSG_WARN([silently not building ]modname[.])
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
+               targetname=""
+       fi
+fi
+
+AC_SUBST(eap_mschapv2_cflags)
+AC_SUBST(eap_mschapv2_ldflags)
+
+dnl AC_CONFIG_HEADER(config.h)
+
+AC_SUBST(targetname)  # keep this!  Don't change!
+AC_OUTPUT(Makefile)  # keep this!  Don't change!
index a96fb7d..abf0606 100644 (file)
@@ -1,28 +1,8 @@
 #ifndef _EAP_MSCHAPV2_H
 #define _EAP_MSCHAPV2_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_mschapv2_h, "$Id$")
-
 #include "eap.h"
 
-/*
- *     draft-kamath-pppext-eap-mschapv2-00.txt says:
- *
- *     Supplicant              FreeRADIUS
- *                     <--     challenge
- *     response        -->
- *                     <--     success
- *     success         -->
- *
- *     But what we often see is:
- *
- *     Supplicant              FreeRADIUS
- *                     <--     challenge
- *     response        -->
- *                     <--     success
- *     ack             -->
- */
 #define PW_EAP_MSCHAPV2_ACK            0
 #define PW_EAP_MSCHAPV2_CHALLENGE      1
 #define PW_EAP_MSCHAPV2_RESPONSE       2
index 460464f..5d98b15 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "eap_mschapv2.h"
 
-#include <freeradius-devel/rad_assert.h>
+#include <rad_assert.h>
 
 typedef struct rlm_eap_mschapv2_t {
         int with_ntdomain_hack;
@@ -140,7 +137,7 @@ static int eapmschapv2_compose(EAP_HANDLER *handler, VALUE_PAIR *reply)
                /*
                 *      Copy the Challenge, success, or error over.
                 */
-               memcpy(ptr, reply->vp_strvalue, reply->length);
+               memcpy(ptr, reply->strvalue, reply->length);
                memcpy((ptr + reply->length), handler->identity, strlen(handler->identity));
                break;
 
@@ -173,7 +170,7 @@ static int eapmschapv2_compose(EAP_HANDLER *handler, VALUE_PAIR *reply)
                eap_ds->request->type.data[1] = eap_ds->response->id;
                length = htons(length);
                memcpy((eap_ds->request->type.data + 2), &length, sizeof(uint16_t));
-               memcpy((eap_ds->request->type.data + 4), reply->vp_strvalue + 1, 42);
+               memcpy((eap_ds->request->type.data + 4), reply->strvalue + 1, 42);
                break;
 
        case PW_MSCHAP_ERROR:
@@ -230,7 +227,7 @@ static int mschapv2_initiate(void *type_data, EAP_HANDLER *handler)
         */
        challenge->length = MSCHAPV2_CHALLENGE_LEN;
        for (i = 0; i < MSCHAPV2_CHALLENGE_LEN; i++) {
-               challenge->vp_strvalue[i] = lrad_rand();
+               challenge->strvalue[i] = lrad_rand();
        }
        radlog(L_INFO, "rlm_eap_mschapv2: Issuing Challenge");
 
@@ -244,7 +241,7 @@ static int mschapv2_initiate(void *type_data, EAP_HANDLER *handler)
         *      We're at the stage where we're challenging the user.
         */
        data->code = PW_EAP_MSCHAPV2_CHALLENGE;
-       memcpy(data->challenge, challenge->vp_strvalue, MSCHAPV2_CHALLENGE_LEN);
+       memcpy(data->challenge, challenge->strvalue, MSCHAPV2_CHALLENGE_LEN);
 
        handler->opaque = data;
        handler->free_opaque = free;
@@ -362,6 +359,9 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
        EAP_DS *eap_ds = handler->eap_ds;
        VALUE_PAIR *challenge, *response;
 
+       /*
+        *      Get the User-Password for this user.
+        */
        rad_assert(handler->request != NULL);
        rad_assert(handler->stage == AUTHENTICATE);
 
@@ -439,10 +439,10 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
                 *      The MS-Length field is 5 + value_size + length
                 *      of name, which is put after the response.
                 */
-               if (((eap_ds->response->type.data[2] << 8) |
+               if (((eap_ds->response->type.data[2] << 8) | 
                     eap_ds->response->type.data[3]) < (5 + 49)) {
                        radlog(L_ERR, "rlm_eap_mschapv2: Response contains contradictory length %d %d",
-                             (eap_ds->response->type.data[2] << 8) |
+                             (eap_ds->response->type.data[2] << 8) | 
                               eap_ds->response->type.data[3], 5 + 49);
                        return 0;
                }
@@ -487,7 +487,7 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
                return 0;
        }
        challenge->length = MSCHAPV2_CHALLENGE_LEN;
-       memcpy(challenge->vp_strvalue, data->challenge, MSCHAPV2_CHALLENGE_LEN);
+       memcpy(challenge->strvalue, data->challenge, MSCHAPV2_CHALLENGE_LEN);
 
        response = pairmake("MS-CHAP2-Response", "0x00", T_OP_EQ);
        if (!response) {
@@ -497,10 +497,10 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
        }
 
        response->length = MSCHAPV2_RESPONSE_LEN;
-       memcpy(response->vp_strvalue + 2, &eap_ds->response->type.data[5],
+       memcpy(response->strvalue + 2, &eap_ds->response->type.data[5],
               MSCHAPV2_RESPONSE_LEN - 2);
-       response->vp_strvalue[0] = eap_ds->response->type.data[1];
-       response->vp_strvalue[1] = eap_ds->response->type.data[5 + MSCHAPV2_RESPONSE_LEN];
+       response->strvalue[0] = eap_ds->response->type.data[1];
+       response->strvalue[1] = eap_ds->response->type.data[5 + MSCHAPV2_RESPONSE_LEN];
 
        /*
         *      Add the pairs to the request, and call the 'mschap'
@@ -523,16 +523,16 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
                char *username = NULL;
                eap_tunnel_data_t *tunnel;
                rlm_eap_mschapv2_t *inst = (rlm_eap_mschapv2_t *) arg;
-
+               
                /*
                 *      Set up the callbacks for the tunnel
                 */
                tunnel = rad_malloc(sizeof(*tunnel));
                memset(tunnel, 0, sizeof(*tunnel));
-
+               
                tunnel->tls_session = arg;
                tunnel->callback = mschap_postproxy;
-
+               
                /*
                 *      Associate the callback with the request.
                 */
@@ -563,17 +563,17 @@ static int mschapv2_authenticate(void *arg, EAP_HANDLER *handler)
                if (inst->with_ntdomain_hack &&
                    ((challenge = pairfind(handler->request->packet->vps,
                                           PW_USER_NAME)) != NULL) &&
-                   ((username = strchr(challenge->vp_strvalue, '\\')) != NULL)) {
+                   ((username = strchr(challenge->strvalue, '\\')) != NULL)) {
                        /*
                         *      Wipe out the NT domain.
                         *
                         *      FIXME: Put it into MS-CHAP-Domain?
                         */
                        username++; /* skip the \\ */
-                       memmove(challenge->vp_strvalue,
+                       memmove(challenge->strvalue,
                                username,
                                strlen(username) + 1); /* include \0 */
-                       challenge->length = strlen(challenge->vp_strvalue);
+                       challenge->length = strlen(challenge->strvalue);
                }
 
                /*
index 493d850..c4183ab 100644 (file)
@@ -1,16 +1,15 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
+*/
 
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
 
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
+/* Define if you have the <openssl/engine.h> header file.  */
+#undef HAVE_OPENSSL_ENGINE_H
 
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+/* Define if you have the <openssl/err.h> header file.  */
+#undef HAVE_OPENSSL_ERR_H
index 240f2e2..128afcb 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.5 .
+# From configure.in Revision: 1.2.4.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -875,7 +875,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -2069,6 +2069,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -2107,12 +2112,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 2f5a6a7..4b18748 100644 (file)
@@ -4,7 +4,6 @@
 # Version:     $Id$
 #
 
-AC_PREREQ([2.53])
 AC_INIT(rlm_eap_peap.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_eap_peap])
index ab4b720..264aa36 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003 Alan DeKok <aland@freeradius.org>
- * Copyright 2006 The FreeRADIUS server project
  */
 #ifndef _EAP_PEAP_H
 #define _EAP_PEAP_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_peap_h, "$Id$")
-
 #include "eap_tls.h"
 
 typedef struct peap_tunnel_t {
index 929dade..21edd21 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *   Copyright 2003 Alan DeKok <aland@freeradius.org>
- *   Copyright 2006 The FreeRADIUS server project
  */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include "eap_peap.h"
 
 /*
@@ -55,7 +50,7 @@ static int eappeap_failure(EAP_HANDLER *handler, tls_session_t *tls_session)
         *      FIXME: Check the return code.
         */
        tls_handshake_send(tls_session);
-
+       
        return 1;
 }
 
@@ -171,12 +166,12 @@ static VALUE_PAIR *eap2vp(EAP_DS *eap_ds,
        /*
         *      Hand-build an EAP packet from the crap in PEAP version 0.
         */
-       vp->vp_strvalue[0] = PW_EAP_RESPONSE;
-       vp->vp_strvalue[1] = eap_ds->response->id;
-       vp->vp_strvalue[2] = 0;
-       vp->vp_strvalue[3] = EAP_HEADER_LEN + data_len;
+       vp->strvalue[0] = PW_EAP_RESPONSE;
+       vp->strvalue[1] = eap_ds->response->id;
+       vp->strvalue[2] = 0;
+       vp->strvalue[3] = EAP_HEADER_LEN + data_len;
 
-       memcpy(vp->vp_strvalue + EAP_HEADER_LEN, data, data_len);
+       memcpy(vp->strvalue + EAP_HEADER_LEN, data, data_len);
        vp->length = EAP_HEADER_LEN + data_len;
 
        return vp;
@@ -206,7 +201,7 @@ static int vp2eap(tls_session_t *tls_session, VALUE_PAIR *vp)
                if (debug_flag > 0) for (i = 0; i < total; i++) {
                        if ((i & 0x0f) == 0) printf("  PEAP tunnel data out %04x: ", i);
 
-                       printf("%02x ", vp->vp_strvalue[i + 4]);
+                       printf("%02x ", vp->strvalue[i + 4]);
 
                        if ((i & 0x0f) == 0x0f) printf("\n");
                }
@@ -218,10 +213,10 @@ static int vp2eap(tls_session_t *tls_session, VALUE_PAIR *vp)
         *      Send the EAP data, WITHOUT the header.
         */
 #if 1
-       (tls_session->record_plus)(&tls_session->clean_in, vp->vp_strvalue + EAP_HEADER_LEN,
+       (tls_session->record_plus)(&tls_session->clean_in, vp->strvalue + EAP_HEADER_LEN,
                vp->length - EAP_HEADER_LEN);
 #else
-       (tls_session->record_plus)(&tls_session->clean_in, vp->vp_strvalue, vp->length);
+       (tls_session->record_plus)(&tls_session->clean_in, vp->strvalue, vp->length);
 #endif
        tls_handshake_send(tls_session);
 
@@ -269,7 +264,7 @@ static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
        if (debug_flag > 0) {
                printf("  PEAP: Processing from tunneled session code %p %d\n",
                       reply, reply->code);
-
+               
                for (vp = reply->vps; vp != NULL; vp = vp->next) {
                        putchar('\t');vp_print(stdout, vp);putchar('\n');
                }
@@ -346,7 +341,7 @@ static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
                         */
                        pairdelete(&reply->vps, PW_PROXY_STATE);
                        pairdelete(&reply->vps, PW_MESSAGE_AUTHENTICATOR);
-
+                       
                        t->accept_vps = reply->vps;
                        reply->vps = NULL;
                }
@@ -391,7 +386,7 @@ static int eappeap_postproxy(EAP_HANDLER *handler, void *data)
        fake = (REQUEST *) request_data_get(handler->request,
                                            handler->request->proxy,
                                            REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK);
-
+       
        /*
         *      Do the callback, if it exists, and if it was a success.
         */
@@ -434,7 +429,7 @@ static int eappeap_postproxy(EAP_HANDLER *handler, void *data)
                if (debug_flag > 0) {
                        printf("  PEAP: Final reply from tunneled session code %d\n",
                               fake->reply->code);
-
+                       
                        for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {
                                putchar('\t');vp_print(stdout, vp);putchar('\n');
                        }
@@ -459,12 +454,12 @@ static int eappeap_postproxy(EAP_HANDLER *handler, void *data)
                        eaptls_fail(handler->eap_ds, 0);
                        return 0;
                        break;
-
+                       
                 default:  /* Don't Do Anything */
                        DEBUG2(" PEAP: Got reply %d",
                               request->proxy_reply->code);
                        break;
-               }
+               }       
        }
        request_free(&fake);    /* robust if fake == NULL */
 
@@ -677,10 +672,10 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                        t->username = pairmake("User-Name", "", T_OP_EQ);
                        rad_assert(t->username != NULL);
 
-                       memcpy(t->username->vp_strvalue, data + 1, data_len - 1);
+                       memcpy(t->username->strvalue, data + 1, data_len - 1);
                        t->username->length = data_len - 1;
-                       t->username->vp_strvalue[t->username->length] = 0;
-                       DEBUG2("  PEAP: Got tunneled identity of %s", t->username->vp_strvalue);
+                       t->username->strvalue[t->username->length] = 0;
+                       DEBUG2("  PEAP: Got tunneled identity of %s", t->username->strvalue);
 
                        /*
                         *      If there's a default EAP type,
@@ -689,7 +684,7 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                        if (t->default_eap_type != 0) {
                                DEBUG2("  PEAP: Setting default EAP type for tunneled EAP session.");
                                vp = pairmake("EAP-Type", "0", T_OP_EQ);
-                               vp->vp_integer = t->default_eap_type;
+                               vp->lvalue = t->default_eap_type;
                                pairadd(&fake->config_items, vp);
                        }
                }
@@ -700,7 +695,7 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                pairadd(&fake->packet->vps, vp);
                fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
                DEBUG2("  PEAP: Setting User-Name to %s",
-                      fake->username->vp_strvalue);
+                      fake->username->strvalue);
        }
 
        /*
@@ -708,7 +703,7 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
         */
        if (t->state) {
                DEBUG2("  PEAP: Adding old state with %02x %02x",
-                      t->state->vp_strvalue[0], t->state->vp_strvalue[1]);
+                      t->state->strvalue[0], t->state->strvalue[1]);
                vp = paircopy(t->state);
                if (vp) pairadd(&fake->packet->vps, vp);
        }
@@ -873,7 +868,7 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                                 *      done.  Handle it like normal.
                                 */
                                if ((fake->options & RAD_REQUEST_OPTION_PROXY_EAP) == 0) {
-                                       DEBUG2("    PEAP: Cancelling proxy to realm %s until the tunneled EAP session has been established", vp->vp_strvalue);
+                                       DEBUG2("    PEAP: Cancelling proxy to realm %s until the tunneled EAP session has been established", vp->strvalue);
                                        goto do_process;
                                }
 
@@ -886,7 +881,7 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                                           PW_EAP_MESSAGE);
                        }
 
-                       DEBUG2("  PEAP: Tunneled authentication will be proxied to %s", vp->vp_strvalue);
+                       DEBUG2("  PEAP: Tunneled authentication will be proxied to %s", vp->strvalue);
 
                        /*
                         *      Tell the original request that it's going
@@ -943,7 +938,7 @@ int eappeap_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                                                         REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK,
                                                         fake, my_request_free);
                                rad_assert(rcode == 0);
-
+                               
                                /*
                                 *      Do NOT free the fake request!
                                 */
index 9eeb822..59d8b2c 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003 Alan DeKok <aland@freeradius.org>
- * Copyright 2006 The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 #include "eap_peap.h"
 
 typedef struct rlm_eap_peap_t {
@@ -77,6 +73,7 @@ static int eappeap_detach(void *arg)
 {
        rlm_eap_peap_t *inst = (rlm_eap_peap_t *) arg;
 
+       if (inst->default_eap_type_name) free(inst->default_eap_type_name);
 
        free(inst);
 
@@ -191,7 +188,7 @@ static int eappeap_authenticate(void *arg, EAP_HANDLER *handler)
 
                        (tls_session->record_plus)(&tls_session->clean_in,
                                                  &eap_packet, sizeof(eap_packet));
-
+                       
                        tls_handshake_send(tls_session);
                        (tls_session->record_init)(&tls_session->clean_in);
                }
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/AES.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/AES.cpp
deleted file mode 100644 (file)
index 5498624..0000000
+++ /dev/null
@@ -1,572 +0,0 @@
-/**\r
- * AES.cpp\r
- *\r
- * The Advanced Encryption Standard (AES, aka AES) block cipher,\r
- * designed by J. Daemen and V. Rijmen.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "AES.h"\r
-#include "AES.tab"\r
-\r
-#define FULL_UNROLL\r
-\r
-#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)\r
-\r
-#ifdef _MSC_VER\r
-#define GETWORD(p) SWAP(*((uint *)(p)))\r
-#define PUTWORD(ct, st) { *((uint *)(ct)) = SWAP((st)); }\r
-#else\r
-#define GETWORD(pt) (((uint)(pt)[0] << 24) ^ ((uint)(pt)[1] << 16) ^ ((uint)(pt)[2] <<  8) ^ ((uint)(pt)[3]))\r
-#define PUTWORD(ct, st) { (ct)[0] = (byte)((st) >> 24); (ct)[1] = (byte)((st) >> 16); (ct)[2] = (byte)((st) >>  8); (ct)[3] = (byte)(st); }\r
-#endif\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-AES::AES() {\r
-}\r
-\r
-AES::~AES() {\r
-       Nr = 0;\r
-       memset(e_sched, 0, sizeof(e_sched));\r
-       memset(d_sched, 0, sizeof(d_sched));\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Support methods\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-void AES::ExpandKey(const byte *cipherKey, uint keyBits) {\r
-    uint *rek = e_sched;\r
-       int i = 0;\r
-       uint temp;\r
-\r
-       rek[0] = GETWORD(cipherKey     );\r
-       rek[1] = GETWORD(cipherKey +  4);\r
-       rek[2] = GETWORD(cipherKey +  8);\r
-       rek[3] = GETWORD(cipherKey + 12);\r
-       if (keyBits == 128) {\r
-               for (;;) {\r
-                       temp  = rek[3];\r
-                       rek[4] = rek[0] ^\r
-                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
-                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^\r
-                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^\r
-                               (Te4[(temp >> 24)       ] & 0x000000ff) ^\r
-                               rcon[i];\r
-                       rek[5] = rek[1] ^ rek[4];\r
-                       rek[6] = rek[2] ^ rek[5];\r
-                       rek[7] = rek[3] ^ rek[6];\r
-                       if (++i == 10) {\r
-                               Nr = 10;\r
-                               return;\r
-                       }\r
-                       rek += 4;\r
-               }\r
-       }\r
-       rek[4] = GETWORD(cipherKey + 16);\r
-       rek[5] = GETWORD(cipherKey + 20);\r
-       if (keyBits == 192) {\r
-               for (;;) {\r
-                       temp = rek[ 5];\r
-                       rek[ 6] = rek[ 0] ^\r
-                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
-                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^\r
-                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^\r
-                               (Te4[(temp >> 24)       ] & 0x000000ff) ^\r
-                               rcon[i];\r
-                       rek[ 7] = rek[ 1] ^ rek[ 6];\r
-                       rek[ 8] = rek[ 2] ^ rek[ 7];\r
-                       rek[ 9] = rek[ 3] ^ rek[ 8];\r
-                       if (++i == 8) {\r
-                               Nr = 12;\r
-                               return;\r
-                       }\r
-                       rek[10] = rek[ 4] ^ rek[ 9];\r
-                       rek[11] = rek[ 5] ^ rek[10];\r
-                       rek += 6;\r
-               }\r
-       }\r
-       rek[6] = GETWORD(cipherKey + 24);\r
-       rek[7] = GETWORD(cipherKey + 28);\r
-       if (keyBits == 256) {\r
-        for (;;) {\r
-               temp = rek[ 7];\r
-               rek[ 8] = rek[ 0] ^\r
-                       (Te4[(temp >> 16) & 0xff] & 0xff000000) ^\r
-                       (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^\r
-                       (Te4[(temp      ) & 0xff] & 0x0000ff00) ^\r
-                       (Te4[(temp >> 24)       ] & 0x000000ff) ^\r
-                       rcon[i];\r
-               rek[ 9] = rek[ 1] ^ rek[ 8];\r
-               rek[10] = rek[ 2] ^ rek[ 9];\r
-               rek[11] = rek[ 3] ^ rek[10];\r
-                       if (++i == 7) {\r
-                               Nr = 14;\r
-                               return;\r
-                       }\r
-               temp = rek[11];\r
-               rek[12] = rek[ 4] ^\r
-                       (Te4[(temp >> 24)       ] & 0xff000000) ^\r
-                       (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^\r
-                       (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^\r
-                       (Te4[(temp      ) & 0xff] & 0x000000ff);\r
-               rek[13] = rek[ 5] ^ rek[12];\r
-               rek[14] = rek[ 6] ^ rek[13];\r
-               rek[15] = rek[ 7] ^ rek[14];\r
-\r
-                       rek += 8;\r
-        }\r
-       }\r
-       Nr = 0;\r
-}\r
-\r
-void AES::InvertKey() {\r
-    uint *rek = e_sched;\r
-    uint *rdk = d_sched;\r
-       uint r;\r
-\r
-    assert(Nr == 10 || Nr == 12 || Nr == 14);\r
-    rek += 4*Nr;\r
-       /* apply the inverse MixColumn transform to all round keys but the first and the last: */\r
-    memcpy(rdk, rek, 16);\r
-       rdk += 4;\r
-       rek -= 4;\r
-       for (r = 1; r < Nr; r++) {\r
-               rdk[0] =\r
-                       Td0[Te4[(rek[0] >> 24)       ] & 0xff] ^\r
-                       Td1[Te4[(rek[0] >> 16) & 0xff] & 0xff] ^\r
-                       Td2[Te4[(rek[0] >>  8) & 0xff] & 0xff] ^\r
-                       Td3[Te4[(rek[0]      ) & 0xff] & 0xff];\r
-               rdk[1] =\r
-                       Td0[Te4[(rek[1] >> 24)       ] & 0xff] ^\r
-                       Td1[Te4[(rek[1] >> 16) & 0xff] & 0xff] ^\r
-                       Td2[Te4[(rek[1] >>  8) & 0xff] & 0xff] ^\r
-                       Td3[Te4[(rek[1]      ) & 0xff] & 0xff];\r
-               rdk[2] =\r
-                       Td0[Te4[(rek[2] >> 24)       ] & 0xff] ^\r
-                       Td1[Te4[(rek[2] >> 16) & 0xff] & 0xff] ^\r
-                       Td2[Te4[(rek[2] >>  8) & 0xff] & 0xff] ^\r
-                       Td3[Te4[(rek[2]      ) & 0xff] & 0xff];\r
-               rdk[3] =\r
-                       Td0[Te4[(rek[3] >> 24)       ] & 0xff] ^\r
-                       Td1[Te4[(rek[3] >> 16) & 0xff] & 0xff] ^\r
-                       Td2[Te4[(rek[3] >>  8) & 0xff] & 0xff] ^\r
-                       Td3[Te4[(rek[3]      ) & 0xff] & 0xff];\r
-               rdk += 4;\r
-               rek -= 4;\r
-       }\r
-    memcpy(rdk, rek, 16);\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Public Interface\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-void AES::makeKey(const byte *cipherKey, uint keySize, uint dir) {\r
-    switch (keySize) {\r
-    case  16: case  24: case  32:\r
-        keySize <<= 3; // key size is now in bits\r
-        break;\r
-    case 128: case 192: case 256:\r
-        break;\r
-    default:\r
-        assert(keySize == 16 || keySize == 24 || keySize == 32 || keySize == 128 || keySize == 192 || keySize == 256);\r
-    }\r
-    assert(dir >= DIR_NONE && dir <= DIR_BOTH);\r
-    if (dir != DIR_NONE) {\r
-        ExpandKey(cipherKey, keySize);\r
-           if (dir & DIR_DECRYPT) {\r
-            InvertKey();\r
-           }\r
-    }\r
-}\r
-\r
-void AES::encrypt(const byte *pt, byte *ct) {\r
-    uint *rek = e_sched;\r
-       uint s0, s1, s2, s3, t0, t1, t2, t3;\r
-#ifndef FULL_UNROLL\r
-    int r;\r
-#endif /* ?FULL_UNROLL */\r
-\r
-    /*\r
-        * map byte array block to cipher state\r
-        * and add initial round key:\r
-        */\r
-       s0 = GETWORD(pt     ) ^ rek[0];\r
-       s1 = GETWORD(pt +  4) ^ rek[1];\r
-       s2 = GETWORD(pt +  8) ^ rek[2];\r
-       s3 = GETWORD(pt + 12) ^ rek[3];\r
-#ifdef FULL_UNROLL\r
-    /* round 1: */\r
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[ 4];\r
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[ 5];\r
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[ 6];\r
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[ 7];\r
-       /* round 2: */\r
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[ 8];\r
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[ 9];\r
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[10];\r
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[11];\r
-    /* round 3: */\r
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[12];\r
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[13];\r
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[14];\r
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[15];\r
-       /* round 4: */\r
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[16];\r
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[17];\r
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[18];\r
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[19];\r
-    /* round 5: */\r
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[20];\r
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[21];\r
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[22];\r
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[23];\r
-       /* round 6: */\r
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[24];\r
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[25];\r
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[26];\r
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[27];\r
-    /* round 7: */\r
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[28];\r
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[29];\r
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[30];\r
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[31];\r
-       /* round 8: */\r
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[32];\r
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[33];\r
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[34];\r
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[35];\r
-    /* round 9: */\r
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[36];\r
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[37];\r
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[38];\r
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[39];\r
-    if (Nr > 10) {\r
-        /* round 10: */\r
-        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[40];\r
-        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[41];\r
-        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[42];\r
-        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[43];\r
-        /* round 11: */\r
-        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[44];\r
-        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[45];\r
-        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[46];\r
-        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[47];\r
-        if (Nr > 12) {\r
-            /* round 12: */\r
-            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rek[48];\r
-            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rek[49];\r
-            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rek[50];\r
-            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rek[51];\r
-            /* round 13: */\r
-            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rek[52];\r
-            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rek[53];\r
-            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rek[54];\r
-            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rek[55];\r
-        }\r
-    }\r
-    rek += Nr << 2;\r
-#else  /* !FULL_UNROLL */\r
-    /*\r
-        * Nr - 1 full rounds:\r
-        */\r
-    r = Nr >> 1;\r
-    for (;;) {\r
-        t0 =\r
-            Te0[(s0 >> 24)       ] ^\r
-            Te1[(s1 >> 16) & 0xff] ^\r
-            Te2[(s2 >>  8) & 0xff] ^\r
-            Te3[(s3      ) & 0xff] ^\r
-            rek[4];\r
-        t1 =\r
-            Te0[(s1 >> 24)       ] ^\r
-            Te1[(s2 >> 16) & 0xff] ^\r
-            Te2[(s3 >>  8) & 0xff] ^\r
-            Te3[(s0      ) & 0xff] ^\r
-            rek[5];\r
-        t2 =\r
-            Te0[(s2 >> 24)       ] ^\r
-            Te1[(s3 >> 16) & 0xff] ^\r
-            Te2[(s0 >>  8) & 0xff] ^\r
-            Te3[(s1      ) & 0xff] ^\r
-            rek[6];\r
-        t3 =\r
-            Te0[(s3 >> 24)       ] ^\r
-            Te1[(s0 >> 16) & 0xff] ^\r
-            Te2[(s1 >>  8) & 0xff] ^\r
-            Te3[(s2      ) & 0xff] ^\r
-            rek[7];\r
-\r
-        rek += 8;\r
-        if (--r == 0) {\r
-            break;\r
-        }\r
-\r
-        s0 =\r
-            Te0[(t0 >> 24)       ] ^\r
-            Te1[(t1 >> 16) & 0xff] ^\r
-            Te2[(t2 >>  8) & 0xff] ^\r
-            Te3[(t3      ) & 0xff] ^\r
-            rek[0];\r
-        s1 =\r
-            Te0[(t1 >> 24)       ] ^\r
-            Te1[(t2 >> 16) & 0xff] ^\r
-            Te2[(t3 >>  8) & 0xff] ^\r
-            Te3[(t0      ) & 0xff] ^\r
-            rek[1];\r
-        s2 =\r
-            Te0[(t2 >> 24)       ] ^\r
-            Te1[(t3 >> 16) & 0xff] ^\r
-            Te2[(t0 >>  8) & 0xff] ^\r
-            Te3[(t1      ) & 0xff] ^\r
-            rek[2];\r
-        s3 =\r
-            Te0[(t3 >> 24)       ] ^\r
-            Te1[(t0 >> 16) & 0xff] ^\r
-            Te2[(t1 >>  8) & 0xff] ^\r
-            Te3[(t2      ) & 0xff] ^\r
-            rek[3];\r
-    }\r
-#endif /* ?FULL_UNROLL */\r
-    /*\r
-        * apply last round and\r
-        * map cipher state to byte array block:\r
-        */\r
-       s0 =\r
-               (Te4[(t0 >> 24)       ] & 0xff000000) ^\r
-               (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Te4[(t3      ) & 0xff] & 0x000000ff) ^\r
-               rek[0];\r
-       PUTWORD(ct     , s0);\r
-       s1 =\r
-               (Te4[(t1 >> 24)       ] & 0xff000000) ^\r
-               (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Te4[(t0      ) & 0xff] & 0x000000ff) ^\r
-               rek[1];\r
-       PUTWORD(ct +  4, s1);\r
-       s2 =\r
-               (Te4[(t2 >> 24)       ] & 0xff000000) ^\r
-               (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Te4[(t1      ) & 0xff] & 0x000000ff) ^\r
-               rek[2];\r
-       PUTWORD(ct +  8, s2);\r
-       s3 =\r
-               (Te4[(t3 >> 24)       ] & 0xff000000) ^\r
-               (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Te4[(t2      ) & 0xff] & 0x000000ff) ^\r
-               rek[3];\r
-       PUTWORD(ct + 12, s3);\r
-}\r
-\r
-void AES::decrypt(const byte *ct, byte *pt) {\r
-    uint *rdk = d_sched;\r
-       uint s0, s1, s2, s3, t0, t1, t2, t3;\r
-#ifndef FULL_UNROLL\r
-    int r;\r
-#endif /* ?FULL_UNROLL */\r
-\r
-    /*\r
-        * map byte array block to cipher state\r
-        * and add initial round key:\r
-        */\r
-    s0 = GETWORD(ct     ) ^ rdk[0];\r
-    s1 = GETWORD(ct +  4) ^ rdk[1];\r
-    s2 = GETWORD(ct +  8) ^ rdk[2];\r
-    s3 = GETWORD(ct + 12) ^ rdk[3];\r
-#ifdef FULL_UNROLL\r
-    /* round 1: */\r
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[ 4];\r
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[ 5];\r
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[ 6];\r
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[ 7];\r
-    /* round 2: */\r
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[ 8];\r
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[ 9];\r
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[10];\r
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[11];\r
-    /* round 3: */\r
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[12];\r
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[13];\r
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[14];\r
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[15];\r
-    /* round 4: */\r
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[16];\r
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[17];\r
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[18];\r
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[19];\r
-    /* round 5: */\r
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[20];\r
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[21];\r
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[22];\r
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[23];\r
-    /* round 6: */\r
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[24];\r
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[25];\r
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[26];\r
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[27];\r
-    /* round 7: */\r
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[28];\r
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[29];\r
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[30];\r
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[31];\r
-    /* round 8: */\r
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[32];\r
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[33];\r
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[34];\r
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[35];\r
-    /* round 9: */\r
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[36];\r
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[37];\r
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[38];\r
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[39];\r
-    if (Nr > 10) {\r
-        /* round 10: */\r
-        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[40];\r
-        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[41];\r
-        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[42];\r
-        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[43];\r
-        /* round 11: */\r
-        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[44];\r
-        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[45];\r
-        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[46];\r
-        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[47];\r
-        if (Nr > 12) {\r
-            /* round 12: */\r
-            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rdk[48];\r
-            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rdk[49];\r
-            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rdk[50];\r
-            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rdk[51];\r
-            /* round 13: */\r
-            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rdk[52];\r
-            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rdk[53];\r
-            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rdk[54];\r
-            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rdk[55];\r
-        }\r
-    }\r
-       rdk += Nr << 2;\r
-#else  /* !FULL_UNROLL */\r
-    /*\r
-     * Nr - 1 full rounds:\r
-     */\r
-    r = Nr >> 1;\r
-    for (;;) {\r
-        t0 =\r
-            Td0[(s0 >> 24)       ] ^\r
-            Td1[(s3 >> 16) & 0xff] ^\r
-            Td2[(s2 >>  8) & 0xff] ^\r
-            Td3[(s1      ) & 0xff] ^\r
-            rdk[4];\r
-        t1 =\r
-            Td0[(s1 >> 24)       ] ^\r
-            Td1[(s0 >> 16) & 0xff] ^\r
-            Td2[(s3 >>  8) & 0xff] ^\r
-            Td3[(s2      ) & 0xff] ^\r
-            rdk[5];\r
-        t2 =\r
-            Td0[(s2 >> 24)       ] ^\r
-            Td1[(s1 >> 16) & 0xff] ^\r
-            Td2[(s0 >>  8) & 0xff] ^\r
-            Td3[(s3      ) & 0xff] ^\r
-            rdk[6];\r
-        t3 =\r
-            Td0[(s3 >> 24)       ] ^\r
-            Td1[(s2 >> 16) & 0xff] ^\r
-            Td2[(s1 >>  8) & 0xff] ^\r
-            Td3[(s0      ) & 0xff] ^\r
-            rdk[7];\r
-\r
-        rdk += 8;\r
-        if (--r == 0) {\r
-            break;\r
-        }\r
-\r
-        s0 =\r
-            Td0[(t0 >> 24)       ] ^\r
-            Td1[(t3 >> 16) & 0xff] ^\r
-            Td2[(t2 >>  8) & 0xff] ^\r
-            Td3[(t1      ) & 0xff] ^\r
-            rdk[0];\r
-        s1 =\r
-            Td0[(t1 >> 24)       ] ^\r
-            Td1[(t0 >> 16) & 0xff] ^\r
-            Td2[(t3 >>  8) & 0xff] ^\r
-            Td3[(t2      ) & 0xff] ^\r
-            rdk[1];\r
-        s2 =\r
-            Td0[(t2 >> 24)       ] ^\r
-            Td1[(t1 >> 16) & 0xff] ^\r
-            Td2[(t0 >>  8) & 0xff] ^\r
-            Td3[(t3      ) & 0xff] ^\r
-            rdk[2];\r
-        s3 =\r
-            Td0[(t3 >> 24)       ] ^\r
-            Td1[(t2 >> 16) & 0xff] ^\r
-            Td2[(t1 >>  8) & 0xff] ^\r
-            Td3[(t0      ) & 0xff] ^\r
-            rdk[3];\r
-    }\r
-#endif /* ?FULL_UNROLL */\r
-    /*\r
-        * apply last round and\r
-        * map cipher state to byte array block:\r
-        */\r
-       s0 =\r
-               (Td4[(t0 >> 24)       ] & 0xff000000) ^\r
-               (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Td4[(t1      ) & 0xff] & 0x000000ff) ^\r
-               rdk[0];\r
-       PUTWORD(pt     , s0);\r
-       s1 =\r
-               (Td4[(t1 >> 24)       ] & 0xff000000) ^\r
-               (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Td4[(t2      ) & 0xff] & 0x000000ff) ^\r
-               rdk[1];\r
-       PUTWORD(pt +  4, s1);\r
-       s2 =\r
-               (Td4[(t2 >> 24)       ] & 0xff000000) ^\r
-               (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Td4[(t3      ) & 0xff] & 0x000000ff) ^\r
-               rdk[2];\r
-       PUTWORD(pt +  8, s2);\r
-       s3 =\r
-               (Td4[(t3 >> 24)       ] & 0xff000000) ^\r
-               (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^\r
-               (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^\r
-               (Td4[(t0      ) & 0xff] & 0x000000ff) ^\r
-               rdk[3];\r
-       PUTWORD(pt + 12, s3);\r
-}\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/AES.h b/src/modules/rlm_eap/types/rlm_eap_psk/AES.h
deleted file mode 100644 (file)
index 4505c27..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/**\r
- * AES.h\r
- *\r
- * The Advanced Encryption Standard (AES, aka AES) block cipher,\r
- * designed by J. Daemen and V. Rijmen.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __AES_H\r
-#define __AES_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(AES_H, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char   byte;\r
-typedef unsigned long   uint;   /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-#ifndef AES_BLOCKBITS\r
-#define AES_BLOCKBITS   128\r
-#endif\r
-#if AES_BLOCKBITS != 128\r
-#error "AES_BLOCKBITS must be 128"\r
-#endif\r
-\r
-#ifndef AES_BLOCKSIZE\r
-#define AES_BLOCKSIZE   16 /* bytes */\r
-#endif\r
-#if AES_BLOCKSIZE != 16\r
-#error "AES_BLOCKSIZE must be 16"\r
-#endif\r
-\r
-#ifndef AES_MINKEYBITS\r
-#define AES_MINKEYBITS  128\r
-#endif\r
-#if AES_MINKEYBITS != 128\r
-#error "AES_MINKEYBITS must be 128"\r
-#endif\r
-\r
-#ifndef AES_MINKEYSIZE\r
-#define AES_MINKEYSIZE  16 /* bytes */\r
-#endif\r
-#if AES_MINKEYSIZE != 16\r
-#error "AES_MINKEYSIZE must be 16"\r
-#endif\r
-\r
-#ifndef AES_MAXKEYBITS\r
-#define AES_MAXKEYBITS  256\r
-#endif\r
-#if AES_MAXKEYBITS != 256\r
-#error "AES_MAXKEYBITS must be 256"\r
-#endif\r
-\r
-#ifndef AES_MAXKEYSIZE\r
-#define AES_MAXKEYSIZE  32 /* bytes */\r
-#endif\r
-#if AES_MAXKEYSIZE != 32\r
-#error "AES_MAXKEYSIZE must be 32"\r
-#endif\r
-\r
-#define MAXKC  (AES_MAXKEYBITS/32)\r
-#define MAXKB  (AES_MAXKEYBITS/8)\r
-#define MAXNR  14\r
-\r
-class AES: public BlockCipher {\r
-public:\r
-\r
-       AES();\r
-       virtual ~AES();\r
-\r
-    /**\r
-     * Block size in bits.\r
-     */\r
-    inline uint blockBits() const {\r
-               return AES_BLOCKBITS;\r
-       }\r
-\r
-    /**\r
-     * Block size in bytes.\r
-     */\r
-    inline uint blockSize() const {\r
-               return AES_BLOCKSIZE;\r
-       }\r
-\r
-    /**\r
-     * Key size in bits.\r
-     */\r
-       inline uint keyBits() const {\r
-               return (Nr - 6) << 5;\r
-       }\r
-\r
-    /**\r
-     * Key size in bytes.\r
-     */\r
-       inline uint keySize() const {\r
-               return (Nr - 6) << 2;\r
-       }\r
-\r
-    void makeKey(const byte *cipherKey, uint keyBits, uint dir);\r
-\r
-    void encrypt(const byte *pt, byte *ct);\r
-\r
-    void decrypt(const byte *ct, byte *pt);\r
-\r
-private:\r
-    // static void Initialize();\r
-       void ExpandKey(const byte *cipherKey, uint keyBits);\r
-       void InvertKey();\r
-       uint Nr;\r
-       uint e_sched[4*(MAXNR + 1)];\r
-       uint d_sched[4*(MAXNR + 1)];\r
-};\r
-\r
-#endif /* __AES_H */\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/BlockCipher.h b/src/modules/rlm_eap/types/rlm_eap_psk/BlockCipher.h
deleted file mode 100644 (file)
index 919569f..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/**\r
- * BlockCipher.h\r
- *\r
- * A simple abstraction for the basic functionality of a block cipher engine.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __BLOCKCIPHER_H\r
-#define __BLOCKCIPHER_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(BlockCipher_h, "$Id$")\r
-\r
-#include "/usr/include/sys/types.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char   byte;\r
-//typedef unsigned long   uint;   /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-#define DIR_NONE    0\r
-#define DIR_ENCRYPT 1\r
-#define DIR_DECRYPT 2\r
-#define DIR_BOTH    (DIR_ENCRYPT | DIR_DECRYPT) /* both directions */\r
-\r
-class BlockCipher {\r
-public:\r
-\r
-    /**\r
-     * Cipher's block size in bits.\r
-     */\r
-    virtual uint blockBits() const = 0;\r
-\r
-    /**\r
-     * Cipher's block size in bytes.\r
-     */\r
-       virtual uint blockSize() const = 0;\r
-\r
-    /**\r
-     * Cipher's key size in bits.\r
-     */\r
-       virtual uint keyBits() const = 0;\r
-\r
-    /**\r
-     * Cipher's key size in bytes.\r
-     */\r
-    virtual uint keySize() const = 0;\r
-\r
-    /**\r
-     * Setup the key schedule for encryption, decryption, or both.\r
-     *\r
-     * @param   cipherKey   the cipher key.\r
-     * @param   keyBits     size of the cipher key in bits.\r
-     * @param   direction   cipher direction (DIR_ENCRYPT, DIR_DECRYPT, or DIR_BOTH).\r
-     */\r
-    virtual void makeKey(const byte *cipherKey, uint keyBits, uint dir) = 0;\r
-\r
-    /**\r
-     * Encrypt exactly one block of plaintext.\r
-     *\r
-     * @param   pt          plaintext block.\r
-     * @param   ct          ciphertext block.\r
-     */\r
-    virtual void encrypt(const byte *pt, byte *ct) = 0;\r
-\r
-    /**\r
-     * Decrypt exactly one block of ciphertext.\r
-     *\r
-     * @param   ct          ciphertext block.\r
-     * @param   pt          plaintext block.\r
-     */\r
-    virtual void decrypt(const byte *ct, byte *pt) = 0;\r
-\r
-};\r
-\r
-#endif /* __BLOCKCIPHER_H */\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/CTR.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/CTR.cpp
deleted file mode 100644 (file)
index 0a6a499..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*\r
- * CTR.cpp\r
- *\r
- * The counter (CTR) mode of operation for block ciphers.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "CTR.h"\r
-\r
-CTR::CTR(BlockCipher* E) {\r
-    this->E = E;\r
-    block_size = E->blockSize();\r
-    N = (byte *)calloc(block_size, 1);\r
-    S = (byte *)calloc(block_size, 1);\r
-    s = 0;\r
-}\r
-\r
-CTR::~CTR() {\r
-    memset(N, (byte)0, block_size); free(N);\r
-    memset(S, (byte)0, block_size); free(S);\r
-}\r
-\r
-void CTR::init(const byte* N) {\r
-    // initialize nonce:\r
-    memcpy(this->N, N, block_size);\r
-    E->encrypt(N, S); // S = E_K(N)\r
-    s = block_size;\r
-}\r
-\r
-void CTR::update(const byte* M, uint m, byte* C) {\r
-    uint i = block_size - s;\r
-    uint j = 0;\r
-    while (m >= s) {\r
-        for (uint b = 0; b < s; b++) {\r
-            C[j + b] = (byte)(M[j + b] ^ S[i + b]);\r
-        }\r
-        // proceed to the next block:\r
-        m -= s;\r
-        j += s;\r
-        // increment the nonce:\r
-        for (uint n = block_size - 1; n >= 0; n--) {\r
-            if ((++N[n] & 0xff) != 0) {\r
-                break;\r
-            }\r
-        }\r
-        E->encrypt(N, S);\r
-        s = block_size;\r
-        i = 0;\r
-    }\r
-    //assert(m < s);\r
-    // process remaining chunk (m bytes):\r
-    for (uint b = 0; b < m; b++) {\r
-        C[j + b] = (byte)(M[j + b] ^ S[i + b]);\r
-    }\r
-    s -= m;\r
-    //assert(0 < s && s <= block_size);\r
-}\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/CTR.h b/src/modules/rlm_eap/types/rlm_eap_psk/CTR.h
deleted file mode 100644 (file)
index 0a6307c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*\r
- * CTR.h\r
- *\r
- * The counter (CTR) mode of operation for block ciphers.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __CTR_H\r
-#define __CTR_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(CTR_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char   byte;\r
-typedef unsigned long   uint;   /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-class CTR {\r
-public:\r
-\r
-    CTR(BlockCipher* E);\r
-    virtual ~CTR();\r
-\r
-    /**\r
-     * Start encrypting/decrypting a message using a given nonce.\r
-     *\r
-     * @param   N   the normalized nonce (initial counter value)\r
-     */\r
-    void init(const byte* N);\r
-\r
-    /**\r
-     * Either encrypt or decrypt a message chunk.\r
-     *\r
-     * @param   M   message chunk\r
-     * @param   m   its length in bytes\r
-     * @param   C   the resulting encrypted/decrypted message chunk\r
-     */\r
-    void update(const byte* M, uint m, byte* C);\r
-\r
-private:\r
-    BlockCipher *E; // block cipher context\r
-    uint block_size;\r
-    byte* N;        // CTR counter  (block_size bytes)\r
-    byte* S;        // CTR mask     (block_size bytes)\r
-    uint s;         // available mask bytes on S\r
-};\r
-\r
-#endif /* __CTR_H */\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/EAX.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/EAX.cpp
deleted file mode 100644 (file)
index e28cd1d..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*\r
- * EAX.cpp\r
- *\r
- * The EAX authenticated encryption mode of operation,\r
- * designed by M. Bellare, P. Rogaway and D. Wagner.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "EAX.h"\r
-\r
-EAX::EAX() {\r
-       _E = 0; // block cipher context\r
-       tag_size = 0;\r
-       block_size = 0;\r
-       t_n = 0;      // [t]_n\r
-       _C = 0;       // CTR context\r
-       nt = 0;\r
-       ht = 0;\r
-       mt = 0;\r
-}\r
-\r
-/*********************************************************************\r
- * Calls common to incremental and non-incremental API\r
- ********************************************************************/\r
-\r
-void EAX::initialize(const byte* K, uint k, uint t, BlockCipher* E) {\r
-       if (E == 0) {\r
-               throw "Invalid cipher";\r
-       }\r
-    if (K == 0) {\r
-        throw "Invalid key size";\r
-    }\r
-    if (t > E->blockSize()) {\r
-        throw "Invalid tag size";\r
-    }\r
-    _E = E;\r
-    _E->makeKey(K, k, DIR_ENCRYPT);\r
-    _C = new CTR(_E);\r
-    tag_size = t;\r
-    block_size = _E->blockSize();\r
-    t_n = (byte *)calloc(block_size, 1);\r
-    nt = (byte *)calloc(block_size, 1);\r
-    ht = (byte *)calloc(block_size, 1);\r
-    mt = (byte *)calloc(block_size, 1);\r
-}\r
-\r
-/**\r
- * Session is over; destroy all key material and cleanup!\r
- */\r
-EAX::~EAX() {\r
-       if (_E != 0) {\r
-               t_n[block_size - 1] = 0;\r
-               delete _C;\r
-               memset(nt, (byte)0, block_size);\r
-               memset(ht, (byte)0, block_size);\r
-               memset(mt, (byte)0, block_size);\r
-       }\r
-}\r
-\r
-/**\r
- * Supply a message header. The header "grows" with each call\r
- * until a eax_provide_header() call is made that follows a\r
- * eax_encrypt(), eax_decrypt(), eax_provide_plaintext(),\r
- * eax_provide_ciphertext() or eax_compute_plaintext() call.\r
- * That starts reinitializes the header.\r
- */\r
-void EAX::provideHeader(const byte* H, uint h) {\r
-    if (H == 0 && h > 0) {\r
-        throw "Invalid header";\r
-    }\r
-    _H.update(H, h);\r
-}\r
-\r
-\r
-/*********************************************************************\r
- * All-in-one, non-incremental interface\r
- ********************************************************************/\r
-\r
-/**\r
- * Encrypt the given message with the given key, nonce and header.\r
- * Specify the header (if nonempty) with eax_provide_header().\r
- */\r
-void EAX::encrypt(\r
-        const byte* N,  // the nonce and\r
-        uint n,         // its length (in bytes), and\r
-        const byte* M,  // the plaintext and\r
-        uint m,         // its length (in bytes).\r
-        byte* C,        // The m-byte ciphertext\r
-        byte* T) {      // and the tag T are returned.\r
-    provideNonce(N, n);\r
-    computeCiphertext(M, m, C);\r
-    if (T != 0) {\r
-        computeTag(T);\r
-    }\r
-}\r
-\r
-/**\r
- * Decrypt the given ciphertext with the given key, nonce and header.\r
- * Specify the header (if nonempty) with eax_provide_header().\r
- * Returns 1 for a valid ciphertext, 0 for an invalid ciphertext and for invalid or missing parameters.\r
- */\r
-bool EAX::decrypt(\r
-        const byte* N,  // the nonce and\r
-        uint n,         // its length (in bytes), and\r
-        const byte* C,  // the ciphertext and\r
-        uint c,         // its length (in bytes), and\r
-        const byte* T,  // the tag.\r
-        byte* P) {      // if valid, return the c-byte plaintext.\r
-    provideNonce(N, n);\r
-    provideCiphertext(C, c);\r
-    if (checkTag(T)) {\r
-        computePlaintext(C, c, P);\r
-        return true;\r
-    } else {\r
-        return false;\r
-    }\r
-}\r
-\r
-\r
-/*********************************************************************\r
- * Incremental interface\r
- ********************************************************************/\r
-\r
-/**\r
- * Provide a nonce. For encryption, do this before calling\r
- * eax_compute_ciphertext() and eax_compute_tag();\r
- * for decryption, do this before calling\r
- * eax_provide_ciphertext(), eax_check_tag, or eax_compute_plaintext().\r
- */\r
-void EAX::provideNonce(const byte* N, uint n) {\r
-    if (N == 0 && n > 0) {\r
-        throw "Invalid nonce";\r
-    }\r
-    // nonce OMAC:\r
-    t_n[block_size - 1] = 0;\r
-    _N.init(_E);\r
-    _N.update(t_n, block_size);\r
-    _N.update(N, n);\r
-    _N.final(nt);\r
-    _C->init(nt); // N <- OMAC_K^0(N)\r
-    memset(nt, (byte)0, block_size);\r
-    // header OMAC:\r
-    t_n[block_size - 1] = 1;\r
-    _H.init(_E);\r
-    _H.update(t_n, block_size);\r
-    // message OMAC:\r
-    t_n[block_size - 1] = 2;\r
-    _M.init(_E);\r
-    _M.update(t_n, block_size);\r
-}\r
-\r
-/**\r
- * Encrypt a message or a part of a message.\r
- * The nonce needs already to have been\r
- * specified by a call to eax_provide_nonce().\r
- */\r
-void EAX::computeCiphertext(const byte* M, uint m, byte* C) {\r
-    if (M == 0 && m > 0 ||\r
-        C == 0) {\r
-        throw "Invalid buffer(s)";\r
-    }\r
-    _C->update(M, m, C);\r
-    _M.update(C, m);\r
-}\r
-\r
-/**\r
- * Message and header finished: compute the authentication tag that is a part\r
- * of the complete ciphertext.\r
- */\r
-void EAX::computeTag(byte* T) {     // compute the tag T.\r
-    if (T == 0 && tag_size > 0) {\r
-        throw "Invalid tag";\r
-    }\r
-    //assert(M.t < block_size);   // at least [t]_n must have been provided\r
-    _N.final(nt);\r
-    _H.final(ht);\r
-    _M.final(mt);\r
-    for (uint i = 0; i < tag_size; i++) {\r
-        T[i] = (byte)(nt[i] ^ ht[i] ^ mt[i]);\r
-    }\r
-}\r
-\r
-/**\r
- * Supply the ciphertext, or the next piece of ciphertext.\r
- * This is used to check for the subsequent authenticity check eax_check_tag().\r
- */\r
-void EAX::provideCiphertext(const byte* C, uint c) {\r
-    if (C == 0 && c > 0) {\r
-        throw "Invalid ciphertext";\r
-    }\r
-    _M.update(C, c);\r
-}\r
-\r
-/**\r
- * The nonce, ciphertext and header have all been fully provided; check if\r
- * they are valid for the given tag.\r
- * Returns true for a valid ciphertext, false for an invalid ciphertext\r
- * (in which case plaintext/ciphertext might be zeroized as well).\r
- */\r
-bool EAX::checkTag(const byte* T) {\r
-    if (T == 0 && tag_size > 0) {\r
-        throw "Invalid tag";\r
-    }\r
-    //assert(M.t < block_size);   // at least [t]_n must have been provided\r
-    _N.final(nt);\r
-    _H.final(ht);\r
-    _M.final(mt);\r
-    for (uint i = 0; i < tag_size; i++) {\r
-        if (T[i] != (byte)(nt[i] ^ ht[i] ^ mt[i])) {\r
-            return false;\r
-        }\r
-    }\r
-    return true;\r
-}\r
-\r
-/**\r
- * Recover the plaintext from the provided ciphertext.\r
- * A call to eax_provide_nonce() needs to precede this call.\r
- * The caller is responsible for separately checking if the ciphertext is valid.\r
- * Normally this would be done before computing the plaintext with\r
- * eax_compute_plaintext().\r
- */\r
-void EAX::computePlaintext(const byte* C, uint c, byte* P) {\r
-    if (C == 0 && c > 0 ||\r
-        P == 0) {\r
-        throw "Invalid buffer(s)";\r
-    }\r
-    _C->update(C, c, P);\r
-}\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/EAX.h b/src/modules/rlm_eap/types/rlm_eap_psk/EAX.h
deleted file mode 100644 (file)
index 64062dd..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*\r
- * EAX.h\r
- *\r
- * The EAX authenticated encryption mode of operation,\r
- * designed by M. Bellare, P. Rogaway and D. Wagner.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __EAX_H\r
-#define __EAX_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(EAX_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-#include "OMAC.h"\r
-#include "CTR.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char   byte;\r
-typedef unsigned long   uint;   /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-class EAX {\r
-public:\r
-\r
-       EAX();\r
-\r
-    /**\r
-     * Key and parameter setup to init a EAX context data structure.\r
-     */\r
-    void initialize(const byte* K, uint k, uint t, BlockCipher* E);\r
-\r
-    /**\r
-     * Session is over; destroy all key material and cleanup!\r
-     */\r
-    virtual ~EAX();\r
-\r
-    /*********************************************************************\r
-     * Calls common to incremental and non-incremental API\r
-     ********************************************************************/\r
-\r
-    /**\r
-     * Supply a message header. The header "grows" with each call\r
-     * until a eax_provide_header() call is made that follows a\r
-     * eax_encrypt(), eax_decrypt(), eax_provide_plaintext(),\r
-     * eax_provide_ciphertext() or eax_compute_plaintext() call.\r
-     * That starts reinitializes the header.\r
-     */\r
-    void provideHeader(const byte* H, uint h);\r
-\r
-\r
-    /*********************************************************************\r
-     * All-in-one, non-incremental interface\r
-     ********************************************************************/\r
-\r
-    /**\r
-     * Encrypt the given message with the given key, nonce and header.\r
-     * Specify the header (if nonempty) with eax_provide_header().\r
-     */\r
-    void encrypt(\r
-            const byte* N,  // the nonce and\r
-            uint n,         // its length (in bytes), and\r
-            const byte* M,  // the plaintext and\r
-            uint m,         // its length (in bytes).\r
-            byte* C,        // The m-byte ciphertext\r
-            byte* T);\r
-\r
-    /**\r
-     * Decrypt the given ciphertext with the given key, nonce and header.\r
-     * Specify the header (if nonempty) with eax_provide_header().\r
-     * Returns 1 for a valid ciphertext, 0 for an invalid ciphertext and for invalid or missing parameters.\r
-     */\r
-    bool decrypt(\r
-            const byte* N,  // the nonce and\r
-            uint n,         // its length (in bytes), and\r
-            const byte* C,  // the ciphertext and\r
-            uint c,         // its length (in bytes), and\r
-            const byte* T,  // the tag.\r
-            byte* P);\r
-\r
-\r
-    /*********************************************************************\r
-     * Incremental interface\r
-     ********************************************************************/\r
-\r
-    /**\r
-     * Provide a nonce. For encryption, do this before calling\r
-     * eax_compute_ciphertext() and eax_compute_tag();\r
-     * for decryption, do this before calling\r
-     * eax_provide_ciphertext(), eax_check_tag, or eax_compute_plaintext().\r
-     */\r
-    void provideNonce(const byte* N, uint n);\r
-\r
-    /**\r
-     * Encrypt a message or a part of a message.\r
-     * The nonce needs already to have been\r
-     * specified by a call to eax_provide_nonce().\r
-     */\r
-    void computeCiphertext(const byte* M, uint m, byte* C);\r
-\r
-    /**\r
-     * Message and header finished: compute the authentication tag that is a part\r
-     * of the complete ciphertext.\r
-     */\r
-    void computeTag(byte* T);\r
-\r
-    /**\r
-     * Supply the ciphertext, or the next piece of ciphertext.\r
-     * This is used to check for the subsequent authenticity check eax_check_tag().\r
-     */\r
-    void provideCiphertext(const byte* C, uint c);\r
-\r
-    /**\r
-     * The nonce, ciphertext and header have all been fully provided; check if\r
-     * they are valid for the given tag.\r
-     * Returns true for a valid ciphertext, false for an invalid ciphertext\r
-     * (in which case plaintext/ciphertext might be zeroized as well).\r
-     */\r
-    bool checkTag(const byte* T);\r
-\r
-    /**\r
-     * Recover the plaintext from the provided ciphertext.\r
-     * A call to eax_provide_nonce() needs to precede this call.\r
-     * The caller is responsible for separately checking if the ciphertext is valid.\r
-     * Normally this would be done before computing the plaintext with\r
-     * eax_compute_plaintext().\r
-     */\r
-    void computePlaintext(const byte* C, uint c, byte* P);\r
-\r
-private:\r
-    BlockCipher* _E;// block cipher context\r
-    uint tag_size;\r
-    uint block_size;\r
-    byte* t_n;      // [t]_n\r
-    OMAC _N;        // nonce OMAC\r
-    OMAC _H;        // header OMAC\r
-    OMAC _M;        // message OMAC\r
-    CTR* _C;        // CTR context\r
-    byte* nt;\r
-    byte* ht;\r
-    byte* mt;\r
-};\r
-\r
-#endif /* __EAX_H */\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/Makefile.in b/src/modules/rlm_eap/types/rlm_eap_psk/Makefile.in
deleted file mode 100644 (file)
index 7d4aac9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# $Id$
-#
-
-TARGET      = rlm_eap_psk
-SRCS        = rlm_eap_psk.cpp eap_psk.cpp eap_psk_ssm.cpp AES.cpp OMAC.cpp CTR.cpp EAX.cpp SOBMMO.cpp userinfo.c
-HEADERS     = eap_psk.h eap_psk_ssm.h AES.h OMAC.h CTR.h EAX.h BlockCipher.h SOBMMO.h userinfo.h
-RLM_CFLAGS  = $(INCLTDL) -I../.. -I../../libeap
-RLM_LIBS    = -lstdc++
-RLM_INSTALL =
-
-RLM_DIR=../../
-include ${RLM_DIR}../rules.mak
-
-$(LT_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/OMAC.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/OMAC.cpp
deleted file mode 100644 (file)
index 8c1cf84..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*\r
- * OMAC.cpp\r
- *\r
- * The One-key CBC MAC (OMAC) message authentication code,\r
- * designed by T. Iwata and K. Kurosawa.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSID("$Id$")\r
-\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "OMAC.h"\r
-\r
-OMAC::OMAC() {\r
-    _E = 0;\r
-    block_size = 0;\r
-    t = 0;\r
-    mask = 0;\r
-    ready = 0;\r
-    memset(L, (byte)0, sizeof(L));\r
-    memset(T, (byte)0, sizeof(L));\r
-}\r
-\r
-OMAC::~OMAC() {\r
-    _E = 0;\r
-    block_size = 0;\r
-    t = 0;\r
-    mask = 0;\r
-    ready = 0;\r
-    memset(L, (byte)0, sizeof(L));\r
-    memset(T, (byte)0, sizeof(L));\r
-}\r
-\r
-void OMAC::init(BlockCipher* E) {\r
-    if (E == 0) {\r
-        throw "Invalid block cipher";\r
-    }\r
-    _E = E;\r
-    t = block_size = _E->blockSize();\r
-    if (block_size != 16 && block_size != 8) {\r
-        throw "Block size not supported";\r
-    }\r
-    mask = (block_size == 16) ? 0x87 : 0x1B;\r
-    // compute padding mask:\r
-    memset(L, (byte)0, block_size);\r
-    _E->encrypt(L, L); // L = E_K(0^n)\r
-    uint c = L[0] & 0x80; // carry\r
-    for (uint b = 0; b < block_size - 1; b++) {\r
-        L[b] = (byte)((L[b] << 1) | ((L[b + 1] & 0xff) >> 7));\r
-    }\r
-    L[block_size - 1] = (byte)((L[block_size - 1] << 1) ^ (c != 0 ? mask : 0)); // B = 2L\r
-    // initialize tag accumulator\r
-    memset(T, (byte)0, block_size);\r
-    ready = 0;\r
-}\r
-\r
-void OMAC::update(const byte* M, uint m) {\r
-    if (_E == 0) {\r
-        throw "OMAC computation not initialized";\r
-    }\r
-    uint i = block_size - t;\r
-    uint j = 0;\r
-    while (m > t) { // N.B. m is strictly larger than t!\r
-        // complete tag block:\r
-        for (uint b = 0; b < t; b++) {\r
-            T[i + b] ^= M[j + b];\r
-        }\r
-        _E->encrypt(T, T); // since there is more data, no padding applies\r
-        // proceed to the next block:\r
-        m -= t;\r
-        j += t;\r
-        t = block_size;\r
-        i = 0;\r
-        //assert(m > 0);\r
-    }\r
-    // process remaining chunk (m bytes):\r
-    for (uint b = 0; b < m; b++) {\r
-        T[i + b] ^= M[j + b];\r
-    }\r
-    t -= m;\r
-    //assert(m == 0 || t < block_size); // m == 0 here only occurs if m == 0 from the very beginning\r
-}\r
-\r
-void OMAC::final(byte* tag) {\r
-    if (_E != 0) {\r
-        // compute padding:\r
-        if (t > 0) {\r
-            // compute special padding mask:\r
-            uint c = L[0] & 0x80; // carry\r
-            for (uint b = 0; b < block_size - 1; b++) {\r
-                L[b] = (byte)((L[b] << 1) | ((L[b + 1] & 0xff) >> 7));\r
-            }\r
-            L[block_size - 1] = (byte)((L[block_size - 1] << 1) ^ (c != 0 ? mask : 0)); // P = 4L\r
-            // pad incomplete block:\r
-            T[block_size - t] ^= 0x80; // padding toggle\r
-            t = 0;\r
-        }\r
-        for (uint b = 0; b < block_size; b++) {\r
-            T[b] ^= L[b];\r
-        }\r
-        _E->encrypt(T, T); // T contains the complete tag\r
-        ready = 1; // OMAC tag available\r
-        _E = 0; // OMAC computation is complete; context no longer initialized\r
-    } else if (!ready) {\r
-        throw "OMAC computation not initialized";\r
-    }\r
-    memcpy(tag, T, block_size);\r
-}\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/OMAC.h b/src/modules/rlm_eap/types/rlm_eap_psk/OMAC.h
deleted file mode 100644 (file)
index 62f364a..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*\r
- * OMAC.h\r
- *\r
- * The One-key CBC MAC (OMAC) message authentication code,\r
- * designed by T. Iwata and K. Kurosawa.\r
- *\r
- * @author Paulo S. L. M. Barreto\r
- *\r
- * @version 2.0\r
- *\r
- * This software is hereby placed in the public domain.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#ifndef __OMAC_H\r
-#define __OMAC_H\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(OMAC_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-#ifndef USUAL_TYPES\r
-#define USUAL_TYPES\r
-typedef unsigned char   byte;\r
-typedef unsigned long   uint;   /* assuming sizeof(uint) == 4 */\r
-#endif /* USUAL_TYPES */\r
-\r
-#define OMAC_MAXBLOCKSIZE   16\r
-\r
-class OMAC {\r
-public:\r
-\r
-    OMAC();\r
-\r
-    virtual ~OMAC();\r
-\r
-    /**\r
-     * Start computing an OMAC tag by selecting the underlying block cipher.\r
-     *\r
-     * @param   E   block cipher underlying OMAC computation.\r
-     *              CAVEAT: in the current implementation the block size\r
-     *              must be either 16 or 8.\r
-     */\r
-    void init(BlockCipher* E);\r
-\r
-    /**\r
-     * Update the OMAC tag computation with a message chunk.\r
-     *\r
-     * @param   M   message chunk\r
-     * @param   m   its length in bytes\r
-     */\r
-    void update(const byte* M, uint m);\r
-\r
-    /**\r
-     * Complete the computation of the OMAC tag, or simply\r
-     * get the finished OMAC tag if available.\r
-     *\r
-     * @return  the OMAC tag.\r
-     */\r
-    void final(byte *tag);\r
-\r
-    /**\r
-     * Get the default tag size for the underlying block cipher.\r
-     *\r
-     * @return the default tag size in bytes.\r
-     */\r
-    uint tagSize() {\r
-        return block_size;\r
-    }\r
-\r
-private:\r
-    BlockCipher *_E;            // block cipher context\r
-    uint block_size;\r
-    uint t;                     // remaining space on T, in bytes\r
-    uint mask;\r
-    uint ready;\r
-    byte L[OMAC_MAXBLOCKSIZE];  // OMAC padding (block_size bytes): B = 2L, P = 4L\r
-    byte T[OMAC_MAXBLOCKSIZE];  // OMAC tag     (block_size bytes)\r
-};\r
-\r
-#endif /* __OMAC_H */\r
-\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/SOBMMO.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/SOBMMO.cpp
deleted file mode 100644 (file)
index 36ab6a8..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- *@memo        Implementation of the modified counter mode
- *@doc
- *@author      A. MAGNIEZ (FT R&D - DTL/SSR)
- *
- * Copyright 2006 The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include "SOBMMO.h"
-#include <stdlib.h>
-#include <string.h>
-#include "eap_psk.h"
-
-/**
- *@memo                default constructor
- */
-SOBMMO::SOBMMO():sizeBlock(0),nbOutputBlocks(0),outputBlocks(NULL) {
-}
-
-/**
- *@memo                default destructor
- */
-SOBMMO::~SOBMMO() {
-  if(outputBlocks!=NULL) {
-    free(outputBlocks);
-  }
-}
-
-/**
- *@memo                this function initializes the modified counter mode
- *@param       K, the dedicated key (its size must be equal to the block size of E)
- *@param       E, the block cipher context
- *@param       inputBlock, the input block (its size must be equal to the block size of E)
- *@param       nb, the number of wanted output blocks
- *@param       counterValues, the counter values (its size must be nbOutputBlock*sizeBlock)
- *@return      1 if the output blocks have been produced, 0 in the other cases.
- */
-int SOBMMO::initialize(const byte* K, BlockCipher* E,const byte* inputBlock,int nb,const byte* counterValues){
-  int i; // iterator
-  char hexstr[1024];
-  byte buf[16];
-
-  sizeBlock=E->blockSize();
-  nbOutputBlocks=nb;
-
-
-  // allocate memory for the output blocks
-  outputBlocks=(byte *)malloc(sizeBlock*nbOutputBlocks);
-  if(outputBlocks==NULL){
-    return 0;
-  }
-
-  // debug traces
-  pskConvertHex((char *)K, (char *)&hexstr, sizeBlock);
-  DEBUG2("SOBMMO::initialize: K=");
-  DEBUG2((char *)&hexstr);
-
-  pskConvertHex((char *)inputBlock, (char *)&hexstr, sizeBlock);
-  DEBUG2("SOBMMO::initialize: inputBlock=");
-  DEBUG2((char *)&hexstr);
-
-  pskConvertHex((char *)counterValues, (char *)&hexstr, sizeBlock*nbOutputBlocks);
-  DEBUG2("SOBMMO::initialize: counterValues=");
-  DEBUG2((char *)&hexstr);
-
-  E->makeKey(K,sizeBlock,DIR_ENCRYPT);
-  E->encrypt(inputBlock,outputBlocks);
-
-  // duplicate the first result
-  for(i=1;i<nbOutputBlocks;i++)
-    {
-      memcpy(outputBlocks+i*sizeBlock,outputBlocks,sizeBlock);
-    }
-
-  pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
-  DEBUG2("SOBMMO::initialize: outputBlocks before XOR=");
-  DEBUG2((char *)&hexstr);
-
-  // XOR counter values
-  for(i=0;i<(nbOutputBlocks*sizeBlock);i++)
-    {
-      *(outputBlocks+i)=(*(outputBlocks+i))^(*(counterValues+i));
-    }
-
-  pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
-  DEBUG2("SOBMMO::initialize: outputBlocks after XOR=");
-  DEBUG2((char *)&hexstr);
-
-  // in order to check that AES(K,M) is valid
-  E->encrypt(outputBlocks,buf);
-  pskConvertHex((char *)buf, (char *)&hexstr, 16);
-  DEBUG2("SOBMMO::initialize: buf=");
-  DEBUG2((char *)&hexstr);
-
-  // produce each output block
-  for(i=0;i<nbOutputBlocks;i++)
-    {
-      E->encrypt(outputBlocks+i*sizeBlock,outputBlocks+i*sizeBlock); // Be careful, pt=ct !!! TBTested
-    }
-
-  pskConvertHex((char *)outputBlocks, (char *)&hexstr, nbOutputBlocks*sizeBlock);
-  DEBUG2("SOBMMO::initialize: produced output blocks=");
-  DEBUG2((char *)&hexstr);
-
-  return 1;
-
-}
-
-
-/**
- *@memo                this function returns an output block
- *@param       id, the number of the wanted output block (the numerotation begins at 1 !!)
- */
-byte* SOBMMO::getOutputBlock(int id){
-  byte* output=NULL;
-
-  if(id<1 || id>nbOutputBlocks) {
-    return NULL;
-  }
-
-  output=(byte*)malloc(sizeBlock);
-  if(output==NULL){
-    return NULL;
-  }
-  memcpy(output,outputBlocks+(id-1)*sizeBlock,sizeBlock);
-  return output;
-}
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/SOBMMO.h b/src/modules/rlm_eap/types/rlm_eap_psk/SOBMMO.h
deleted file mode 100644 (file)
index 4f1796b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**\r
- *@memo        Implementation of the modified counter mode\r
- *@doc          \r
- *@author      A. MAGNIEZ (FT R&D - DTL/SSR) \r
- *\r
- * Copyright 2006 The FreeRADIUS server project\r
- */\r
-\r
-#ifndef _SOBMMO_H_\r
-#define _SOBMMO_H_\r
-\r
-#include <freeradius-devel/ident.h>\r
-RCSIDH(SOBMMO_h, "$Id$")\r
-\r
-#include "BlockCipher.h"\r
-\r
-\r
-class SOBMMO {\r
- public:\r
-  \r
-  SOBMMO();\r
-  \r
-  int initialize(const byte* K, BlockCipher* E,const byte* inputBlock,int nb,const byte* counterValues);\r
-  \r
-  byte* getOutputBlock(int id);\r
-  \r
-  virtual ~SOBMMO();\r
-  \r
-private:\r
-  int sizeBlock; //the size of a block cipher (input and output) in bytes\r
-  int nbOutputBlocks; //number of required output blocks\r
-  byte* outputBlocks; //pointer to output blocks\r
-};\r
-\r
-#endif\r
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk.cpp
deleted file mode 100644 (file)
index d02c8e1..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $Id$ */
-
-/*
- * eap_psk.cpp
- *
- * Implementation of the EAP-PSK packet management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "eap_psk.h"
-
-
-/*
- *
- *  PSK Packet Format in EAP
- *  --- ------ ------ -- ---
- * 0                   1                   2                   3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |     Code      |   Identifier  |            Length             |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |     Type      |   Data
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- */
-
-
-int pskConvertHex(char *inbytes, char *outstr, int numbytes)
-{
-       int i;
-       char buildstr[1024], tempstr[10];
-
-       memset(buildstr, 0, 1024);
-
-       for (i=0;i<numbytes;i++)
-       {
-               sprintf((char *)tempstr, "%02X",(unsigned char)inbytes[i]);
-               strcat((char *)buildstr, (char *)tempstr);
-       }
-       strcpy(outstr, (char *)buildstr);
-
-       return 1;
-}
-
-
-int pskHex2Bin(const char *hex, unsigned char *bin, int numbytes) {
-    int len = strlen(hex);
-    char c;
-    int i;
-    unsigned char v;
-    for (i = 0; i < numbytes; i++) {
-        c = hex[2*i];
-        if (c >= '0' && c <= '9') {
-            v = c - '0';
-        } else if (c >= 'A' && c <= 'F') {
-         v = c - 'A' + 10;
-        } else if (c >= 'a' && c <= 'f') {
-         v = c - 'a' + 10;
-        } else {
-         //v = 0;
-         return 0; // non hexa character
-        }
-        v <<= 4;
-        c = hex[2*i + 1];
-        if (c >= '0' && c <= '9') {
-         v += c - '0';
-        } else if (c >= 'A' && c <= 'F') {
-         v += c - 'A' + 10;
-        } else if (c >= 'a' && c <= 'f') {
-         v += c - 'a' + 10;
-        } else {
-         //v = 0;
-         return 0; // non hexa character
-        }
-        bin[i] = v;
-    }
-    return 1;
-}
-
-
-int pskGetRandomBytes(void *buf, int nbytes){
-  FILE *fptr=NULL;
-  int written=0;
-
-  if((fptr = fopen("/dev/urandom","r")) == NULL) {
-    radlog(L_ERR,"pskGetRandomBytes: urandom device not accessible");
-    return 0;
-  }
-
-  if((written = fread(buf,1,nbytes,fptr)) != nbytes) {
-    radlog(L_ERR,"pskGetRandomBytes: number not generated");
-    return 0;
-  }
-
-  fclose(fptr);
-
-  return 1;
-}
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk.h b/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk.h
deleted file mode 100644 (file)
index 07b0cf7..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $Id$ */
-
-/*
- * eap_psk.h
- *
- * Implementation of the EAP-PSK packet management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-
-
-#ifndef _EAP_PSK_H
-#define _EAP_PSK_H
-
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_psk_h, "$Id$")
-
-#include "eap.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-// EAP-PSK Type
-#define EAPPSK_TYPE 255
-
-// EXT_Payload maximum length in bytes
-#define EXT_PAYLOAD_MAX_LEN 977
-
-#define PSK_PCHANNEL_REPLAY_COUNTER_SIZE sizeof(unsigned long int) // size in octets
-#define PSK_KEY_SIZE (PSK_AK_SIZE+PSK_KDK_SIZE)                    // size in octets
-#define PSK_AK_SIZE 16                                             // size in octets
-#define PSK_KDK_SIZE 16                                            // size in octets
-#define PSK_TEK_SIZE 16                                            // size in octets
-#define PSK_MSK_SIZE 64                                            // size in octets
-#define PSK_EMSK_SIZE 64                                           // size in octets
-#define PSK_RANDOM_NUMBER_SIZE 16                                  // size in octets
-#define PSK_MAC_SIZE 16                                            // size in octets
-#define EAP_HEADER_SIZE 5                                          // size in octets
-#define PSK_SIZE 16
-
-
-
-// EAP-PSK attribute flags
-#define PSK_STATUS_CONT            0x40
-#define PSK_STATUS_DONE_FAILURE    0xC0
-#define PSK_STATUS_DONE_SUCCESS    0x80
-
-#define PSK_IS_EXT                 0x20
-
-
-// the EAP-PSK configuration parameters
-typedef struct eap_psk_conf {
-  unsigned char        *privateKey;           // the server private key
-  unsigned char        *id_s;                 // the server name
-  unsigned int ldapSupport;           // if an LDAP directory is used
-  unsigned char        *peerNaiAttribute;     // the LDAP attribute name which corresponds to the peer NAI
-  unsigned char        *peerKeyAttribute;     // the LDAP attribute name which corresponds to the peer Key = AK || KDK
-  unsigned char  *usersFilePath;       // the EAP-PSK users file path
-  unsigned int   nbRetry;              // the number of bad authorized responses while the EAP-PSK authentication
-  unsigned int   maxDelay;                // the maximum interval in seconds between two correct responses
-} PSK_CONF;
-
-
-// data format of the first EAP-PSK message
-typedef struct psk_message_1 {
-  unsigned char rand_s[PSK_RANDOM_NUMBER_SIZE];
-}psk_message_1;
-
-// data format of the second EAP-PSK message
-typedef struct psk_message_2 {
-  unsigned char rand_p[PSK_RANDOM_NUMBER_SIZE];
-  unsigned char mac_p[16];
-  unsigned char *id_p;
-}psk_message_2;
-
-// data format of the third EAP-PSK message
-typedef struct psk_message_3 {
-  unsigned char mac_s[16];
-  unsigned long int nonce;
-  unsigned char tag[16];
-  unsigned char flags;
-  unsigned char ext_type;
-  unsigned char *extPayload;
-}psk_message_3;
-
-// data format of the fourth EAP-PSK message
-typedef struct psk_message_4 {
-  unsigned long int nonce;
-  unsigned char tag[16];
-  unsigned char flags;
-  unsigned char ext_type;
-  unsigned char *ext_payload;
-}psk_message_4;
-
-
-/**
- *@memo                this function converts a string into hexa
- *@param    inbytes, pointer to a string
- *@param    outstr, pointer to the hexa conversion
- *@param    numbytes, number of bytes to convert
- *@return      0 if an error has occured
- */
-int pskConvertHex(char *inbytes, char *outstr, int numbytes);
-
-
-/**
- *@memo                this function converts a string which contains hexa characters into hexa
- *@param    inbytes, the string to convert
- *@param       outstr, the conversion in hexa
- *@param       numbytes, the number of bytes to convert
- *@return      0 if an error has occured
- */
-int pskHex2Bin(const char *hex, unsigned char *bin, int numbytes);
-
-
-/**
- *@memo                this function delivers random bytes
- *@param    buf, pointer to the buffer to fill
- *@param    nbytes, number of bytes to generate
- *@return   0 if an error has occured
- */
-int pskGetRandomBytes(void *buf, int nbytes);
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /*_EAP_PSK_H*/
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk_ssm.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk_ssm.cpp
deleted file mode 100644 (file)
index 02bd03c..0000000
+++ /dev/null
@@ -1,800 +0,0 @@
-/* $Id$ */
-
-/*
- * eap_psk_ssm.cpp
- *
- * Implementation of the Server State Machine (SSM)
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-
-#include "autoconf.h"
-#include "libradius.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "radiusd.h"
-#include "modpriv.h"
-#include "modules.h"
-#include "modcall.h"
-#include "conffile.h"
-#include "ltdl.h"
-
-
-#include "eap_psk_ssm.h"
-#include "AES.h"
-#include "OMAC.h"
-#include "EAX.h"
-#include "SOBMMO.h"
-
-#include "userinfo.h"
-
-
-/*  PSK Packet Format in EAP
- *  --- ------ ------ -- ---
- * 0                   1                   2                   3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |     Code      |   Identifier  |            Length             |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |     Type      |   Data
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-
- */
-
-
-int pskProcess(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket){
-
-  // error cases
-  if(conf==NULL || session==NULL)
-    {
-      radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without EAP-PSK configuration and session information");
-      return 0;
-    }
-
-  if(recvPacket && (recvPacket->code!=PW_EAP_RESPONSE || recvPacket->type.type!=EAPPSK_TYPE))
-    {
-      radlog(L_ERR,"pskProcess: EAP-PSK Response expected");
-      return 0;
-    }
-
-  switch(session->state)
-    {
-    case INIT: return pskInit(conf,session,sentPacket);
-    case RANDSENT:
-               if(recvPacket) return pskRandSent(conf,session, recvPacket,sentPacket);
-    case PCHANNEL:
-               if(recvPacket) return pskPChannel(conf,session,recvPacket,sentPacket);
-    default:
-      radlog(L_ERR,"pskProcess: Impossible to process the EAP-PSK authentication");
-      return 0;
-    }
-
-}
-
-
-int pskInit(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *sentPacket){
-
-  char hexstr[1024];
-
-  session->nbRetry=0;
-  session->pChannelReplayCounter=0;
-  session->authStatus=PSK_STATUS_CONT;
-  session->isSupportedExt=1;
-  session->extType=0;
-
-  sentPacket->code=PW_EAP_REQUEST;
-  sentPacket->length=PSK_RANDOM_NUMBER_SIZE+EAP_HEADER_SIZE;
-  sentPacket->type.type=EAPPSK_TYPE;
-  sentPacket->type.length=PSK_RANDOM_NUMBER_SIZE;
-  sentPacket->type.data=NULL;
-  sentPacket->type.data=(unsigned char*)malloc(PSK_RANDOM_NUMBER_SIZE);
-
-  if(sentPacket->type.data==NULL)
-    {
-      radlog(L_ERR,"pskInit: Out of memory");
-      return 0;
-    }
-
-  // generate a 128-bit random value and put this value in session->rand_s
-  if(!pskGetRandomBytes(sentPacket->type.data,PSK_RANDOM_NUMBER_SIZE)) {
-    radlog(L_ERR,"pskInit: problem during random number generation");
-    return 0;
-  }
-
-  pskConvertHex((char *)sentPacket->type.data, (char *)hexstr,PSK_RANDOM_NUMBER_SIZE);
-  DEBUG2("pskInit: random number RA :");
-  DEBUG2((char *)hexstr);
-
-  // save this value in session information
-  memcpy(session->rand_s,sentPacket->type.data,PSK_RANDOM_NUMBER_SIZE);
-
-  session->state=RANDSENT;
-
-  return 1;
-
-}
-
-
-int pskRandSent(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket){
-
-  /* the received packet is shown below
-   *
-   * 0                   1                   2                   3
-   * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |    Code=2     |  Identifier   |            Length             |
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |  Type EAP-PSK |                                               |
-   * +-+-+-+-+-+-+-+-+                                               +
-   * |                                                               |
-   * +                                                               +
-   * |                             RAND_P                            |
-   * +                                                               +
-   * |                                                               |
-   * +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |               |                                               |
-   * +-+-+-+-+-+-+-+-+                                               +
-   * |                                                               |
-   * +                                                               +
-   * |                             MAC_P                             |
-   * +                                                               +
-   * |                                                               |
-   * +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |               |                                               |
-   * +-+-+-+-+-+-+-+-+                                               :
-   * :                              ID_P                             :
-   * :                                                               :
-   * +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |                               |
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   */
-
-
-  psk_message_2 *psk_msg_2;
-  psk_message_3 *psk_msg_3;
-  int identitySize;
-  char hexstr[1024];
-
-  unsigned char buffer[PSK_MAC_SIZE];
-  unsigned char *data;
-  unsigned char *ptr;
-  unsigned char buftmp[PSK_AK_SIZE+PSK_KDK_SIZE];
-
-  //user profile
-  userinfo_t*    uinfo = NULL;
-
-  char **psk_vals;
-  char *psk_val;
-  int i=0;
-  char **atts;
-  unsigned char privateKey[PSK_SIZE];
-
-  // for the mac calculation
-  OMAC om;
-  AES c;
-
-  // for the key derivation
-  SOBMMO sob;
-  unsigned char *block;
-  // counter values
-  unsigned char counterValues[]={
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09};
-
-
-  // for the pchannel
-  unsigned char nn[PSK_RANDOM_NUMBER_SIZE];
-  unsigned char eapHeader[EAP_HEADER_SIZE];
-  EAX eax;
-
-
-
-  if(recvPacket->length<(EAP_HEADER_SIZE+PSK_RANDOM_NUMBER_SIZE+PSK_MAC_SIZE+1))
-    {
-      // the packet is malformed
-      DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
-      sentPacket->code=PW_EAP_FAILURE;
-
-      return 1;
-    }
-
-  // retrieve the identity of the peer, ID_P
-  identitySize=recvPacket->length-(EAP_HEADER_SIZE+PSK_RANDOM_NUMBER_SIZE+PSK_MAC_SIZE);
-  session->id_p=(unsigned char *)malloc(identitySize+1);
-  if(session->id_p==NULL)
-    {
-      radlog(L_ERR,"pskRandSent: Out of memory");
-      return 0;
-    }
-  psk_msg_2=(psk_message_2*)recvPacket->type.data;
-  memcpy(session->id_p,&(psk_msg_2->id_p),identitySize);
-  session->id_p[identitySize]='\0';
-
-  // search the peer identity in the user file whose path is conf->usersFilePath
-
-  uinfo = pskGetUserInfo((char*)conf->usersFilePath, (char*)session->id_p);
-  if (uinfo)
-    {
-
-      DEBUG2("pskRandSent: identity successfully checked");
-      DEBUG2("pskRandSent: saving peer information");
-
-      // save keys
-      memcpy(session->ak,uinfo->AK,PSK_AK_SIZE);
-      memcpy(session->kdk,uinfo->KDK,PSK_KDK_SIZE);
-
-      DEBUG2("pskRandSent: found user %s in %s",session->id_p, conf->usersFilePath);
-
-      free(uinfo);
-
-    } else {
-
-      // the peer identity wasn't found
-      DEBUG2("pskRandSent: the peer identity isn't valid");
-      DEBUG2("pskRandSent: the authentication must fail");
-      sentPacket->code=PW_EAP_FAILURE;
-
-      return 1;
-    }
-
-  // calculate the following MAC: MAC(session->ak, ID_P || conf->id_s || session->rand_s || RAND_P)
-
-  // making the formula
-  data=(unsigned char *)malloc(strlen((char*)session->id_p)+strlen((char*)conf->id_s)+2*PSK_RANDOM_NUMBER_SIZE);
-  if(data==NULL) {
-    radlog(L_ERR,"pskRandSent: out of memory");
-    return 0;
-  }
-  ptr=data;
-  memcpy(ptr,session->id_p,strlen((char*)session->id_p));
-  ptr+=strlen((char*)session->id_p);
-  memcpy(ptr,conf->id_s,strlen((char*)conf->id_s));
-  ptr+=strlen((char*)conf->id_s);
-  memcpy(ptr,session->rand_s,PSK_RANDOM_NUMBER_SIZE);
-  ptr+=PSK_RANDOM_NUMBER_SIZE;
-  memcpy(ptr,psk_msg_2->rand_p,PSK_RANDOM_NUMBER_SIZE);
-
-  pskConvertHex((char *)data, (char *)hexstr,strlen((char*)session->id_p)+strlen((char*)conf->id_s)+2*PSK_RANDOM_NUMBER_SIZE);
-  DEBUG2("pskRandSent: [B||A||RA||RB] :");
-  DEBUG2((char *)hexstr);
-
-  pskConvertHex((char *)(session->ak), (char *)hexstr,PSK_AK_SIZE);
-  DEBUG2("pskRandSent: AK :");
-  DEBUG2((char *)hexstr);
-
-
-  // obtain the mac
-
-  c.makeKey(session->ak,PSK_AK_SIZE,DIR_ENCRYPT);
-  om.init(&c);
-  om.update(data,strlen((char*)session->id_p)+strlen((char*)conf->id_s)+2*PSK_RANDOM_NUMBER_SIZE);
-  om.final(buffer);
-  free(data);
-
-  pskConvertHex((char *)buffer, (char *)hexstr,PSK_MAC_SIZE);
-  DEBUG2("pskRandSent: MAC of [B||A||RA||RB] :");
-  DEBUG2((char *)hexstr);
-
-
-  if(memcmp(buffer,psk_msg_2->mac_p,PSK_MAC_SIZE))
-    {
-      // the received MAC attribute is not correct
-      DEBUG2("pskRandSent: the received MAC attribute isn't correct");
-      DEBUG2("pskRandSent: the authentication must fail");
-      sentPacket->code=PW_EAP_FAILURE;
-
-      return 1;
-    }
-
-
-  DEBUG2("pskRandSent: the received MAC attribute is correct");
-
-  // KEY DERIVATION
-
-  // initialize the sobmmo
-  sob.initialize(session->kdk,&c,psk_msg_2->rand_p,9,counterValues);
-
-  // get the TEK
-  block=sob.getOutputBlock(1);
-  memcpy(session->tek,block,PSK_TEK_SIZE);
-  free(block);
-
-  pskConvertHex((char *)session->tek, (char *)hexstr, PSK_TEK_SIZE);
-  DEBUG2("pskRandSent: TEK :");
-  DEBUG2((char *)hexstr);
-
-  // get the MSK
-  for(int i=0;i<4;i++)
-    {
-      block=sob.getOutputBlock(i+2);
-      memcpy(&session->msk[i*16],block,16);
-      free(block);
-    }
-
-  pskConvertHex((char *)session->msk, (char *)hexstr, PSK_MSK_SIZE);
-  DEBUG2("pskRandSent: MSK :");
-  DEBUG2((char *)hexstr);
-
-  // get the EMSK
-  for(int i=0;i<4;i++)
-    {
-      block=sob.getOutputBlock(i+6);
-      memcpy(&session->emsk[i*16],block,16);
-      free(block);
-    }
-
-  pskConvertHex((char *)session->emsk, (char *)hexstr, PSK_EMSK_SIZE);
-  DEBUG2("pskRandSent: EMSK :");
-  DEBUG2((char *)hexstr);
-
-
-  // obtain the mac of [A||RB]
-  data=(unsigned char *)malloc(strlen((char*)conf->id_s)+PSK_RANDOM_NUMBER_SIZE);
-  if(data==NULL) {
-    radlog(L_ERR,"pskRandSent: out of memory");
-    return 0;
-  }
-  memcpy(data,conf->id_s,strlen((char*)conf->id_s));
-  memcpy(data+strlen((char*)conf->id_s),psk_msg_2->rand_p,PSK_RANDOM_NUMBER_SIZE);
-
-  pskConvertHex((char *)data, (char *)hexstr,strlen((char*)conf->id_s)+PSK_RANDOM_NUMBER_SIZE);
-  DEBUG2("pskRandSent: [A||RB] :");
-  DEBUG2((char *)hexstr);
-
-  c.makeKey(session->ak,PSK_AK_SIZE,DIR_ENCRYPT);
-  om.init(&c);
-  om.update(data,strlen((char*)conf->id_s)+PSK_RANDOM_NUMBER_SIZE);
-  om.final(buffer);
-  free(data);
-
-  pskConvertHex((char *)&buffer, (char *)hexstr,16);
-  DEBUG2("pskRandSent: MAC of [A||RB] :");
-  DEBUG2((char *)hexstr);
-
-
-  if(session->extType==0)
-    {
-      // standard authentication
-
-      sentPacket->code=PW_EAP_REQUEST;
-      sentPacket->length=EAP_HEADER_SIZE+2*PSK_MAC_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+1;
-      sentPacket->type.type=EAPPSK_TYPE;
-      sentPacket->type.length=2*PSK_MAC_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+1;
-      sentPacket->type.data=NULL;
-      sentPacket->type.data=(unsigned char*)malloc(2*PSK_MAC_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+1);
-
-      if(sentPacket->type.data==NULL)
-       {
-         radlog(L_ERR,"pskRandSent: Out of memory");
-         return 0;
-       }
-
-      psk_msg_3=(psk_message_3*)sentPacket->type.data;
-
-      // add to sentPacket the following MAC: MAC(session->AK, conf->id_s || RAND_P)
-      memcpy(psk_msg_3->mac_s,buffer,PSK_MAC_SIZE);
-
-      // add to sentPacket the following information:
-      // R = DONE_SUCCESS (the R flag is equal to session->authStatus)
-      // E=0
-      psk_msg_3->nonce=htonl(session->pChannelReplayCounter);
-
-      // calculate the EAP header
-      eapHeader[0]=sentPacket->code;
-      eapHeader[1]=(recvPacket->id)+1; // we suppose that the identifier is incremented by 1
-
-      sentPacket->length=htons(sentPacket->length);
-      memcpy(&(eapHeader[2]),&(sentPacket->length),2);
-      sentPacket->length=ntohs(sentPacket->length);
-
-      eapHeader[4]=sentPacket->type.type;
-
-      pskConvertHex((char *)eapHeader, (char *)hexstr,EAP_HEADER_SIZE);
-      DEBUG2("pskRandSent: eapHeader :");
-      DEBUG2((char *)hexstr);
-
-      // the replay counter is the least significant bytes of the nonce !
-      memset(nn,0,PSK_RANDOM_NUMBER_SIZE);
-      memcpy(&nn[PSK_RANDOM_NUMBER_SIZE-PSK_PCHANNEL_REPLAY_COUNTER_SIZE],&(psk_msg_3->nonce),PSK_PCHANNEL_REPLAY_COUNTER_SIZE);
-
-      pskConvertHex((char *)nn, (char *)hexstr,PSK_RANDOM_NUMBER_SIZE);
-      DEBUG2("pskRandSent: nn :");
-      DEBUG2((char *)hexstr);
-
-      session->authStatus=PSK_STATUS_DONE_SUCCESS;
-
-      // EAX encryption
-
-      eax.initialize(session->tek, PSK_TEK_SIZE, AES_BLOCKSIZE, &c);
-
-      eax.provideNonce((byte*)nn,PSK_RANDOM_NUMBER_SIZE);
-      eax.provideHeader((byte*)eapHeader,EAP_HEADER_SIZE);
-      eax.computeCiphertext((byte*)&(session->authStatus),sizeof(session->authStatus),(byte*)&(psk_msg_3->flags));
-      eax.computeTag((byte*)psk_msg_3->tag);
-
-      // !!! BE CAREFUL !!!
-      // the authorization isn't taken into account in this implementation
-      // that's why R=DONE_SUCCESS
-
-    } else {
-      // extended authentication
-
-
-      // !!!!! NOT IMPLEMENTED !!!!!!
-      return 0;
-
-      /*
-
-      // call the extension which must update the session->authStatus, i.e. the result of the EAP-PSK authentication
-      // see the pskExtension function declaration for more details
-      void *payloadOut=NULL;
-      int sizePayloadOut=0;
-      int resul;
-      resul=pskExtension(conf,session,PSK_STATUS_CONT,NULL,0,&payloadOut,&sizePayloadOut);
-
-      if(!resul || (sizePayloadOut<1) || (sizePayloadOut>EXT_PAYLOAD_MAX_LEN))
-       {
-         //the extension has failed
-         // the authentication must fail
-         // the sentPacket must be a EAP_Failure packet
-         return 1;
-       }
-
-      // add to sentPacket the following information:
-      // R = CONT or DONE_FAILURE or DONE_SUCCESS thanks to session->authStatus
-      // E = 1
-      // EXT_Type=session->extType
-      // EXT_payload=payloadOut
-
-      */
-
-    }
-
-  session->pChannelReplayCounter++;
-
-  session->state=PCHANNEL;
-
-
-  return 1;
-
-}
-
-
-
-int pskPChannel(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket){
-
-  /* the received packet is shown below
-   *
-   * 0                   1                   2                   3
-   * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |    Code=2     |  Identifier   |            Length             |
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |  Type EAP-PSK |               Nonce...                                                                      :
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   *     ...Nonce    |                                               |
-   * +-+-+-+-+-+-+-+-+                                               +
-   * |                                                               |
-   * +                                                               +
-   * |                             TAG                               |
-   * +                                                               +
-   * |                                                               |
-   * +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |               | R |E| Reserved|EXT_Type (opt)|                |
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++                +
-   * :                                                               :
-   * :        EXT_Payload (optional)                                 :
-   * +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   * |                               |
-   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-   *
-   * EXT_Type and EXT_Payload must be in the EAP packet when E is set to 1
-   * EXT_Payload could be null
-   *
-  */
-
-  psk_message_4 *psk_msg_4;
-
-  // for the pchannel
-  unsigned char eapHeader[EAP_HEADER_SIZE];
-  unsigned char nn[PSK_RANDOM_NUMBER_SIZE];
-  EAX eax;
-  AES c;
-  bool st;
-  unsigned char flags;
-
-  if(recvPacket->length<(EAP_HEADER_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+PSK_MAC_SIZE+1))
-    {
-      // the packet is malformed
-      // the session->nbRetry isn't incremented
-      // sentPacket must be the previous request sent by the server ###### PB TIMER ########
-
-      DEBUG2("pskPChannel: receiving a invalid EAP-PSK packet: the packet is malformed");
-      DEBUG2("pskPChannel: the authentication must fail");
-      sentPacket->code=PW_EAP_FAILURE;
-
-      return 1;
-    }
-
-
-  psk_msg_4=(psk_message_4*)recvPacket->type.data;
-
-
-  if(ntohl(psk_msg_4->nonce)!=session->pChannelReplayCounter)
-    {
-      // the received packet isn't awaited
-      // the session->nbRetry isn't incremented
-      // sentPacket must be the previous request sent by the server
-
-      DEBUG2("pskPChannel: receiving a invalid EAP-PSK packet: the replay counter isn't valid");
-      DEBUG2("pskPChannel: the authentication must fail");
-      sentPacket->code=PW_EAP_FAILURE;
-
-      return 1;
-    }
-
-  // decrypt the received packet with the EAX mode and check the EAP header
-
-   // calculate the EAP header
-  eapHeader[0]=recvPacket->code;
-  eapHeader[1]=recvPacket->id;
-
-  recvPacket->length=htons(recvPacket->length);
-  memcpy(&(eapHeader[2]),&(recvPacket->length),2);
-  recvPacket->length=ntohs(recvPacket->length);
-
-  eapHeader[4]=recvPacket->type.type;
-
-  // the replay counter is the least significant bytes of the nonce !
-  memset(nn,0,PSK_RANDOM_NUMBER_SIZE);
-  memcpy(&nn[PSK_RANDOM_NUMBER_SIZE-PSK_PCHANNEL_REPLAY_COUNTER_SIZE],&(psk_msg_4->nonce),PSK_PCHANNEL_REPLAY_COUNTER_SIZE);
-
-  // EAX encryption
-
-  eax.initialize(session->tek, PSK_TEK_SIZE, AES_BLOCKSIZE, &c);
-
-  eax.provideNonce((byte*)nn,PSK_RANDOM_NUMBER_SIZE);
-  eax.provideHeader((byte*)eapHeader,EAP_HEADER_SIZE);
-  eax.provideCiphertext((byte*)&(psk_msg_4->flags),sizeof(psk_msg_4->flags));
-  st=eax.checkTag((byte*)psk_msg_4->tag);
-
-  if(!st){
-    // the decryption ends by a failure
-
-    DEBUG2("pskPChannel: receiving a invalid EAP-PSK packet: the decryption fails");
-    DEBUG2("pskPChannel: the authentication must fail");
-    sentPacket->code=PW_EAP_FAILURE;
-
-    return 1;
-  }
-
-
-  eax.computePlaintext((byte*)&(psk_msg_4->flags),sizeof(psk_msg_4->flags),(byte*)&flags);
-
-  if((((flags & PSK_IS_EXT)==PSK_IS_EXT) && recvPacket->length<(EAP_HEADER_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+PSK_MAC_SIZE+2)) || (((flags & PSK_IS_EXT)==0) && recvPacket->length!=(EAP_HEADER_SIZE+PSK_PCHANNEL_REPLAY_COUNTER_SIZE+PSK_MAC_SIZE+1)))
-    {
-      // the packet is malformed
-      // the authentication must fail
-      // the sentPacket must be a EAP_Failure packet
-
-      DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
-      sentPacket->code=PW_EAP_FAILURE;
-
-      return 1;
-     }
-
-
-   if(session->extType==0 && ((flags & PSK_IS_EXT)==PSK_IS_EXT))
-     {
-       // error: standard authentication awaited
-       // the authentication must fail
-       // the sentPacket must be a EAP_Failure packet
-
-       DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
-       sentPacket->code=PW_EAP_FAILURE;
-
-       return 1;
-     }
-
-   if(session->extType!=0 && ((flags & PSK_IS_EXT)==0))
-     {
-       // error: extended authentication awaited
-       // the authentication must fail
-       // the sentPacket must be a EAP_Failure packet
-
-       DEBUG2("pskPChannel: the packet is malformed: the authentication must fail");
-       sentPacket->code=PW_EAP_FAILURE;
-
-       return 1;
-     }
-
-   if((flags & PSK_IS_EXT)==0)
-     {
-       // standard authentication
-
-       if(((flags & PSK_STATUS_DONE_SUCCESS)==PSK_STATUS_DONE_SUCCESS) && session->authStatus==PSK_STATUS_DONE_SUCCESS)
-        {
-          // sentPacket must be an EAP_Success packet
-          // indicate to the lower layer that the MSK and the EMSK are ready
-          // the EAP-PSK authentication will end after sending sentPacket
-
-          sentPacket->code=PW_EAP_SUCCESS;
-
-        } else {
-          // sentPacket must be an EAP_Failure packet
-          // the EAP-PSK authentication will end after sending sentPacket
-
-          sentPacket->code=PW_EAP_FAILURE;
-
-        }
-
-     } else {
-       // extended authentication
-
-
-       // !!!!! NOT IMPLEMENTED !!!!!
-       return 0;
-
-
-       /*
-       if(session->isSupportedExt)
-        {
-
-          if(recvPacket->data.EXT_Payload)
-            {
-
-              // call the extension which must update the session->authStatus, i.e. the result of the EAP-PSK authentication
-              // see the pskExtension function declaration for more details
-              void *payloadOut=NULL;
-              int sizePayloadOut=0;
-              int sizePayloadIn=recvPacket->length-27; // (27=5+16+4+1+1)
-              int resul;
-              resul=pskExtension(conf,session,recvPacket->data.R,recvPacket->data.EXT_Payload,sizePayloadIn,&payloadOut,&sizePayloadOut);
-
-              if(!resul || (sizePayloadOut<1) || (sizePayloadOut>EXT_PAYLOAD_MAX_LEN))
-                {
-                  //the extension has failed
-                  // the authentication must fail
-                  // the sentPacket must be a EAP_Failure packet
-                  return 1;
-                }
-
-              if(recvPacket->data.R != CONT) {
-                // sentPacket must be an EAP_Success packet or an EAP_Failure packet thanks to the server policy and the received R flag
-                // indicate to the lower layer that the MSK and the EMSK are ready in case an EAP_Success packet must be sent
-                // the EAP-PSK authentication will end after sending sentPacket
-                return 1;
-              }
-
-              // add to sentPacket the following information:
-              // R = CONT or DONE_FAILURE or DONE_SUCCESS thanks to session->authStatus
-              // E = 1
-              // EXT_Type=session->extType
-              // EXT_payload=payloadOut
-
-            } else {
-              // the peer doesn't support the specified extension
-
-              session->isSupportedExt=0;
-
-              if(recvPacket->data.R != CONT) {
-                // sentPacket must be an EAP_Success packet or an EAP_Failure packet thanks to the server policy and the received R flag
-                // indicate to the lower layer that the MSK and the EMSK are ready in case of an EAP_Success packet must be sent
-                // the EAP-PSK authentication will end after sending sentPacket
-                return 1;
-              }
-
-              // add to sentPacket the following information:
-              // R = DONE_FAILURE or DONE_SUCCESS thanks to the server policy
-              // E = 1
-              // EXT_Type=session->extType
-            }
-
-        } else {
-
-           if(recvPacket->data.R != CONT && recvPacket->data.EXT_Payload==NULL) {
-             // sentPacket must be an EAP_Success packet or an EAP_Failure packet thanks to the server policy and the received R flag
-             // indicate to the lower layer that the MSK and the EMSK are ready in case of an EAP_Success packet must be sent
-             // the EAP-PSK authentication will end after sending sentPacket
-             return 1;
-
-           } else {
-             // the packet is malformed
-             // the authentication must fail
-             // the sentPacket must be a EAP_Failure packet
-             return 1;
-           }
-
-        }
-       */
-
-       session->pChannelReplayCounter++;
-       // use the EAX mode to encrypt the EXT_Payload and protect the EAP header
-
-       // !!!! NOT IMPLEMENTED !!!!
-       // only standard authentication supported
-
-       session->pChannelReplayCounter++;
-
-     }
-
-   // stay in this state
-   return 1;
-
-}
-
-
-
-int pskExtension(PSK_CONF *conf, PSK_SESSION *session, unsigned short receivedStatus, void *dataIn, int sizeDataIn, void **dataOut, int *sizeDataOut){
-
-  // this functionality makes it possible to do authorization, account refilling...
-
-  // this function must update the session->authStatus variable thanks to its policy, the received R flag, i.e. the receivedStatus variable, and the received data
-
-  // !!! Be careful !!!
-  // dataOut mustn't be NULL
-
-  // !!!! NOT IMPLEMENTED !!!!
-  return 0;
-
-}
-
-
-
-/**
- *@memo                this function frees the session data
- *@param        opaque, pointer to a structure which contains information session
- */
-void pskFreeSession(void *opaque){
-  PSK_SESSION *session;
-
-  DEBUG2("pskFreeSession:");
-
-  if(!opaque) return;
-
-  session=(PSK_SESSION *)opaque;
-  if(!session) return;
-
-  if(session->id_p) {
-    free(session->id_p);
-  }
-
-  free(session);
-
-  opaque=NULL;
-
-  DEBUG2("pskFreeSession: finished");
-
-}
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk_ssm.h b/src/modules/rlm_eap/types/rlm_eap_psk/eap_psk_ssm.h
deleted file mode 100644 (file)
index de886a4..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* $Id$ */
-
-/*
- * eap_psk_ssm.h
- *
- * Implementation of the Server State Machine (SSM)
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#ifndef _EAP_PSK_SSM_H
-#define _EAP_PSK_SSM_H
-
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_psk_ssm_h, "$Id$")
-
-#include "eap_psk.h"
-#include "eap.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-
-// server states
-typedef enum {
-  INIT,       // the server state machine starts in the INIT state
-  RANDSENT,
-  PCHANNEL
-}PSK_STATE;
-
-
-// information which must be kept during the EAP-PSK session
-typedef struct psk_session_t {
-  PSK_STATE state;                                       // state of the server state machine
-  unsigned char rand_s[PSK_RANDOM_NUMBER_SIZE];          // random number generated by the server
-  unsigned char *id_p;                                   // peer identity
-  unsigned char ak[PSK_AK_SIZE];                         // authentication key
-  unsigned char kdk[PSK_KDK_SIZE];                       // derivation key
-  unsigned char tek[PSK_TEK_SIZE];                       // TEK key
-  unsigned char msk[PSK_MSK_SIZE];                       // MSK key
-  unsigned char emsk[PSK_EMSK_SIZE];                     // EMSK key
-  unsigned int nbRetry;                                  // the current number of request re emissions
-  unsigned long int pChannelReplayCounter;               // the p-channel replay counter
-  unsigned char extType;                                // the extension type if evolved authentication is used, else 0
-  unsigned char authStatus;                             // the latest R flag sent by the server
-  unsigned char isSupportedExt;                          // 0 if the peer doesn't support the specified extension
-}PSK_SESSION;
-
-
-/**
- *@memo                this function is the entry point of the server state machine
- *@param        conf, pointer to the current configuration of EAP-PSK
- *@param        session, pointer to a structure which contains information session
- *@param        recvPacket, pointer to a received EAP_PACKET
- *@param        sentPacket, pointer to the EAP_PACKET to send
- *@return       0 if an error has occured
- */
-  int pskProcess(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo                this function corresponds to the first state of the server state machine
- *@param        conf, pointer to the current configuration of EAP-PSK
- *@param        session, pointer to a structure which contains information session
- *@param        sentPacket, pointer to the EAP_PACKET to send
- *@return       0 if an error has occured
- */
-  int pskInit(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo                this function corresponds to the second state of the server state machine
- *@param        conf, pointer to the current configuration of EAP-PSK
- *@param        session, pointer to a structure which contains information session
- *@param        recvPacket, pointer to a received EAP_PACKET
- *@param        sentPacket, pointer to the EAP_PACKET to send
- *@return       0 if an error has occured
- */
-  int pskRandSent(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo                this function corresponds to the third state of the server state machine
- *@param        conf, pointer to the current configuration of EAP-PSK
- *@param        session, pointer to a structure which contains information session
- *@param        recvPacket, pointer to a received EAP_PACKET
- *@param        sentPacket, pointer to the EAP_PACKET to send
- *@return       0 if no error has occured
- */
-  int pskPChannel(PSK_CONF *conf, PSK_SESSION *session, EAP_PACKET *recvPacket, EAP_PACKET *sentPacket);
-
-
-/**
- *@memo                this function contains the extension to EAP-PSK
- *@param        conf, pointer to the current configuration of EAP-PSK
- *@param        session, pointer to a structure which contains information session
- *@param        receivedStatus, the latest R flag sent by the peer
- *@param        dataIn, pointer to the received data
- *@param        sizeDataIn, size of the received data
- *@param        dataOut, pointer to a pointer that points data to send
- *@param        sizeDataOut, pointer to the size of data to be sent (sizeDataOut must be at most equal to EXT_PAYLAOD_MAX_LEN)
- *@return       0 if an error has occured
- */
-  int pskExtension(PSK_CONF *conf, PSK_SESSION *session, unsigned short receivedStatus, void *dataIn, int sizeDataIn, void **dataOut, int *sizeDataOut);
-
-
-/**
- *@memo                this function frees an existing session from memory
- *@param        opaque, pointer to a structure which contains information session
- */
-  void pskFreeSession(void *opaque);
-
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /*_EAP_PSK_SSM_H*/
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/rlm_eap_psk.cpp b/src/modules/rlm_eap/types/rlm_eap_psk/rlm_eap_psk.cpp
deleted file mode 100644 (file)
index 72d054a..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/* $Id$ */
-
-/*
- * rlm_eap_psk.cpp
- *
- * Implementation of the interface between the radius server and
- * the eap-psk protocol
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-
-
-#include "autoconf.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#include "eap_psk.h"
-#include "eap_psk_ssm.h"
-
-static CONF_PARSER moduleConfig[] = {
-       { "private_key", PW_TYPE_STRING_PTR,
-         offsetof(PSK_CONF, privateKey), NULL, NULL },
-       { "server_name", PW_TYPE_STRING_PTR,
-         offsetof(PSK_CONF, id_s), NULL, "pskserver" },
-       { "peer_nai_attribute", PW_TYPE_STRING_PTR,
-         offsetof(PSK_CONF, peerNaiAttribute), NULL, "eapPskPeerNAI" },
-       { "peer_key_attribute", PW_TYPE_STRING_PTR,
-         offsetof(PSK_CONF, peerKeyAttribute), NULL, "eapPskPeerKey" },
-       { "users_file_path", PW_TYPE_STRING_PTR,
-         offsetof(PSK_CONF, usersFilePath), NULL, "/etc/raddb/users.psk" },
-       { "nb_retry", PW_TYPE_INTEGER,
-         offsetof(PSK_CONF, nbRetry), NULL, "3" },
-       { "max_delay", PW_TYPE_INTEGER,
-         offsetof(PSK_CONF, maxDelay), NULL, "5" },
-       { NULL, -1, 0, NULL, NULL }           /* end the list */
-};
-
-
-/**
- *@memo                this function add value pair to reply
- */
-static void addReply(VALUE_PAIR** vp,
-                     const char* name, unsigned char* value, int len)
-{
-       VALUE_PAIR *reply_attr;
-       reply_attr = pairmake(name, "", T_OP_EQ);
-       if (!reply_attr) {
-               DEBUG("rlm_eap_psk: "
-                     "add_reply failed to create attribute %s: %s\n",
-                     name, librad_errstr);
-               return;
-       }
-
-       memcpy(reply_attr->vp_octets, value, len);
-       reply_attr->length = len;
-       pairadd(vp, reply_attr);
-}
-
-/*
- *@memo        this function detaches the module
- */
-static int pskDetach(void *arg)
-{
-       PSK_CONF *inst = (PSK_CONF *) arg;
-
-       if (inst->privateKey) free(inst->privateKey);
-       if (inst->id_s) free(inst->id_s);
-       if (inst->peerNaiAttribute) free(inst->peerNaiAttribute);
-       if (inst->peerKeyAttribute) free(inst->peerKeyAttribute);
-       if(inst->usersFilePath) free(inst->usersFilePath);
-
-       free(inst);
-
-       return 0;
-}
-
-
-/*
- *@memo                 this function attaches the module
- */
-static int pskAttach(CONF_SECTION *cs, void **instance)
-{
-       PSK_CONF *inst;
-
-       inst = (PSK_CONF*)malloc(sizeof(*inst));
-       if (!inst) {
-               radlog(L_ERR, "rlm_eap_psk: out of memory");
-               return -1;
-       }
-       memset(inst, 0, sizeof(*inst));
-
-       // parse the configuration attributes
-       if (cf_section_parse(cs, inst, moduleConfig) < 0) {
-         pskDetach(inst);
-         return -1;
-       }
-
-       *instance = inst;
-       return 0;
-}
-
-
-
-/**
- *@memo                this function begins the conversation when the EAP-Identity response is received
- *              send an initial eap-psk request, ie IDREQ
- *@param        handler, pointer to specific information about the eap-psk protocol
- */
-static int pskInitiate(void *type_arg, EAP_HANDLER *handler)
-{
-  PSK_SESSION *session;
-  PSK_CONF *conf=(PSK_CONF*)type_arg;
-
-  if(conf==NULL)
-    {
-      radlog(L_ERR,"rlm_eap_psk: Cannot initiate EAP-PSK without having its configuration");
-      return 0;
-    }
-
-  DEBUG2("rlm_eap_psk: privateKey: %s",conf->privateKey);
-  DEBUG2("rlm_eap_psk: id_s: %s", conf->id_s);
-  DEBUG2("rlm_eap_psk: peerNaiAttribute: %s", conf->peerNaiAttribute);
-  DEBUG2("rlm_eap_psk: peerKeyAttribute: %s", conf->peerKeyAttribute);
-  DEBUG2("rlm_eap_psk: usersFilePath: %s", conf->usersFilePath);
-
-  // allocate memory in order to save the state of session
-  handler->opaque=malloc(sizeof(PSK_SESSION));
-  if(!handler->opaque) {
-    radlog(L_ERR,"rlm_eap_psk: Out of memory");
-    return 0;
-  }
-
-  // save this pointer in the handler
-  session=(PSK_SESSION *)handler->opaque;
-  handler->free_opaque=pskFreeSession;
-
-  // initializing session information
-  memset(session,0,sizeof(PSK_SESSION));
-  session->state=INIT;
-
-  handler->stage=AUTHENTICATE;
-
-  // initiate the eap-psk protocol
-  return pskProcess(conf,session,NULL,handler->eap_ds->request);
-
-}
-
-
-
-
-/**
- *@memo                this function uses specific EAP-Type authentication mechanism to authenticate the user
- *              may be called many times
- *@param        handler, pointer to specific information about the eap-psk protocol
- */
-static int pskAuthenticate(void *arg, EAP_HANDLER *handler)
-{
-  PSK_SESSION *session;
-  PSK_CONF *conf=(PSK_CONF*)arg;
-  int resul;
-
-  if(conf==NULL)
-    {
-      radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without having EAP-PSK configuration");
-      return 0;
-    }
-
-  if(!handler->opaque) {
-    radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without EAP-PSK session information");
-    return 0;
-  }
-
-  // find the session information
-  session=(PSK_SESSION *)handler->opaque;
-
-  resul=pskProcess(conf,session,handler->eap_ds->response,handler->eap_ds->request);
-
-  if(handler->eap_ds->request->code==PW_EAP_SUCCESS) {
-    // sending keys
-    addReply(&handler->request->reply->vps,"MS-MPPE-Recv-Key",session->msk,32);
-    addReply(&handler->request->reply->vps,"MS-MPPE-Send-Key",&session->msk[32],32);
-  }
-
-  return resul;
-
-}
-
-
-EAP_TYPE rlm_eap_psk = {
-       "eap_psk",
-       pskAttach,              // attach
-       pskInitiate,            // Start the initial request, after Identity
-       NULL,
-       pskAuthenticate,        // authentication
-       pskDetach               // detach
-};
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/userinfo.c b/src/modules/rlm_eap/types/rlm_eap_psk/userinfo.c
deleted file mode 100644 (file)
index 1f8d99a..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $Id$ */
-
-
-/*
- * userinfo.c
- *
- * Implementation of the user management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "userinfo.h"
-#include "eap_psk_ssm.h"
-#include "eap_psk.h"  //hex2Bin()
-
-
-
-userinfo_t*   pskGetUserInfo(char* path, char* peerID)
-{
-    FILE*       fp;
-    char        buff[1024]; //FIXME: give the buffer a proper size
-                            //when we know more about ID length
-    userinfo_t* uinfo = NULL;
-    int         found = 0;
-    char*       AK = NULL;
-    char*       KDK = NULL;
-       int res;
-
-    fp = fopen(path, "r");
-    if (fp == NULL)
-       {
-           radlog(L_ERR, "pskGetUserInfo: failed to open PSK users file");
-           return NULL;
-       }
-
-    while (!found && fgets(buff, sizeof(buff), fp))
-       {
-         unsigned int     i = 0;
-
-           // ignore comments
-           if (buff[0] == '#')
-               continue;
-
-           // read this login name
-           while (! isspace(buff[i]))
-               i++;
-
-           // is it the one we looking for?
-           if ((i != strlen(peerID))
-               || (strncmp(peerID, buff, i) != 0))
-               continue;
-           else
-               found = 1;
-
-           // skip spaces
-           while (isspace(buff[i]))
-               i++;
-
-           // prepare to store user info
-           uinfo = (userinfo_t*) malloc(sizeof(userinfo_t));
-           if (uinfo == NULL)
-               {
-                   radlog(L_ERR, "pskGetUserInfo: out of memory");
-                   return NULL;
-               }
-
-           //get AK
-           AK = strndup(buff + i, PSK_AK_STRLEN);
-            if (AK == NULL) {
-                radlog(L_ERR, "pskGetUserInfo: out of memory");
-                               free(uinfo);
-                               return NULL;
-           }
-           //FIXME: shouldnt we check the key size?
-           /*
-             else if (strlen(AK) != 32) {
-             log();
-             return NULL;
-             }
-           */
-           res=pskHex2Bin(AK, &(uinfo->AK),PSK_AK_SIZE);
-
-               if(!res)
-               {
-                       radlog(L_ERR, "pskGetUserInfo: the key isn't in hexadecimal format");
-                       free(uinfo);
-                       free(AK);
-                       return NULL;
-               }
-
-           //get KDK
-           KDK = strndup(buff + i + PSK_AK_STRLEN, PSK_KDK_STRLEN);
-           if (KDK == NULL) {
-                       radlog(L_ERR, "psk_get_user_info: out of memory");
-                       free(uinfo);
-                       free(AK);
-                       return NULL;
-           }
-           //FIXME: shouldnt we check the key size?
-           /*
-             else if (strlen(KDK) != 32) {
-             log();
-             return NULL;
-             }
-           */
-           res=pskHex2Bin(KDK, &(uinfo->KDK),PSK_KDK_SIZE);
-
-               if(!res)
-               {
-                       radlog(L_ERR, "pskGetUserInfo: the key isn't in hexadecimal format");
-                       free(uinfo);
-                       free(AK);
-                       free(KDK);
-                       return NULL;
-               }
-
-           free(AK);
-           free(KDK);
-       }
-
-
-    // if user was not found, NULL is returned
-    fclose(fp);
-    return uinfo;
-}
-
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/userinfo.h b/src/modules/rlm_eap/types/rlm_eap_psk/userinfo.h
deleted file mode 100644 (file)
index 7e9c1ad..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $Id$ */
-
-
-/*
- * userinfo.h
- *
- * Implementation of the user management
- *
- *
- * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2006 The FreeRADIUS server project
- *
- */
-
-#ifndef __USERINFO_H__
-#define __USERINFO_H__
-
-#include <freeradius-devel/ident.h>
-RCSIDH(userinfo_h, "$Id$")
-
-
-#include "eap_psk_ssm.h" // PSK_AK/KDK_SIZE
-
-
-
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef struct s_userinfo {
-    //    char*          name;
-    unsigned char  AK[PSK_AK_SIZE];
-    unsigned char  KDK[PSK_KDK_SIZE];
-    //    s_userinfo*  next;
-} userinfo_t;
-
-
-
-
-#define   ASCII_PER_BYTE     2
-#define   PSK_AK_STRLEN      (PSK_AK_SIZE*ASCII_PER_BYTE)
-#define   PSK_KDK_STRLEN     (PSK_KDK_SIZE*ASCII_PER_BYTE)
-
-
-
-
-userinfo_t*  pskGetUserInfo(char*  filename, char*  peerID);
-
-//int        psk_user_free(); //A VOIR
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /*__USERINFO_H__*/
diff --git a/src/modules/rlm_eap/types/rlm_eap_psk/users.psk b/src/modules/rlm_eap/types/rlm_eap_psk/users.psk
deleted file mode 100644 (file)
index abe2218..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# usernames and keys are supposed to be on the same line, separated by
-# white spaces or tabs
-# reading stops after EOF or white line
-#
-
-#user example
-aurelien        9A33DC804926D834894423BDEA4BAA59F6294F39A00D960B3A0DBB404DC62C5C
-
-
-
-
-
diff --git a/src/modules/rlm_eap/types/rlm_eap_sim/Makefile b/src/modules/rlm_eap/types/rlm_eap_sim/Makefile
deleted file mode 100644 (file)
index 56b5318..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Makefile
-#
-# Version:     $Id$
-#
-
-TARGET      = rlm_eap_sim
-SRCS        = rlm_eap_sim.c
-HEADERS     =
-RLM_CFLAGS  = $(INCLTDL) -I../.. -I../../libeap
-RLM_LIBS    =  ../../libeap/libeap.la
-RLM_INSTALL =
-
-RLM_DIR=../../
-include ${RLM_DIR}../rules.mak
-
-$(LT_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_eap/types/rlm_eap_sim/Makefile.in b/src/modules/rlm_eap/types/rlm_eap_sim/Makefile.in
new file mode 100644 (file)
index 0000000..9c588df
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# $Id$
+#
+
+TARGET      = @targetname@
+SRCS        = rlm_eap_sim.c 
+HEADERS     =
+RLM_CFLAGS  = -I../.. -I../../libeap $(INCLTDL)
+RLM_LIBS    = ../../libeap/libeap.la
+RLM_INSTALL =
+
+RLM_DIR=../../
+include ${RLM_DIR}../rules.mak
+
+$(LT_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_eap/types/rlm_eap_sim/configure b/src/modules/rlm_eap/types/rlm_eap_sim/configure
new file mode 100644 (file)
index 0000000..c03f8e4
--- /dev/null
@@ -0,0 +1,3127 @@
+#! /bin/sh
+# From configure.in Revision: 1.3.4.1 .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="rlm_eap_sim.c"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT eap_sim_ldflags eap_sim_cflags targetname LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+fail=
+SMART_LIBS=
+SMART_CLFAGS=
+if test x$with_rlm_eap_sim != xno; then
+
+       ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+       targetname=rlm_eap_sim
+else
+       targetname=
+       echo \*\*\* module rlm_eap_sim is disabled.
+fi
+
+if test x"$fail" != x""; then
+       if test x"${enable_strict_dependencies}" = x"yes"; then
+               { { echo "$as_me:$LINENO: error: set --without-rlm_eap_sim to disable it explicitly." >&5
+echo "$as_me: error: set --without-rlm_eap_sim to disable it explicitly." >&2;}
+   { (exit 1); exit 1; }; }
+       else
+               { echo "$as_me:$LINENO: WARNING: silently not building rlm_eap_sim." >&5
+echo "$as_me: WARNING: silently not building rlm_eap_sim." >&2;}
+               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_eap_sim requires: $fail." >&5
+echo "$as_me: WARNING: FAILURE: rlm_eap_sim requires: $fail." >&2;}
+               if test x"$headersuggestion" != x; then
+                       { echo "$as_me:$LINENO: WARNING: $headersuggestion" >&5
+echo "$as_me: WARNING: $headersuggestion" >&2;}
+               fi
+               if test x"$libsuggestion" != x; then
+                       { echo "$as_me:$LINENO: WARNING: $libsuggestion" >&5
+echo "$as_me: WARNING: $libsuggestion" >&2;}
+               fi
+               targetname=""
+       fi
+fi
+
+eap_sim_ldflags=$SMART_LIBS
+eap_sim_cflags=$SMART_CFLAGS
+
+
+
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@eap_sim_ldflags@,$eap_sim_ldflags,;t t
+s,@eap_sim_cflags@,$eap_sim_cflags,;t t
+s,@targetname@,$targetname,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/src/modules/rlm_eap/types/rlm_eap_sim/configure.in b/src/modules/rlm_eap/types/rlm_eap_sim/configure.in
new file mode 100644 (file)
index 0000000..c5ce37a
--- /dev/null
@@ -0,0 +1,39 @@
+AC_INIT(rlm_eap_sim.c)
+AC_REVISION($Revision$)
+AC_DEFUN(modname,[rlm_eap_sim])
+
+fail=
+SMART_LIBS=
+SMART_CLFAGS=
+if test x$with_[]modname != xno; then
+
+       AC_PROG_CC
+
+       targetname=modname
+else
+       targetname=
+       echo \*\*\* module modname is disabled.
+fi
+
+if test x"$fail" != x""; then
+       if test x"${enable_strict_dependencies}" = x"yes"; then
+               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
+       else
+               AC_MSG_WARN([silently not building ]modname[.])
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.])
+               if test x"$headersuggestion" != x; then
+                       AC_MSG_WARN([$headersuggestion]) 
+               fi
+               if test x"$libsuggestion" != x; then
+                       AC_MSG_WARN([$libsuggestion]) 
+               fi
+               targetname=""
+       fi
+fi
+
+eap_sim_ldflags=$SMART_LIBS
+eap_sim_cflags=$SMART_CFLAGS
+AC_SUBST(eap_sim_ldflags)
+AC_SUBST(eap_sim_cflags)
+AC_SUBST(targetname)
+AC_OUTPUT(Makefile)
index 7b49428..dcbcf33 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca>
- * Copyright 2003,2006  The FreeRADIUS server project
+ * Copyright 2003  The FreeRADIUS server project
  *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,7 +34,7 @@ RCSID("$Id$")
 #include "eap_types.h"
 #include "eap_sim.h"
 
-#include <freeradius-devel/rad_assert.h>
+#include <rad_assert.h>
 
 struct eap_sim_server_state {
        enum eapsim_serverstates state;
@@ -60,7 +57,7 @@ static void add_reply(VALUE_PAIR** vp,
                return;
        }
 
-       memcpy(reply_attr->vp_strvalue, value, len);
+       memcpy(reply_attr->strvalue, value, len);
        reply_attr->length = len;
        pairadd(vp, reply_attr);
 }
@@ -109,7 +106,7 @@ static int eap_sim_sendstart(EAP_HANDLER *handler)
        /* the version list. We support only version 1. */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_VERSION_LIST,
                        PW_TYPE_OCTETS);
-       words = (uint16_t *)newvp->vp_strvalue;
+       words = (uint16_t *)newvp->strvalue;
        newvp->length = 3*sizeof(uint16_t);
        words[0] = htons(1*sizeof(uint16_t));
        words[1] = htons(EAP_SIM_VERSION);
@@ -118,7 +115,7 @@ static int eap_sim_sendstart(EAP_HANDLER *handler)
 
        /* set the EAP_ID - new value */
        newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);
-       newvp->vp_integer = ess->sim_id++;
+       newvp->lvalue = ess->sim_id++;
        pairreplace(vps, newvp);
 
        /* record it in the ess */
@@ -129,13 +126,13 @@ static int eap_sim_sendstart(EAP_HANDLER *handler)
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_FULLAUTH_ID_REQ,
                           PW_TYPE_OCTETS);
        newvp->length = 2;
-       newvp->vp_strvalue[0]=0;
-       newvp->vp_strvalue[0]=1;
+       newvp->strvalue[0]=0;
+       newvp->strvalue[0]=1;
        pairadd(vps, newvp);
 
        /* the SUBTYPE, set to start. */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
-       newvp->vp_integer = eapsim_start;
+       newvp->lvalue = eapsim_start;
        pairreplace(vps, newvp);
 
        return 1;
@@ -159,7 +156,7 @@ static int eap_sim_getchalans(VALUE_PAIR *vps, int chalno,
                       vp->length);
                return 0;
        }
-       memcpy(ess->keys.rand[chalno], vp->vp_strvalue, EAPSIM_RAND_SIZE);
+       memcpy(ess->keys.rand[chalno], vp->strvalue, EAPSIM_RAND_SIZE);
 
        vp = pairfind(vps, ATTRIBUTE_EAP_SIM_SRES1+chalno);
        if(vp == NULL) {
@@ -172,7 +169,7 @@ static int eap_sim_getchalans(VALUE_PAIR *vps, int chalno,
                       vp->length);
                return 0;
        }
-       memcpy(ess->keys.sres[chalno], vp->vp_strvalue, EAPSIM_SRES_SIZE);
+       memcpy(ess->keys.sres[chalno], vp->strvalue, EAPSIM_SRES_SIZE);
 
        vp = pairfind(vps, ATTRIBUTE_EAP_SIM_KC1+chalno);
        if(vp == NULL) {
@@ -185,7 +182,7 @@ static int eap_sim_getchalans(VALUE_PAIR *vps, int chalno,
                       vp->length);
                return 0;
        }
-       memcpy(ess->keys.Kc[chalno], vp->vp_strvalue, EAPSIM_Kc_SIZE);
+       memcpy(ess->keys.Kc[chalno], vp->strvalue, EAPSIM_Kc_SIZE);
 
        return 1;
 }
@@ -232,16 +229,16 @@ static int eap_sim_sendchallenge(EAP_HANDLER *handler)
        /* okay, we got the challenges! Put them into an attribute */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_RAND,
                           PW_TYPE_OCTETS);
-       memset(newvp->vp_strvalue,    0, 2); /* clear reserved bytes */
-       memcpy(newvp->vp_strvalue+2+EAPSIM_RAND_SIZE*0, ess->keys.rand[0], EAPSIM_RAND_SIZE);
-       memcpy(newvp->vp_strvalue+2+EAPSIM_RAND_SIZE*1, ess->keys.rand[1], EAPSIM_RAND_SIZE);
-       memcpy(newvp->vp_strvalue+2+EAPSIM_RAND_SIZE*2, ess->keys.rand[2], EAPSIM_RAND_SIZE);
+       memset(newvp->strvalue,    0, 2); /* clear reserved bytes */
+       memcpy(newvp->strvalue+2+EAPSIM_RAND_SIZE*0, ess->keys.rand[0], EAPSIM_RAND_SIZE);
+       memcpy(newvp->strvalue+2+EAPSIM_RAND_SIZE*1, ess->keys.rand[1], EAPSIM_RAND_SIZE);
+       memcpy(newvp->strvalue+2+EAPSIM_RAND_SIZE*2, ess->keys.rand[2], EAPSIM_RAND_SIZE);
        newvp->length = 2+EAPSIM_RAND_SIZE*3;
        pairadd(outvps, newvp);
 
        /* set the EAP_ID - new value */
        newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);
-       newvp->vp_integer = ess->sim_id++;
+       newvp->lvalue = ess->sim_id++;
        pairreplace(outvps, newvp);
 
        /* make a copy of the identity */
@@ -264,18 +261,18 @@ static int eap_sim_sendchallenge(EAP_HANDLER *handler)
 
        newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC,
                           PW_TYPE_OCTETS);
-       memcpy(newvp->vp_strvalue, ess->keys.nonce_mt, 16);
+       memcpy(newvp->strvalue, ess->keys.nonce_mt, 16);
        newvp->length = 16;
        pairreplace(outvps, newvp);
 
        newvp = paircreate(ATTRIBUTE_EAP_SIM_KEY, PW_TYPE_OCTETS);
-       memcpy(newvp->vp_strvalue, ess->keys.K_aut, 16);
+       memcpy(newvp->strvalue, ess->keys.K_aut, 16);
        newvp->length = 16;
        pairreplace(outvps, newvp);
 
        /* the SUBTYPE, set to challenge. */
        newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);
-       newvp->vp_integer = eapsim_challenge;
+       newvp->lvalue = eapsim_challenge;
        pairreplace(outvps, newvp);
 
        return 1;
@@ -305,7 +302,7 @@ static int eap_sim_sendsuccess(EAP_HANDLER *handler)
 
        /* set the EAP_ID - new value */
        newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);
-       newvp->vp_integer = ess->sim_id++;
+       newvp->lvalue = ess->sim_id++;
        pairreplace(outvps, newvp);
 
        p = ess->keys.msk;
@@ -451,7 +448,7 @@ static int process_eap_sim_start(EAP_HANDLER *handler, VALUE_PAIR *vps)
                DEBUG2("   EAP-Sim version field is too short.");
                return 0;
        }
-       memcpy(&simversion, selectedversion_vp->vp_strvalue, sizeof(simversion));
+       memcpy(&simversion, selectedversion_vp->strvalue, sizeof(simversion));
        simversion = ntohs(simversion);
        if(simversion != EAP_SIM_VERSION) {
                DEBUG2("   EAP-Sim version %d is unknown.", simversion);
@@ -459,7 +456,7 @@ static int process_eap_sim_start(EAP_HANDLER *handler, VALUE_PAIR *vps)
        }
 
        /* record it for later keying */
-       memcpy(ess->keys.versionselect, selectedversion_vp->vp_strvalue,
+       memcpy(ess->keys.versionselect, selectedversion_vp->strvalue,
               sizeof(ess->keys.versionselect));
 
        /*
@@ -469,7 +466,7 @@ static int process_eap_sim_start(EAP_HANDLER *handler, VALUE_PAIR *vps)
                DEBUG2("   EAP-Sim nonce_mt must be 16 bytes (+2 bytes padding), not %d", nonce_vp->length);
                return 0;
        }
-       memcpy(ess->keys.nonce_mt, nonce_vp->vp_strvalue+2, 16);
+       memcpy(ess->keys.nonce_mt, nonce_vp->strvalue+2, 16);
 
        /* everything looks good, change states */
        eap_sim_stateenter(handler, ess, eapsim_server_challenge);
@@ -558,7 +555,7 @@ static int eap_sim_authenticate(void *arg, EAP_HANDLER *handler)
                DEBUG2("   no subtype attribute was created, message dropped");
                return 0;
        }
-       subtype = vp->vp_integer;
+       subtype = vp->lvalue;
 
        /*
         *      Client error supersedes anything else.
@@ -628,3 +625,68 @@ EAP_TYPE rlm_eap_sim = {
        eap_sim_authenticate,           /* authentication */
        NULL                            /* XXX detach */
 };
+
+/*
+ * $Log$
+ * Revision 1.12.4.1  2007-02-15 12:51:38  aland
+ *     Handle Client-Error code.  If the client sends us one, we stop
+ *     talking EAP-SIM.
+ *
+ *     This closes #419
+ *
+ * Revision 1.12  2004/03/19 02:20:35  mcr
+ *     increment the EAP-id on each stage of the transaction.
+ *
+ * Revision 1.11  2004/02/26 19:04:31  aland
+ *     perl -i -npe "s/[ \t]+$//g" `find src -name "*.[ch]" -print`
+ *
+ *     Whitespace changes only, from a fresh checkout.
+ *
+ *     For bug # 13
+ *
+ * Revision 1.10  2004/01/30 20:35:33  mcr
+ *     capture the RAND/SRES/Kc when we initialize the SIM
+ *     rather than later, when they may have changed.
+ *
+ * Revision 1.9  2004/01/30 19:38:29  mcr
+ *     added some debugging of why EAP-sim might not want to
+ *     handle the request - lacking RAND1 attribute.
+ *
+ * Revision 1.8  2003/12/29 01:13:43  mcr
+ *     if the un-marshalling fails, then fail the packet.
+ *
+ * Revision 1.7  2003/11/22 00:21:17  mcr
+ *     send the encryption keys to the AccessPoint.
+ *
+ * Revision 1.6  2003/11/22 00:10:18  mcr
+ *     the version list attribute's length of versions is in bytes,
+ *     not entries.
+ *
+ * Revision 1.5  2003/11/21 19:15:51  mcr
+ *     rename "SIM-Chal" to "SIM-Rand" to sync with names in official
+ *     documentation.
+ *
+ * Revision 1.4  2003/11/21 19:02:19  mcr
+ *     pack the RAND attribute properly - should have 2 bytes
+ * reserved.
+ *
+ * Revision 1.3  2003/11/06 15:45:12  aland
+ *     u_int -> uint
+ *
+ * Revision 1.2  2003/10/31 22:33:45  mcr
+ *     fixes for version list length types.
+ *     do not include length in hash.
+ *     use defines rather than constant sizes.
+ *
+ * Revision 1.1  2003/10/29 02:49:19  mcr
+ *     initial commit of eap-sim
+ *
+ * Revision 1.3  2003/09/14 00:44:42  mcr
+ *     finished trivial challenge state.
+ *
+ *
+ * Local Variables:
+ * c-file-style: "linux"
+ * End Variables:
+ *
+ */
index 493d850..c4183ab 100644 (file)
@@ -1,16 +1,15 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
+*/
 
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
 
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
+/* Define if you have the <openssl/engine.h> header file.  */
+#undef HAVE_OPENSSL_ENGINE_H
 
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+/* Define if you have the <openssl/err.h> header file.  */
+#undef HAVE_OPENSSL_ERR_H
index af2dd39..81dd2ec 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.12 .
+# From configure.in Revision: 1.9.4.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -875,7 +875,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -2069,6 +2069,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -2107,12 +2112,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index eae6eed..88b62a5 100644 (file)
@@ -4,7 +4,6 @@
 # Version:     $Id$
 #
 
-AC_PREREQ([2.53])
 AC_INIT(rlm_eap_tls.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_eap_tls])
index 080b52f..5792b20 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
- *
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 
 #ifdef HAVE_OPENSSL_RAND_H
 #include <openssl/rand.h>
@@ -34,10 +29,6 @@ RCSID("$Id$")
 
 #include "rlm_eap_tls.h"
 
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
 static CONF_PARSER module_config[] = {
        { "rsa_key_exchange", PW_TYPE_BOOLEAN,
          offsetof(EAP_TLS_CONF, rsa_key), NULL, "no" },
@@ -49,15 +40,15 @@ static CONF_PARSER module_config[] = {
          offsetof(EAP_TLS_CONF, dh_key_length), NULL, "512" },
        { "verify_depth", PW_TYPE_INTEGER,
          offsetof(EAP_TLS_CONF, verify_depth), NULL, "0" },
-       { "CA_path", PW_TYPE_FILENAME,
+       { "CA_path", PW_TYPE_STRING_PTR,
          offsetof(EAP_TLS_CONF, ca_path), NULL, NULL },
        { "pem_file_type", PW_TYPE_BOOLEAN,
          offsetof(EAP_TLS_CONF, file_type), NULL, "yes" },
-       { "private_key_file", PW_TYPE_FILENAME,
+       { "private_key_file", PW_TYPE_STRING_PTR,
          offsetof(EAP_TLS_CONF, private_key_file), NULL, NULL },
-       { "certificate_file", PW_TYPE_FILENAME,
+       { "certificate_file", PW_TYPE_STRING_PTR,
          offsetof(EAP_TLS_CONF, certificate_file), NULL, NULL },
-       { "CA_file", PW_TYPE_FILENAME,
+       { "CA_file", PW_TYPE_STRING_PTR,
          offsetof(EAP_TLS_CONF, ca_file), NULL, NULL },
        { "private_key_password", PW_TYPE_STRING_PTR,
          offsetof(EAP_TLS_CONF, private_key_password), NULL, NULL },
@@ -77,8 +68,6 @@ static CONF_PARSER module_config[] = {
          offsetof(EAP_TLS_CONF, cipher_list), NULL, NULL},
        { "check_cert_issuer", PW_TYPE_STRING_PTR,
          offsetof(EAP_TLS_CONF, check_cert_issuer), NULL, NULL},
-       { "make_cert_command", PW_TYPE_STRING_PTR,
-         offsetof(EAP_TLS_CONF, make_cert_command), NULL, NULL},
 
        { NULL, -1, 0, NULL, NULL }           /* end the list */
 };
@@ -240,7 +229,7 @@ static int cbtls_verify(int ok, X509_STORE_CTX *ctx)
                 *      against the specified value and fail
                 *      verification if they don't match.
                 */
-               if (conf->check_cert_issuer &&
+               if (conf->check_cert_issuer && 
                    (strcmp(issuer, conf->check_cert_issuer) != 0)) {
                        radlog(L_AUTH, "rlm_eap_tls: Certificate issuer (%s) does not match specified value (%s)!", issuer, conf->check_cert_issuer);
                        my_ok = 0;
@@ -337,26 +326,28 @@ static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf)
                radlog(L_INFO, "rlm_eap_tls: Loading the certificate file as a chain");
                if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) {
                        radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-                       radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
+                       radlog(L_ERR, "rlm_eap_tls: Error reading certificate file");
                        return NULL;
                }
 
        } else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) {
                radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-               radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
+               radlog(L_ERR, "rlm_eap_tls: Error reading certificate file");
                return NULL;
        }
 
+
        /* Load the CAs we trust */
        if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
                radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-               radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
+               radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list");
                return NULL;
        }
        SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
+
        if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
                radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
-               radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file);
+               radlog(L_ERR, "rlm_eap_tls: Error reading private key file");
                return NULL;
        }
 
@@ -382,17 +373,13 @@ static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf)
         *      SSL_OP_SINGLE_DH_USE has an impact on the computer
         *      time needed during negotiation, but it is not very
         *      large.
-        */
-       ctx_options |= SSL_OP_SINGLE_DH_USE;
-
-       /*
+        *       
         *      SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS to work around issues
         *      in Windows Vista client.
         *      http://www.openssl.org/~bodo/tls-cbc.txt
         *      http://www.nabble.com/(RADIATOR)-Radiator-Version-3.16-released-t2600070.html
         */
-       ctx_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
-
+       ctx_options |= SSL_OP_SINGLE_DH_USE | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
        SSL_CTX_set_options(ctx, ctx_options);
 
        /*
@@ -473,6 +460,18 @@ static int eaptls_detach(void *arg)
        conf = inst->conf;
 
        if (conf) {
+               free(conf->dh_file);
+               free(conf->ca_path);
+               free(conf->certificate_file);
+               free(conf->private_key_file);
+               free(conf->private_key_password);
+               free(conf->ca_file);
+               free(conf->random_file);
+
+               free(conf->check_cert_cn);
+               free(conf->cipher_list);
+               free(conf->check_cert_issuer);
+
                memset(conf, 0, sizeof(*conf));
                free(inst->conf);
                inst->conf = NULL;
@@ -520,27 +519,6 @@ static int eaptls_attach(CONF_SECTION *cs, void **instance)
                return -1;
        }
 
-       /*
-        *      This magic makes the administrators life HUGELY easier
-        *      on initial deployments.
-        *
-        *      If the server starts up in debugging mode, AND the
-        *      bootstrap command is configured, AND it exists, AND
-        *      there is no server certificate
-        */
-       if (conf->make_cert_command && (debug_flag >= 2)) {
-               struct stat buf;
-
-               if ((stat(conf->make_cert_command, &buf) == 0) &&
-                   (stat(conf->certificate_file, &buf) < 0) &&
-                   (errno == ENOENT) &&
-                   (radius_exec_program(conf->make_cert_command, NULL, 1,
-                                        NULL, 0, NULL, NULL, 0) != 0)) {
-                       eaptls_detach(inst);
-                       return -1;
-               }
-       }
-
 
        /*
         *      Initialize TLS
@@ -592,7 +570,7 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
        eap_tls_t       *inst;
        VALUE_PAIR      *vp;
        int             client_cert = TRUE;
-       int             verify_mode = 0;
+       int             verify_mode = SSL_VERIFY_NONE;
 
        inst = (eap_tls_t *)type_arg;
 
@@ -608,7 +586,7 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
                if (!vp) {
                        client_cert = FALSE;
                } else {
-                       client_cert = vp->vp_integer;
+                       client_cert = vp->lvalue;
                }
        }
 
@@ -662,7 +640,7 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
         */
        ssn->offset = inst->conf->fragment_size;
        vp = pairfind(handler->request->packet->vps, PW_FRAMED_MTU);
-       if (vp && ((vp->vp_integer - 14) < ssn->offset)) {
+       if (vp && ((vp->lvalue - 14) < ssn->offset)) {
                /*
                 *      Discount the Framed-MTU by:
                 *       4 : EAPOL header
@@ -675,7 +653,7 @@ static int eaptls_initiate(void *type_arg, EAP_HANDLER *handler)
                 *      ---
                 *      14
                 */
-               ssn->offset = vp->vp_integer - 14;
+               ssn->offset = vp->lvalue - 14;
        }
 
        handler->opaque = ((void *)ssn);
index 00279a1..52f3ef2 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
  * Copyright 2003  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
  */
 #ifndef _RLM_EAP_TLS_H
 #define _RLM_EAP_TLS_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rlm_eap_tls_h, "$Id$")
-
 #include "eap_tls.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "radiusd.h"
+#include "modules.h"
 
 /* configured values goes right here */
 typedef struct eap_tls_conf {
@@ -42,7 +38,6 @@ typedef struct eap_tls_conf {
        char            *ca_file;
        char            *dh_file;
        char            *rsa_file;
-       char            *make_cert_command;
        int             rsa_key;
        int             dh_key;
        int             rsa_key_length;
index 493d850..c4183ab 100644 (file)
@@ -1,16 +1,15 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
+*/
 
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
 
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
+/* Define if you have the <openssl/engine.h> header file.  */
+#undef HAVE_OPENSSL_ENGINE_H
 
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+/* Define if you have the <openssl/err.h> header file.  */
+#undef HAVE_OPENSSL_ERR_H
index 7d48a62..7daf874 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.8 .
+# From configure.in Revision: 1.5.4.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -875,7 +875,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -2069,6 +2069,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -2107,12 +2112,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 942acdd..f233a0b 100644 (file)
@@ -4,7 +4,6 @@
 # Version:     $Id$
 #
 
-AC_PREREQ([2.53])
 AC_INIT(rlm_eap_ttls.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_eap_ttls])
index 30ebf85..e255037 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003 Alan DeKok <aland@freeradius.org>
- * Copyright 2006 The FreeRADIUS server project
  */
 #ifndef _EAP_TTLS_H
 #define _EAP_TTLS_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(eap_ttls_h, "$Id$")
-
 #include "eap_tls.h"
 
 typedef struct ttls_tunnel_t {
index 8b08930..7cd8eb7 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2003 Alan DeKok <aland@freeradius.org>
- * Copyright 2006 The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/autoconf.h>
+#include "autoconf.h"
 #include "eap_ttls.h"
 
 
@@ -69,6 +65,7 @@ static int eapttls_detach(void *arg)
 {
        rlm_eap_ttls_t *inst = (rlm_eap_ttls_t *) arg;
 
+       if (inst->default_eap_type_name) free(inst->default_eap_type_name);
 
        free(inst);
 
@@ -140,7 +137,7 @@ static void ttls_free(void *p)
 
        if (t->username) {
                DEBUG2("  TTLS: Freeing handler for user %s",
-                      t->username->vp_strvalue);
+                      t->username->strvalue);
        }
 
        pairfree(&t->username);
index 7acfdad..8a00ec8 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *   Copyright 2003 Alan DeKok <aland@freeradius.org>
- *   Copyright 2006 The FreeRADIUS server project
  */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include "eap_ttls.h"
 
 /*
@@ -128,7 +123,7 @@ static int diameter_verify(const uint8_t *data, unsigned int data_len)
                        DEBUG2("  rlm_eap_ttls: Tunneled attribute %d is too long (%d) to pack into a RADIUS attribute.", attr, length);
                        return 0;
                }
-
+                   
                if (length > data_left) {
                        DEBUG2("  rlm_eap_ttls: Tunneled attribute %d is longer than room left in the packet (%d > %d).", attr, length, data_left);
                        return 0;
@@ -159,7 +154,7 @@ static int diameter_verify(const uint8_t *data, unsigned int data_len)
                        DEBUG2("  rlm_eap_ttls: ERROR! Diameter attribute overflows packet!");
                        return 0;
                }
-
+       
                /*
                 *      Check again for equality, now that we're padded
                 *      length to a multiple of 4 octets.
@@ -267,14 +262,14 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                                pairfree(&vp);
                                return NULL;
                        }
-                       memcpy(&vp->vp_integer, data, vp->length);
-
+                       memcpy(&vp->lvalue, data, vp->length);
+                       
                        /*
                         *      Stored in host byte order: change it.
                         */
-                       vp->vp_integer = ntohl(vp->vp_integer);
+                       vp->lvalue = ntohl(vp->lvalue);
                        break;
-
+                       
                case PW_TYPE_IPADDR:
                        if (size != vp->length) {
                                DEBUG2("  rlm_eap_ttls: Invalid length attribute %d",
@@ -283,8 +278,8 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                                pairfree(&vp);
                                return NULL;
                        }
-                 memcpy(&vp->vp_ipaddr, data, vp->length);
-
+                 memcpy(&vp->lvalue, data, vp->length);
+                 
                  /*
                   *    Stored in network byte order: don't change it.
                   */
@@ -299,7 +294,7 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                   */
                default:
                        vp->length = size;
-                       memcpy(vp->vp_strvalue, data, vp->length);
+                       memcpy(vp->strvalue, data, vp->length);
                        break;
                }
 
@@ -319,8 +314,8 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                         *      If the password is exactly 16 octets,
                         *      it won't be zero-terminated.
                         */
-                       vp->vp_strvalue[vp->length] = '\0';
-                       vp->length = strlen(vp->vp_strvalue);
+                       vp->strvalue[vp->length] = '\0';
+                       vp->length = strlen(vp->strvalue);
                        break;
 
                        /*
@@ -360,7 +355,7 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                                eapttls_gen_challenge(ssl, challenge,
                                                      sizeof(challenge));
 
-                               if (memcmp(challenge, vp->vp_octets,
+                               if (memcmp(challenge, vp->strvalue,
                                           vp->length) != 0) {
                                        DEBUG2("  TTLS: Tunneled challenge is incorrect");
                                        pairfree(&first);
@@ -492,20 +487,21 @@ static int vp2diameter(tls_session_t *tls_session, VALUE_PAIR *first)
                switch (vp->type) {
                case PW_TYPE_INTEGER:
                case PW_TYPE_DATE:
-                       attr = ntohl(vp->vp_integer); /* stored in host order */
+                       attr = ntohl(vp->lvalue); /* stored in host order */
                        memcpy(p, &attr, sizeof(attr));
                        length = 4;
                        break;
 
                case PW_TYPE_IPADDR:
-                       memcpy(p, &vp->vp_ipaddr, 4); /* network order */
+                       attr = vp->lvalue; /* stored in network order */
+                       memcpy(p, &attr, sizeof(attr));
                        length = 4;
                        break;
 
                case PW_TYPE_STRING:
                case PW_TYPE_OCTETS:
                default:
-                       memcpy(p, vp->vp_strvalue, vp->length);
+                       memcpy(p, vp->strvalue, vp->length);
                        length = vp->length;
                        break;
                }
@@ -617,7 +613,7 @@ static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
                        DEBUG2("  TTLS: Got MS-CHAP2-Success, tunneling it to the client in a challenge.");
                        rcode = RLM_MODULE_HANDLED;
                        t->authenticated = TRUE;
-
+                       
                        /*
                         *      Delete MPPE keys & encryption policy.  We don't
                         *      want these here.
@@ -626,7 +622,7 @@ static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
                        pairdelete(&reply->vps, ((311 << 16) | 8));
                        pairdelete(&reply->vps, ((311 << 16) | 16));
                        pairdelete(&reply->vps, ((311 << 16) | 17));
-
+                       
                        /*
                         *      Use the tunneled reply, but not now.
                         */
@@ -754,7 +750,7 @@ static int eapttls_postproxy(EAP_HANDLER *handler, void *data)
        fake = (REQUEST *) request_data_get(handler->request,
                                            handler->request->proxy,
                                            REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK);
-
+       
        /*
         *      Do the callback, if it exists, and if it was a success.
         */
@@ -785,7 +781,7 @@ static int eapttls_postproxy(EAP_HANDLER *handler, void *data)
                if (debug_flag > 0) {
                        printf("  TTLS: Final reply from tunneled session code %d\n",
                               fake->reply->code);
-
+                       
                        for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {
                                putchar('\t');vp_print(stdout, vp);putchar('\n');
                        }
@@ -810,12 +806,12 @@ static int eapttls_postproxy(EAP_HANDLER *handler, void *data)
                        eaptls_fail(handler->eap_ds, 0);
                        return 0;
                        break;
-
+                       
                 default:  /* Don't Do Anything */
                        DEBUG2(" TTLS: Got reply %d",
                               request->proxy_reply->code);
                        break;
-               }
+               }       
        }
        request_free(&fake);    /* robust if fake == NULL */
 
@@ -992,7 +988,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
 #ifndef NDEBUG
        if (debug_flag > 0) {
                printf("  TTLS: Got tunneled request\n");
-
+               
                for (vp = fake->packet->vps; vp != NULL; vp = vp->next) {
                        putchar('\t');vp_print(stdout, vp);putchar('\n');
                }
@@ -1003,7 +999,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
         *      Update other items in the REQUEST data structure.
         */
        fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
-       fake->password = pairfind(fake->packet->vps, PW_USER_PASSWORD);
+       fake->password = pairfind(fake->packet->vps, PW_PASSWORD);
 
        /*
         *      No User-Name, try to create one from stored data.
@@ -1017,22 +1013,22 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                        vp = pairfind(fake->packet->vps, PW_EAP_MESSAGE);
                        if (vp &&
                            (vp->length >= EAP_HEADER_LEN + 2) &&
-                           (vp->vp_strvalue[0] == PW_EAP_RESPONSE) &&
-                           (vp->vp_strvalue[EAP_HEADER_LEN] == PW_EAP_IDENTITY) &&
-                           (vp->vp_strvalue[EAP_HEADER_LEN + 1] != 0)) {
+                           (vp->strvalue[0] == PW_EAP_RESPONSE) &&
+                           (vp->strvalue[EAP_HEADER_LEN] == PW_EAP_IDENTITY) &&
+                           (vp->strvalue[EAP_HEADER_LEN + 1] != 0)) {
                                /*
                                 *      Create & remember a User-Name
                                 */
                                t->username = pairmake("User-Name", "", T_OP_EQ);
                                rad_assert(t->username != NULL);
 
-                               memcpy(t->username->vp_strvalue, vp->vp_strvalue + 5,
+                               memcpy(t->username->strvalue, vp->strvalue + 5,
                                       vp->length - 5);
                                t->username->length = vp->length - 5;
-                               t->username->vp_strvalue[t->username->length] = 0;
+                               t->username->strvalue[t->username->length] = 0;
 
                                DEBUG2("  TTLS: Got tunneled identity of %s",
-                                      t->username->vp_strvalue);
+                                      t->username->strvalue);
 
                                /*
                                 *      If there's a default EAP type,
@@ -1043,7 +1039,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                                        vp = paircreate(PW_EAP_TYPE,
                                                        PW_TYPE_INTEGER);
                                        rad_assert(vp != NULL);
-                                       vp->vp_integer = t->default_eap_type;
+                                       vp->lvalue = t->default_eap_type;
                                        pairadd(&fake->config_items, vp);
                                }
 
@@ -1069,7 +1065,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
         */
        if (t->state) {
                DEBUG2("  TTLS: Adding old state with %02x %02x",
-                      t->state->vp_strvalue[0], t->state->vp_strvalue[1]);
+                      t->state->strvalue[0], t->state->strvalue[1]);
                vp = paircopy(t->state);
                if (vp) pairadd(&fake->packet->vps, vp);
        }
@@ -1182,7 +1178,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                vp = pairfind(fake->config_items, PW_PROXY_TO_REALM);
                if (vp) {
                        eap_tunnel_data_t *tunnel;
-                       DEBUG2("  TTLS: Tunneled authentication will be proxied to %s", vp->vp_strvalue);
+                       DEBUG2("  TTLS: Tunneled authentication will be proxied to %s", vp->strvalue);
 
                        /*
                         *      Tell the original request that it's going
@@ -1219,7 +1215,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                                                 REQUEST_DATA_EAP_TUNNEL_CALLBACK,
                                                 tunnel, free);
                        rad_assert(rcode == 0);
-
+                       
                        /*
                         *      rlm_eap.c has taken care of associating
                         *      the handler with the fake request.
@@ -1258,15 +1254,15 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                case RLM_MODULE_REJECT:
                        rcode = PW_AUTHENTICATION_REJECT;
                        break;
-
+                       
                case RLM_MODULE_HANDLED:
                        rcode = PW_ACCESS_CHALLENGE;
                        break;
-
+                       
                case RLM_MODULE_OK:
                        rcode = PW_AUTHENTICATION_ACK;
                        break;
-
+                       
                default:
                        rcode = PW_AUTHENTICATION_REJECT;
                        break;
index 7c783cc..221545f 100644 (file)
@@ -1,52 +1,18 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+*/
 
-/* Define to 1 if you have the `printf' function. */
-#undef HAVE_PRINTF
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
+/* Define if you have the printf function.  */
+#undef HAVE_PRINTF
 
-/* Define to 1 if you have the <stdio.h> header file. */
+/* Define if you have the <stdio.h> header file.  */
 #undef HAVE_STDIO_H
 
-/* Define to 1 if you have the <stdlib.h> header file. */
+/* Define if you have the <stdlib.h> header file.  */
 #undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
index e5a101f..59317ad 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.6 .
+# From configure.in Revision: 1.5 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -938,7 +938,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1284,9 +1284,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
- # change 'example'
 # change 'example'
 
- # change 'example'
 # change 'example'
 
 if test x$with_rlm_example != xno; then
 
@@ -1858,7 +1858,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1916,7 +1917,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2032,7 +2034,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2086,7 +2089,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2131,7 +2135,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2175,7 +2180,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2488,7 +2494,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2570,7 +2577,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2740,7 +2748,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2803,7 +2812,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2953,7 +2963,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3137,7 +3148,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3985,6 +3997,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4023,12 +4040,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index cb2017c..947b56d 100644 (file)
@@ -1,14 +1,13 @@
-AC_PREREQ([2.53])
-AC_INIT(rlm_example.c) # change 'example'
+AC_INIT(rlm_example.c)  # change 'example'
 AC_REVISION($Revision$)
-AC_DEFUN(modname,[rlm_example]) # change 'example'
+AC_DEFUN(modname,[rlm_example])  # change 'example'
 
 if test x$with_[]modname != xno; then
 
        AC_PROG_CC
        AC_PROG_CPP
 
-       dnl put configuration checks here.
+       dnl put configuration checks here.  
        dnl set $fail to what's missing, on fatal errors.
        dnl use AC_MSG_WARN() on important messages.
        AC_CHECK_LIB(c, printf,
@@ -36,7 +35,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index 6a2db8e..b37ecf6 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  your name <your address>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <stdio.h>
 
 #include "other.h"
index c41a726..8fd691e 100644 (file)
@@ -1,11 +1,6 @@
-/* Copyright 2006 The FreeRADIUS server project */
-
 #ifndef _OTHER_H
 #define _OTHER_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(other_h, "$Id$")
-
 /* define the function */
 
 void other_function(void);
index 5462062..ebbe968 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  your name <your address>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
 
 /*
  *     Define a structure for our module configuration.
@@ -50,7 +56,7 @@ typedef struct rlm_example_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "integer", PW_TYPE_INTEGER,    offsetof(rlm_example_t,value), NULL,   "1" },
   { "boolean", PW_TYPE_BOOLEAN,    offsetof(rlm_example_t,boolean), NULL, "no"},
   { "string",  PW_TYPE_STRING_PTR, offsetof(rlm_example_t,string), NULL,  NULL},
@@ -59,6 +65,21 @@ static const CONF_PARSER module_config[] = {
   { NULL, -1, 0, NULL, NULL }          /* end the list */
 };
 
+/*
+ *     Do any per-module initialization.  e.g. set up connections
+ *     to external databases, read configuration files, set up
+ *     dictionary entries, etc.
+ *
+ *     Try to avoid putting too much stuff in here - it's better to
+ *     do it in instantiate() where it is not global.
+ */
+static int example_init(void)
+{
+       /*
+        *      Everything's OK, return without an error.
+        */
+       return 0;
+}
 
 /*
  *     Do any per-module initialization that is separate to each
@@ -195,13 +216,9 @@ static int example_checksimul(void *instance, REQUEST *request)
   return RLM_MODULE_OK;
 }
 
-
-/*
- *     Only free memory we allocated.  The strings allocated via
- *     cf_section_parse() do not need to be freed.
- */
 static int example_detach(void *instance)
 {
+       free(((struct rlm_example_t *)instance)->string);
        free(instance);
        return 0;
 }
@@ -216,11 +233,10 @@ static int example_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_example = {
-       RLM_MODULE_INIT,
        "example",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       example_init,                   /* initialization */
        example_instantiate,            /* instantiation */
-       example_detach,                 /* detach */
        {
                example_authenticate,   /* authentication */
                example_authorize,      /* authorization */
@@ -231,4 +247,6 @@ module_t rlm_example = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       example_detach,                 /* detach */
+       NULL,                           /* destroy */
 };
index adfecde..9c69504 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * rlm_exec.c
+ * rlm_exe.c
  *
  * Version:    $Id$
  *
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
 
 /*
  *     Define a structure for our module configuration.
@@ -37,8 +44,7 @@ typedef struct rlm_exec_t {
        char    *input;
        char    *output;
        char    *packet_type;
-       unsigned int    packet_code;
-       int     shell_escape;
+       int     packet_code;
 } rlm_exec_t;
 
 /*
@@ -50,7 +56,7 @@ typedef struct rlm_exec_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        { "wait", PW_TYPE_BOOLEAN,  offsetof(rlm_exec_t,wait), NULL, "yes" },
        { "program",  PW_TYPE_STRING_PTR,
          offsetof(rlm_exec_t,program), NULL, NULL },
@@ -60,7 +66,6 @@ static const CONF_PARSER module_config[] = {
          offsetof(rlm_exec_t,output), NULL, NULL },
        { "packet_type", PW_TYPE_STRING_PTR,
          offsetof(rlm_exec_t,packet_type), NULL, NULL },
-       { "shell_escape", PW_TYPE_BOOLEAN,  offsetof(rlm_exec_t,shell_escape), NULL, "yes" },
        { NULL, -1, 0, NULL, NULL }             /* end the list */
 };
 
@@ -115,8 +120,8 @@ static VALUE_PAIR **decode_string(REQUEST *request, const char *string)
  *     Do xlat of strings.
  */
 static int exec_xlat(void *instance, REQUEST *request,
-                    char *fmt, char *out, size_t outlen,
-                    UNUSED RADIUS_ESCAPE_STRING func)
+                    char *fmt, char *out, int outlen,
+                    RADIUS_ESCAPE_STRING func)
 {
        int             result;
        rlm_exec_t      *inst = instance;
@@ -135,7 +140,7 @@ static int exec_xlat(void *instance, REQUEST *request,
         */
        DEBUG2("rlm_exec (%s): Executing %s", inst->xlat_name, fmt);
        result = radius_exec_program(fmt, request, inst->wait,
-                                    out, outlen, *input_pairs, NULL, inst->shell_escape);
+                                    out, outlen, *input_pairs, NULL);
        DEBUG2("rlm_exec (%s): result %d", inst->xlat_name, result);
        if (result != 0) {
                out[0] = '\0';
@@ -158,6 +163,14 @@ static int exec_detach(void *instance)
                free(inst->xlat_name);
        }
 
+       /*
+        *  Free the strings.
+        */
+       if (inst->program) free(inst->program);
+       if (inst->input) free(inst->input);
+       if (inst->output) free(inst->output);
+       if (inst->packet_type) free(inst->packet_type);
+
        free(inst);
        return 0;
 }
@@ -176,7 +189,7 @@ static int exec_detach(void *instance)
 static int exec_instantiate(CONF_SECTION *conf, void **instance)
 {
        rlm_exec_t      *inst;
-       const char      *xlat_name;
+       char            *xlat_name;
 
        /*
         *      Set up a storage area for instance data
@@ -223,7 +236,7 @@ static int exec_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (inst->wait &&
            (inst->output == NULL)) {
-               radlog(L_INFO, "rlm_exec: wait=yes but no output defined. Did you mean output=none?");
+               radlog(L_INFO, "rlm_exec: Wait=yes but no output defined. Did you mean output=none?");
        }
 
        /*
@@ -263,7 +276,7 @@ static int exec_instantiate(CONF_SECTION *conf, void **instance)
 static int exec_dispatch(void *instance, REQUEST *request)
 {
        int result;
-       VALUE_PAIR **input_pairs, **output_pairs;
+       VALUE_PAIR **input_pairs, **output_pairs, *in;
        VALUE_PAIR *answer;
        rlm_exec_t *inst = (rlm_exec_t *) instance;
 
@@ -301,8 +314,11 @@ static int exec_dispatch(void *instance, REQUEST *request)
         *      It points to the attribute list, but the attribute
         *      list is empty.
         */
-       if (input_pairs && !*input_pairs) {
+       if (!input_pairs || (input_pairs && !*input_pairs)) {
                DEBUG2("rlm_exec (%s): WARNING! Input pairs are empty.  No attributes will be passed to the script", inst->xlat_name);
+               in = NULL;
+       } else {
+               in = *input_pairs;
        }
 
        /*
@@ -318,8 +334,8 @@ static int exec_dispatch(void *instance, REQUEST *request)
         */
        result = radius_exec_program(inst->program, request,
                                     inst->wait, NULL, 0,
-                                    *input_pairs, &answer, inst->shell_escape);
-       if (result < 0) {
+                                    in, &answer);
+       if (result != 0) {
                radlog(L_ERR, "rlm_exec (%s): External script failed",
                       inst->xlat_name);
                return RLM_MODULE_FAIL;
@@ -334,79 +350,11 @@ static int exec_dispatch(void *instance, REQUEST *request)
 
        pairfree(&answer);
 
-       if (result == 0) {
-               return RLM_MODULE_OK;
-       }
-       if (result > RLM_MODULE_NUMCODES) {
-               return RLM_MODULE_FAIL;
-       }
-       return result-1;
+       return RLM_MODULE_OK;
 }
 
 
 /*
- *     First, look for Exec-Program && Exec-Program-Wait.
- *
- *     Then, call exec_dispatch.
- */
-static int exec_postauth(void *instance, REQUEST *request)
-{
-       int result;
-       int exec_wait = 0;
-       VALUE_PAIR *vp, *tmp;
-       rlm_exec_t *inst = (rlm_exec_t *) instance;
-
-       vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM);
-       if (vp) {
-               exec_wait = 0;
-
-       } else if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) {
-               exec_wait = 1;
-       }
-       if (!vp) goto dispatch;
-
-       tmp = NULL;
-       result = radius_exec_program(vp->vp_strvalue, request, exec_wait,
-                                    NULL, 0, request->packet->vps, &tmp,
-                                    inst->shell_escape);
-
-       /*
-        *      Always add the value-pairs to the reply.
-        */
-       pairmove(&request->reply->vps, &tmp);
-       pairfree(&tmp);
-
-       if (result < 0) {
-               /*
-                *      Error. radius_exec_program() returns -1 on
-                *      fork/exec errors.
-                */
-               tmp = pairmake("Reply-Message", "Access denied (external check failed)", T_OP_SET);
-               pairadd(&request->reply->vps, tmp);
-
-               DEBUG2("Login incorrect (external check failed)");
-
-               request->reply->code = PW_AUTHENTICATION_REJECT;
-               return RLM_MODULE_REJECT;
-       }
-       if (result > 0) {
-               /*
-                *      Reject. radius_exec_program() returns >0
-                *      if the exec'ed program had a non-zero
-                *      exit status.
-                */
-               request->reply->code = PW_AUTHENTICATION_REJECT;
-               DEBUG2("Login incorrect (external check said so)");
-               return RLM_MODULE_REJECT;
-       }
-
- dispatch:
-       if (!inst->program) return RLM_MODULE_NOOP;
-
-       return exec_dispatch(instance, request);
-}
-
-/*
  *     The module name should be the only globally exported symbol.
  *     That is, everything else should be 'static'.
  *
@@ -416,11 +364,10 @@ static int exec_postauth(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_exec = {
-       RLM_MODULE_INIT,
        "exec",                         /* Name */
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        exec_instantiate,               /* instantiation */
-       exec_detach,                    /* detach */
        {
                exec_dispatch,          /* authentication */
                exec_dispatch,          /* authorization */
@@ -429,6 +376,8 @@ module_t rlm_exec = {
                NULL,                   /* check simul */
                exec_dispatch,          /* pre-proxy */
                exec_dispatch,          /* post-proxy */
-               exec_postauth           /* post-auth */
+               exec_dispatch           /* post-auth */
        },
+       exec_detach,                    /* detach */
+       NULL,                           /* destroy */
 };
diff --git a/src/modules/rlm_expiration/Makefile b/src/modules/rlm_expiration/Makefile
deleted file mode 100644 (file)
index 77a5aad..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-TARGET  = rlm_expiration
-SRCS    = rlm_expiration.c
-
-include ../rules.mak
diff --git a/src/modules/rlm_expiration/rlm_expiration.c b/src/modules/rlm_expiration/rlm_expiration.c
deleted file mode 100644 (file)
index 0464e18..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * rlm_expiration.c
- *
- * Version:  $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2001,2006  The FreeRADIUS server project
- * Copyright 2004  Kostas Kalevras <kkalev@noc.ntua.gr>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-#include <ctype.h>
-
-/*
- *     Define a structure for our module configuration.
- *
- *     These variables do not need to be in a structure, but it's
- *     a lot cleaner to do so, and a pointer to the structure can
- *     be used as the instance handle.
- */
-typedef struct rlm_expiration_t {
-       char *msg;              /* The Reply-Message passed back to the user if the account is expired */
-} rlm_expiration_t;
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-  { "reply-message", PW_TYPE_STRING_PTR, offsetof(rlm_expiration_t,msg),
-    NULL, "Password Has Expired\r\n"},
-  { NULL, -1, 0, NULL, NULL }
-};
-
-/*
- *      Check if account has expired, and if user may login now.
- */
-static int expiration_authorize(void *instance, REQUEST *request)
-{
-       rlm_expiration_t *data = (rlm_expiration_t *)instance;
-       VALUE_PAIR *vp, *check_item = NULL;
-       char msg[MAX_STRING_LEN];
-
-       if ((check_item = pairfind(request->config_items, PW_EXPIRATION)) != NULL){
-               /*
-               *      Has this user's password expired?
-               *
-               *      If so, remove ALL reply attributes,
-               *      and add our own Reply-Message, saying
-               *      why they're being rejected.
-               */
-               DEBUG("rlm_expiration: Checking Expiration time: '%s'",check_item->vp_strvalue);
-               if (((time_t) check_item->vp_date) <= request->timestamp) {
-                       char logstr[MAX_STRING_LEN];
-                       VALUE_PAIR *module_fmsg_vp;
-
-                       DEBUG("rlm_expiration: Account has expired");
-
-                       if (data->msg && data->msg[0]){
-                               if (!radius_xlat(msg, sizeof(msg), data->msg, request, NULL)) {
-                                       radlog(L_ERR, "rlm_expiration: xlat failed.");
-                                       return RLM_MODULE_FAIL;
-                               }
-
-                               vp = pairmake("Reply-Message", msg, T_OP_ADD);
-                               pairfree(&request->reply->vps);
-                               request->reply->vps = vp;
-                       }
-                        snprintf(logstr, sizeof(logstr), "Account has expired [Expiration %s]",check_item->vp_strvalue);
-                        module_fmsg_vp = pairmake("Module-Failure-Message", logstr, T_OP_EQ);
-                        pairadd(&request->packet->vps, module_fmsg_vp);
-
-                       return RLM_MODULE_USERLOCK;
-               }
-               /*
-                *      Else the account hasn't expired, but it may do so
-                *      in the future.  Set Session-Timeout.
-                */
-               vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT);
-               if (!vp) {
-                       vp = radius_paircreate(request, &request->reply->vps,
-                                              PW_SESSION_TIMEOUT,
-                                              PW_TYPE_INTEGER);
-                       vp->vp_date = (uint32_t) (((time_t) check_item->vp_date) - request->timestamp);
-
-               } else if (vp->vp_date > ((uint32_t) (((time_t) check_item->vp_date) - request->timestamp))) {
-                       vp->vp_date = (uint32_t) (((time_t) check_item->vp_date) - request->timestamp);
-               }
-       }
-       else
-               return RLM_MODULE_NOOP;
-
-       return RLM_MODULE_OK;
-}
-
-/*
- *      Compare the expiration date.
- */
-static int expirecmp(void *instance, REQUEST *req,
-               VALUE_PAIR *request, VALUE_PAIR *check,
-               VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
-{
-       time_t now = 0;
-       instance = instance;
-       request = request;      /* shut the compiler up */
-       check_pairs = check_pairs;
-       reply_pairs = reply_pairs;
-
-       now = (req) ? req->timestamp : time(NULL);
-
-       if (now <= ((time_t) check->vp_date))
-               return 0;
-       return +1;
-}
-
-
-static int expiration_detach(void *instance)
-{
-       paircompare_unregister(PW_EXPIRATION, expirecmp);
-       free(instance);
-       return 0;
-}
-
-/*
- *     Do any per-module initialization that is separate to each
- *     configured instance of the module.  e.g. set up connections
- *     to external databases, read configuration files, set up
- *     dictionary entries, etc.
- *
- *     If configuration information is given in the config section
- *     that must be referenced in later calls, store a handle to it
- *     in *instance otherwise put a null pointer there.
- */
-static int expiration_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_expiration_t *data;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       data = rad_malloc(sizeof(*data));
-       if (!data) {
-               radlog(L_ERR, "rlm_expiration: rad_malloc() failed.");
-               return -1;
-       }
-       memset(data, 0, sizeof(*data));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, data, module_config) < 0) {
-               free(data);
-               radlog(L_ERR, "rlm_expiration: Configuration parsing failed.");
-               return -1;
-       }
-
-       /*
-        * Register the expiration comparison operation.
-        */
-       paircompare_register(PW_EXPIRATION, 0, expirecmp, data);
-
-       *instance = data;
-
-       return 0;
-}
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- *
- *     If the module needs to temporarily modify it's instantiation
- *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
- *     The server will then take care of ensuring that the module
- *     is single-threaded.
- */
-module_t rlm_expiration = {
-       RLM_MODULE_INIT,
-       "expiration",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       expiration_instantiate,         /* instantiation */
-       expiration_detach,              /* detach */
-       {
-               NULL,                   /* authentication */
-               expiration_authorize,   /* authorization */
-               NULL,                   /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
-};
index fc22730..cd78ffa 100644 (file)
@@ -5,6 +5,6 @@
 #
 
 TARGET         = rlm_expr
-SRCS           = rlm_expr.c paircmp.c
+SRCS           = rlm_expr.c
 
 include ../rules.mak
diff --git a/src/modules/rlm_expr/paircmp.c b/src/modules/rlm_expr/paircmp.c
deleted file mode 100644 (file)
index 60ff75d..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * paircmp.c   Valuepair functions for various attributes
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2000,2006  The FreeRADIUS server project
- * Copyright 2000  Alan DeKok <aland@ox.org>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
-/*
- *     Compare a Connect-Info and a Connect-Rate
- */
-static int connectcmp(void *instance,
-                     REQUEST *req UNUSED,
-                     VALUE_PAIR *request,
-                     VALUE_PAIR *check,
-                     VALUE_PAIR *check_pairs,
-                     VALUE_PAIR **reply_pairs)
-{
-       int rate;
-
-       instance = instance;
-       check_pairs = check_pairs; /* shut the compiler up */
-       reply_pairs = reply_pairs;
-
-       rate = atoi((char *)request->vp_strvalue);
-       return rate - check->vp_integer;
-}
-
-
-/*
- *     Compare a portno with a range.
- */
-static int portcmp(void *instance,
-                  REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check,
-       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
-{
-       char buf[MAX_STRING_LEN];
-       char *s, *p;
-       uint32_t lo, hi;
-       uint32_t port = request->vp_integer;
-
-       instance = instance;
-       check_pairs = check_pairs; /* shut the compiler up */
-       reply_pairs = reply_pairs;
-
-       if ((strchr((char *)check->vp_strvalue, ',') == NULL) &&
-                       (strchr((char *)check->vp_strvalue, '-') == NULL)) {
-               return (request->vp_integer - check->vp_integer);
-       }
-
-       /* Same size */
-       strcpy(buf, (char *)check->vp_strvalue);
-       s = strtok(buf, ",");
-
-       while (s != NULL) {
-               if ((p = strchr(s, '-')) != NULL)
-                       p++;
-               else
-                       p = s;
-               lo = strtoul(s, NULL, 10);
-               hi = strtoul(p, NULL, 10);
-               if (lo <= port && port <= hi) {
-                       return 0;
-               }
-               s = strtok(NULL, ",");
-       }
-
-       return -1;
-}
-
-/*
- *     Compare prefix/suffix.
- *
- *     If they compare:
- *     - if PW_STRIP_USER_NAME is present in check_pairs,
- *       strip the username of prefix/suffix.
- *     - if PW_STRIP_USER_NAME is not present in check_pairs,
- *       add a PW_STRIPPED_USER_NAME to the request.
- */
-static int presufcmp(void *instance,
-                    REQUEST *req,
-                    VALUE_PAIR *request, VALUE_PAIR *check,
-       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
-{
-       VALUE_PAIR *vp;
-       char *name = (char *)request->vp_strvalue;
-       char rest[MAX_STRING_LEN];
-       int len, namelen;
-       int ret = -1;
-
-       instance = instance;
-       reply_pairs = reply_pairs; /* shut the compiler up */
-
-#if 0 /* DEBUG */
-       printf("Comparing %s and %s, check->attr is %d\n",
-               name, check->vp_strvalue, check->attribute);
-#endif
-
-       len = strlen((char *)check->vp_strvalue);
-       switch (check->attribute) {
-               case PW_PREFIX:
-                       ret = strncmp(name, (char *)check->vp_strvalue, len);
-                       if (ret == 0 && rest)
-                               strcpy(rest, name + len);
-                       break;
-               case PW_SUFFIX:
-                       namelen = strlen(name);
-                       if (namelen < len)
-                               break;
-                       ret = strcmp(name + namelen - len,
-                                       (char *)check->vp_strvalue);
-                       if (ret == 0 && rest) {
-                               strlcpy(rest, name, namelen - len + 1);
-                       }
-                       break;
-       }
-       if (ret != 0)
-               return ret;
-
-       /*
-        *      If Strip-User-Name == No, then don't do any more.
-        */
-       vp = pairfind(check_pairs, PW_STRIP_USER_NAME);
-       if (vp && !vp->vp_integer) return ret;
-
-       /*
-        *      See where to put the stripped user name.
-        */
-       vp = pairfind(check_pairs, PW_STRIPPED_USER_NAME);
-       if (!vp) {
-               /*
-                *      If "request" is NULL, then the memory will be
-                *      lost!
-                */
-               vp = radius_paircreate(req, &request,
-                                      PW_STRIPPED_USER_NAME, PW_TYPE_STRING);
-       }
-
-       strlcpy((char *)vp->vp_strvalue, rest, sizeof(vp->vp_strvalue));
-       vp->length = strlen(vp->vp_strvalue);
-
-       return ret;
-}
-
-
-/*
- *     Compare the request packet type.
- */
-static int packetcmp(void *instance UNUSED, REQUEST *req,
-                    VALUE_PAIR *request UNUSED,
-                    VALUE_PAIR *check,
-                    VALUE_PAIR *check_pairs UNUSED,
-                    VALUE_PAIR **reply_pairs UNUSED)
-{
-       if (req->packet->code == check->vp_integer) {
-               return 0;
-       }
-
-       return 1;
-}
-
-/*
- *     Compare the response packet type.
- */
-static int responsecmp(void *instance UNUSED,
-                      REQUEST *req,
-                      VALUE_PAIR *request UNUSED,
-                      VALUE_PAIR *check,
-                      VALUE_PAIR *check_pairs UNUSED,
-                      VALUE_PAIR **reply_pairs UNUSED)
-{
-       if (req->reply->code == check->vp_integer) {
-               return 0;
-       }
-
-       return 1;
-}
-
-/*
- *     Generic comparisons, via xlat.
- */
-static int genericcmp(void *instance UNUSED,
-                     REQUEST *req,
-                     VALUE_PAIR *request UNUSED,
-                     VALUE_PAIR *check,
-                     VALUE_PAIR *check_pairs UNUSED,
-                     VALUE_PAIR **reply_pairs UNUSED)
-{
-       if ((check->operator != T_OP_REG_EQ) &&
-           (check->operator != T_OP_REG_EQ)) {
-               int rcode;
-               char name[1024];
-               char value[1024];
-               VALUE_PAIR *vp;
-
-               snprintf(name, sizeof(name), "%%{%s}", check->name);
-
-               rcode = radius_xlat(value, sizeof(value), name, req, NULL);
-               vp = pairmake(check->name, value, T_OP_EQ);
-
-               rcode = radius_compare_vps(req, check, vp);
-               pairfree(&vp);
-
-               return rcode;
-       }
-
-       /*
-        *      Will do the xlat for us
-        */
-       return radius_compare_vps(req, check, NULL);
-}
-
-static int generic_attrs[] = {
-       PW_CLIENT_IP_ADDRESS,
-       PW_PACKET_SRC_IP_ADDRESS,
-       PW_PACKET_DST_IP_ADDRESS,
-       PW_PACKET_SRC_PORT,
-       PW_PACKET_DST_PORT,
-       PW_REQUEST_PROCESSING_STAGE,
-       PW_PACKET_SRC_IPV6_ADDRESS,
-       PW_PACKET_DST_IPV6_ADDRESS,
-       PW_SERVER_IDENTITY,
-       0
-};
-
-/*
- *     Register server-builtin special attributes.
- */
-void pair_builtincompare_init(void)
-{
-       int i;
-
-       paircompare_register(PW_NAS_PORT, PW_NAS_PORT, portcmp, NULL);
-       paircompare_register(PW_PREFIX, PW_USER_NAME, presufcmp, NULL);
-       paircompare_register(PW_SUFFIX, PW_USER_NAME, presufcmp, NULL);
-       paircompare_register(PW_CONNECT_RATE, PW_CONNECT_INFO, connectcmp, NULL);
-       paircompare_register(PW_PACKET_TYPE, 0, packetcmp, NULL);
-       paircompare_register(PW_RESPONSE_PACKET_TYPE, 0, responsecmp, NULL);
-
-       for (i = 0; generic_attrs[i] != 0; i++) {
-               paircompare_register(generic_attrs[i], -1, genericcmp, NULL);
-       }
-}
-
-void pair_builtincompare_detach(void)
-{
-       int i;
-
-       paircompare_unregister(PW_NAS_PORT, portcmp);
-       paircompare_unregister(PW_PREFIX, presufcmp);
-       paircompare_unregister(PW_SUFFIX, presufcmp);
-       paircompare_unregister(PW_CONNECT_RATE, connectcmp);
-       paircompare_unregister(PW_PACKET_TYPE, packetcmp);
-       paircompare_unregister(PW_RESPONSE_PACKET_TYPE, responsecmp);
-
-       for (i = 0; generic_attrs[i] != 0; i++) {
-               paircompare_unregister(generic_attrs[i], genericcmp);
-       }
-
-}
index 8c76d94..c6308a6 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
 
 /*
  *     Define a structure for our module configuration.
@@ -67,8 +74,7 @@ static expr_map_t map[] =
 static int get_number(REQUEST *request, const char **string, int *answer)
 {
        int             i, found;
-       uint32_t        result;
-       int             x;
+       uint32_t        result, x;
        const char      *p;
        expr_token_t    this;
 
@@ -274,10 +280,6 @@ static int expr_instantiate(CONF_SECTION *conf, void **instance)
                inst->xlat_name = strdup(xlat_name);
                xlat_register(xlat_name, expr_xlat, inst);
        }
-       /*
-        * Initialize various paircompare functions
-        */
-       pair_builtincompare_init();
        *instance = inst;
 
        return 0;
@@ -291,7 +293,6 @@ static int expr_detach(void *instance)
        rlm_expr_t      *inst = instance;
 
        xlat_unregister(inst->xlat_name, expr_xlat);
-       pair_builtincompare_detach();
        free(inst->xlat_name);
 
        free(inst);
@@ -308,15 +309,16 @@ static int expr_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_expr = {
-       RLM_MODULE_INIT,
        "expr",                         /* Name */
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        expr_instantiate,               /* instantiation */
-       expr_detach,                    /* detach */
        {
                NULL,                   /* authentication */
                NULL,                   /* authorization */
                NULL,                   /* pre-accounting */
                NULL                    /* accounting */
        },
+       expr_detach,                    /* detach */
+       NULL,                           /* destroy */
 };
index aa8428b..4256a46 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Jeff Carneal <jeff@apex.net>
  */
 
-#include        <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
+#include        "autoconf.h"
+#include        "libradius.h"
 
+#include       <sys/socket.h>
+#include       <sys/time.h>
 #include       <sys/stat.h>
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <pwd.h>
+#include       <grp.h>
 #include       <ctype.h>
 #include       <fcntl.h>
 #include       <limits.h>
 
+#include       "radiusd.h"
+#include       "modules.h"
+
 struct fastuser_instance {
        char *compat_mode;
        int hash_reload;
@@ -63,11 +70,12 @@ static int fastuser_store(PAIR_LIST **hashtable, PAIR_LIST *entry, int idx);
 static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
                                                                                                                                const char *username);
 static void fastuser_tablestats(PAIR_LIST **hashtable, int size);
+static int fastuser_passcheck(REQUEST *request, PAIR_LIST *user, const char *name);
 
-static const CONF_PARSER module_config[] = {
-       { "usersfile",     PW_TYPE_FILENAME,
+static CONF_PARSER module_config[] = {
+       { "usersfile",     PW_TYPE_STRING_PTR,
          offsetof(struct fastuser_instance,usersfile), NULL, "${raddbdir}/users_fast" },
-       { "acctusersfile",     PW_TYPE_FILENAME,
+       { "acctusersfile",     PW_TYPE_STRING_PTR,
          offsetof(struct fastuser_instance,acctusersfile), NULL, "${raddbdir}/acct_users" },
        { "hashsize",     PW_TYPE_INTEGER,
          offsetof(struct fastuser_instance,hashsize), NULL, "100000" },
@@ -87,7 +95,7 @@ static int fallthrough(VALUE_PAIR *vp)
 {
        VALUE_PAIR *tmp;
        tmp = pairfind(vp, PW_FALL_THROUGH);
-       return tmp ? tmp->vp_integer : 0;
+       return tmp ? tmp->lvalue : 0;
 }
 
 /*
@@ -103,7 +111,7 @@ static int rad_check_return(VALUE_PAIR *list)
        */
 
       authtype = pairfind(list, PW_AUTHTYPE);
-      if((authtype) && authtype->vp_integer == PW_AUTHTYPE_REJECT)  {
+      if((authtype) && authtype->lvalue == PW_AUTHTYPE_REJECT)  {
               DEBUG2("rad_check_return:  Auth-Type is Reject");
               return RLM_MODULE_REJECT;
       }
@@ -432,9 +440,20 @@ static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
         */
        while((cur) && (!userfound)) {
                if((strcmp(cur->name, username)==0) &&
-                               paircompare(request, request->packet->vps, cur->check, &request->reply->vps) == 0) {
+                               paircmp(request, request->packet->vps, cur->check, &request->reply->vps) == 0) {
+                       /*
+                        * Usercollide means we have to compare check pairs
+                        * AND the password
+                        */
+                       if(mainconfig.do_usercollide) {
+                               if((userfound = fastuser_passcheck(request, cur, username))==0) {
+                                       cur = cur->next;
+                               }
+
+                       } else {
                                userfound = 1;
                                DEBUG2("  fastusers: Matched %s at %d", cur->name, cur->lineno);
+                       }
                } else {
                        cur = cur->next;
                }
@@ -482,6 +501,45 @@ static void fastuser_tablestats(PAIR_LIST **hashtable, int size) {
        }
 }
 
+static int fastuser_passcheck(REQUEST *request, PAIR_LIST *user,
+                             const char *name UNUSED)
+{
+       int found=0;
+       VALUE_PAIR      *check_save;
+
+       /*
+        * We check for REJECT specially here or a REJECT
+        * user will never match
+        */
+       check_save = pairfind(user->check, PW_AUTHTYPE);
+       if((check_save) && check_save->lvalue == PW_AUTHTYPE_REJECT)  {
+               DEBUG2("  fastusers(uc):  User '%s' line %d is Auth-Type Reject, but usercollide match",
+                                       user->name, user->lineno);
+               return 1;
+       }
+
+       /* Save the orginal config items */
+       check_save = request->config_items;
+       request->config_items = NULL;
+
+       DEBUG2("  fastusers(uc): Checking %s at %d", user->name, user->lineno);
+
+       /* Copy this users check pairs to the request */
+       request->config_items = paircopy(user->check);
+
+       /* Check the req to see if we matched */
+       if(rad_check_password(request)==0) {
+               DEBUG2("  fastusers(uc): Matched %s at %d", user->name, user->lineno);
+               found = 1;
+       }
+
+       /* Restore check items */
+       pairfree(&request->config_items);
+       request->config_items = check_save;
+
+       return found;
+}
+
 /*
  *     (Re-)read the "users" file into memory.
  */
@@ -553,7 +611,7 @@ static int fastuser_authorize(void *instance, REQUEST *request)
         *      Grab the canonical user name.
         */
        namepair = request->username;
-       name = namepair ? (char *) namepair->vp_strvalue : "NONE";
+       name = namepair ? (char *) namepair->strvalue : "NONE";
 
        /*
         *      Find the entry for the user.
@@ -602,7 +660,7 @@ static int fastuser_authorize(void *instance, REQUEST *request)
 
        curdefault = inst->defaults;
        while(curdefault) {
-               if(paircompare(request, request->packet->vps, curdefault->check,
+               if(paircmp(request, request->packet->vps, curdefault->check,
                                                        &request->reply->vps) == 0) {
                        DEBUG2("  fastusers: Matched %s at %d",
                                                        curdefault->name, curdefault->lineno);
@@ -700,7 +758,7 @@ static int fastuser_preacct(void *instance, REQUEST *request)
        struct fastuser_instance *inst = instance;
 
        namepair = request->username;
-       name = namepair ? (char *) namepair->vp_strvalue : "NONE";
+       name = namepair ? (char *) namepair->strvalue : "NONE";
        request_pairs = request->packet->vps;
        config_pairs = &request->config_items;
 
@@ -712,7 +770,7 @@ static int fastuser_preacct(void *instance, REQUEST *request)
                if (strcmp(name, pl->name) && strcmp(pl->name, "DEFAULT"))
                        continue;
 
-               if (paircompare(request, request_pairs, pl->check, &reply_pairs) == 0) {
+               if (paircmp(request, request_pairs, pl->check, &reply_pairs) == 0) {
                        DEBUG2("  acct_users: Matched %s at %d",
                               pl->name, pl->lineno);
                        found = 1;
@@ -762,9 +820,13 @@ static int fastuser_detach(void *instance)
                }
        }
 
+       free(inst->compat_mode);
        free(inst->hashtable);
        pairlist_free(&inst->defaults);
        pairlist_free(&inst->acctusers);
+       free(inst->usersfile);
+       free(inst->acctusersfile);
+       free(inst);
        return 0;
 }
 
@@ -781,11 +843,10 @@ static int fastuser_accounting(void *instance UNUSED, REQUEST *request UNUSED)
 
 /* globally exported name */
 module_t rlm_fastusers = {
-       RLM_MODULE_INIT,
        "fastusers",
        0,                              /* type: reserved */
+       NULL,                           /* initialization */
        fastuser_instantiate,           /* instantiation */
-       fastuser_detach,                /* detach */
        {
                fastuser_authenticate,  /* authentication */
                fastuser_authorize,     /* authorization */
@@ -796,5 +857,7 @@ module_t rlm_fastusers = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       fastuser_detach,                /* detach */
+       NULL                            /* destroy */
 };
 
index 4746ac9..c683327 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2000  Jeff Carneal <jeff@apex.net>
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
+#include       <sys/stat.h>
+
+#include       <stdlib.h>
+#include       <string.h>
+#include       <netdb.h>
 #include       <ctype.h>
 #include       <fcntl.h>
 #include       <limits.h>
 
+#include       "radiusd.h"
+#include       "modules.h"
+
 struct file_instance {
        char *compat_mode;
 
-       char *key;
-
        /* autz */
        char *usersfile;
-       lrad_hash_table_t *users;
+       PAIR_LIST *users;
 
        /* preacct */
        char *acctusersfile;
-       lrad_hash_table_t *acctusers;
+       PAIR_LIST *acctusers;
 
        /* pre-proxy */
        char *preproxy_usersfile;
-       lrad_hash_table_t *preproxy_users;
-
-       /* authenticate */
-       char *auth_usersfile;
-       lrad_hash_table_t *auth_users;
-
-       /* post-proxy */
-       char *postproxy_usersfile;
-       lrad_hash_table_t *postproxy_users;
-
-       /* post-authenticate */
-       char *postauth_usersfile;
-       lrad_hash_table_t *postauth_users;
+       PAIR_LIST *preproxy_users;
 };
 
-
 /*
  *     See if a VALUE_PAIR list contains Fall-Through = Yes
  */
@@ -70,62 +62,25 @@ static int fallthrough(VALUE_PAIR *vp)
        VALUE_PAIR *tmp;
        tmp = pairfind(vp, PW_FALL_THROUGH);
 
-       return tmp ? tmp->vp_integer : 0;
+       return tmp ? tmp->lvalue : 0;
 }
 
-static const CONF_PARSER module_config[] = {
-       { "usersfile",     PW_TYPE_FILENAME,
-         offsetof(struct file_instance,usersfile), NULL, NULL },
-       { "acctusersfile", PW_TYPE_FILENAME,
-         offsetof(struct file_instance,acctusersfile), NULL, NULL },
-       { "preproxy_usersfile", PW_TYPE_FILENAME,
-         offsetof(struct file_instance,preproxy_usersfile), NULL, NULL },
-       { "auth_usersfile", PW_TYPE_FILENAME,
-         offsetof(struct file_instance,auth_usersfile), NULL, NULL },
-       { "postproxy_usersfile", PW_TYPE_FILENAME,
-         offsetof(struct file_instance,postproxy_usersfile), NULL, NULL },
-       { "postauth_usersfile", PW_TYPE_FILENAME,
-         offsetof(struct file_instance,postauth_usersfile), NULL, NULL },
+static CONF_PARSER module_config[] = {
+       { "usersfile",     PW_TYPE_STRING_PTR,
+         offsetof(struct file_instance,usersfile), NULL, "${raddbdir}/users" },
+       { "acctusersfile", PW_TYPE_STRING_PTR,
+         offsetof(struct file_instance,acctusersfile), NULL, "${raddbdir}/acct_users" },
+       { "preproxy_usersfile", PW_TYPE_STRING_PTR,
+         offsetof(struct file_instance,preproxy_usersfile), NULL, "${raddbdir}/preproxy_users" },
        { "compat",        PW_TYPE_STRING_PTR,
          offsetof(struct file_instance,compat_mode), NULL, "cistron" },
-       { "key",           PW_TYPE_STRING_PTR,
-         offsetof(struct file_instance,key), NULL, NULL },
        { NULL, -1, 0, NULL, NULL }
 };
 
-
-static uint32_t pairlist_hash(const void *data)
-{
-       return lrad_hash_string(((const PAIR_LIST *)data)->name);
-}
-
-static int pairlist_cmp(const void *a, const void *b)
-{
-       return strcmp(((const PAIR_LIST *)a)->name,
-                     ((const PAIR_LIST *)b)->name);
-}
-
-static void my_pairlist_free(void *data)
-{
-       PAIR_LIST *pl = data;
-
-       pairlist_free(&pl);
-}
-
-
-static int getusersfile(const char *filename, lrad_hash_table_t **pht,
-                       char *compat_mode_str)
+static int getusersfile(const char *filename, PAIR_LIST **pair_list, char *compat_mode_str)
 {
        int rcode;
        PAIR_LIST *users = NULL;
-       PAIR_LIST *entry, *next;
-       lrad_hash_table_t *ht, *tailht;
-       int order = 0;
-
-       if (!filename) {
-               *pht = NULL;
-               return 0;
-       }
 
        rcode = pairlist_read(filename, &users, 1);
        if (rcode < 0) {
@@ -138,6 +93,7 @@ static int getusersfile(const char *filename, lrad_hash_table_t **pht,
         */
        if ((debug_flag) ||
            (strcmp(compat_mode_str, "cistron") == 0)) {
+               PAIR_LIST *entry;
                VALUE_PAIR *vp;
                int compat_mode = FALSE;
 
@@ -220,6 +176,7 @@ static int getusersfile(const char *filename, lrad_hash_table_t **pht,
 
                        } /* end of loop over check items */
 
+
                        /*
                         *      Look for server configuration items
                         *      in the reply list.
@@ -252,84 +209,11 @@ static int getusersfile(const char *filename, lrad_hash_table_t **pht,
 
        }
 
-       ht = lrad_hash_table_create(pairlist_hash, pairlist_cmp,
-                                   my_pairlist_free);
-       if (!ht) {
-               pairlist_free(&users);
-               return -1;
-       }
-
-       tailht = lrad_hash_table_create(pairlist_hash, pairlist_cmp,
-                                       NULL);
-       if (!tailht) {
-               lrad_hash_table_free(ht);
-               pairlist_free(&users);
-               return -1;
-       }
-
-       /*
-        *      Now that we've read it in, put the entries into a hash
-        *      for faster access.
-        */
-       for (entry = users; entry != NULL; entry = next) {
-               PAIR_LIST *tail;
-
-               next = entry->next;
-               entry->next = NULL;
-               entry->order = order++;
-
-               /*
-                *      Insert it into the hash table, and remember
-                *      the tail of the linked list.
-                */
-               tail = lrad_hash_table_finddata(tailht, entry);
-               if (!tail) {
-                       /*
-                        *      Insert it into the head & tail.
-                        */
-                       if (!lrad_hash_table_insert(ht, entry) ||
-                           !lrad_hash_table_insert(tailht, entry)) {
-                               pairlist_free(&next);
-                               lrad_hash_table_free(ht);
-                               lrad_hash_table_free(tailht);
-                               return -1;
-                       }
-               } else {
-                       tail->next = entry;
-                       if (!lrad_hash_table_replace(tailht, entry)) {
-                               pairlist_free(&next);
-                               lrad_hash_table_free(ht);
-                               lrad_hash_table_free(tailht);
-                               return -1;
-                       }
-               }
-       }
-
-       lrad_hash_table_free(tailht);
-       *pht = ht;
-
+       *pair_list = users;
        return 0;
 }
 
 /*
- *     Clean up.
- */
-static int file_detach(void *instance)
-{
-       struct file_instance *inst = instance;
-       lrad_hash_table_free(inst->users);
-       lrad_hash_table_free(inst->acctusers);
-       lrad_hash_table_free(inst->preproxy_users);
-       lrad_hash_table_free(inst->auth_users);
-       lrad_hash_table_free(inst->postproxy_users);
-       lrad_hash_table_free(inst->postauth_users);
-       free(inst);
-       return 0;
-}
-
-
-
-/*
  *     (Re-)read the "users" file into memory.
  */
 static int file_instantiate(CONF_SECTION *conf, void **instance)
@@ -350,15 +234,20 @@ static int file_instantiate(CONF_SECTION *conf, void **instance)
 
        rcode = getusersfile(inst->usersfile, &inst->users, inst->compat_mode);
        if (rcode != 0) {
-         radlog(L_ERR|L_CONS, "Errors reading %s", inst->usersfile);
-               file_detach(inst);
+               radlog(L_ERR|L_CONS, "Errors reading %s", inst->usersfile);
+               free(inst->usersfile);
+               free(inst->acctusersfile);
+               free(inst);
                return -1;
        }
 
        rcode = getusersfile(inst->acctusersfile, &inst->acctusers, inst->compat_mode);
        if (rcode != 0) {
                radlog(L_ERR|L_CONS, "Errors reading %s", inst->acctusersfile);
-               file_detach(inst);
+               pairlist_free(&inst->users);
+               free(inst->usersfile);
+               free(inst->acctusersfile);
+               free(inst);
                return -1;
        }
 
@@ -368,28 +257,12 @@ static int file_instantiate(CONF_SECTION *conf, void **instance)
        rcode = getusersfile(inst->preproxy_usersfile, &inst->preproxy_users, inst->compat_mode);
        if (rcode != 0) {
                radlog(L_ERR|L_CONS, "Errors reading %s", inst->preproxy_usersfile);
-               file_detach(inst);
-               return -1;
-       }
-
-       rcode = getusersfile(inst->auth_usersfile, &inst->auth_users, inst->compat_mode);
-       if (rcode != 0) {
-               radlog(L_ERR|L_CONS, "Errors reading %s", inst->auth_usersfile);
-               file_detach(inst);
-               return -1;
-       }
-
-       rcode = getusersfile(inst->postproxy_usersfile, &inst->postproxy_users, inst->compat_mode);
-       if (rcode != 0) {
-               radlog(L_ERR|L_CONS, "Errors reading %s", inst->postproxy_usersfile);
-               file_detach(inst);
-               return -1;
-       }
-
-       rcode = getusersfile(inst->postauth_usersfile, &inst->postauth_users, inst->compat_mode);
-       if (rcode != 0) {
-               radlog(L_ERR|L_CONS, "Errors reading %s", inst->postauth_usersfile);
-               file_detach(inst);
+               pairlist_free(&inst->users);
+               pairlist_free(&inst->acctusers);
+               free(inst->usersfile);
+               free(inst->acctusersfile);
+               free(inst->preproxy_usersfile);
+               free(inst);
                return -1;
        }
 
@@ -398,82 +271,176 @@ static int file_instantiate(CONF_SECTION *conf, void **instance)
 }
 
 /*
- *     Common code called by everything below.
+ *     Find the named user in the database.  Create the
+ *     set of attribute-value pairs to check and reply with
+ *     for this user from the database. The main code only
+ *     needs to check the password, the rest is done here.
  */
-static int file_common(struct file_instance *inst, REQUEST *request,
-                      const char *filename, lrad_hash_table_t *ht,
-                      VALUE_PAIR *request_pairs, VALUE_PAIR **reply_pairs)
+static int file_authorize(void *instance, REQUEST *request)
 {
-       const char      *name, *match;
-       VALUE_PAIR      **config_pairs;
+       VALUE_PAIR      *namepair;
+       VALUE_PAIR      *request_pairs;
        VALUE_PAIR      *check_tmp;
        VALUE_PAIR      *reply_tmp;
-       const PAIR_LIST *user_pl, *default_pl;
+       PAIR_LIST       *pl;
        int             found = 0;
-       PAIR_LIST       my_pl;
-       char            buffer[256];
+       const char      *name;
+       struct file_instance *inst = instance;
+       VALUE_PAIR **check_pairs, **reply_pairs;
+       VALUE_PAIR *check_save;
 
-       if (!inst->key) {
-               VALUE_PAIR      *namepair;
+       request_pairs = request->packet->vps;
+       check_pairs = &request->config_items;
+       reply_pairs = &request->reply->vps;
 
-               namepair = request->username;
-               name = namepair ? (char *) namepair->vp_strvalue : "NONE";
-       } else {
-               int len;
+       /*
+        *      Grab the canonical user name.
+        */
+       namepair = request->username;
+       name = namepair ? (char *) namepair->strvalue : "NONE";
 
-               len = radius_xlat(buffer, sizeof(buffer), inst->key,
-                                 request, NULL);
-               if (len) name = buffer;
-               else name = "NONE";
+       /*
+        *      Find the entry for the user.
+        */
+       for(pl = inst->users; pl; pl = pl->next) {
+               /*
+                *      If the current entry is NOT a default,
+                *      AND the name does NOT match the current entry,
+                *      then skip to the next entry.
+                */
+               if ((strcmp(pl->name, "DEFAULT") != 0) &&
+                   (strcmp(name, pl->name) != 0))  {
+                       continue;
+               }
+
+               /*
+                *      If the current request matches against the
+                *      check pairs, then add the reply pairs from the
+                *      entry to the current list of reply pairs.
+                */
+               if ((paircmp(request, request_pairs, pl->check, reply_pairs) == 0)) {
+                       if ((mainconfig.do_usercollide) &&
+                           (strcmp(pl->name, "DEFAULT"))) {
+
+                               /*
+                                * We have to make sure the password
+                                * matches as well
+                                */
+
+                               /* Save the orginal config items */
+                               check_save = paircopy(request->config_items);
+
+                               /* Copy this users check pairs to the request */
+                               check_tmp = paircopy(pl->check);
+                               pairmove(check_pairs, &check_tmp);
+                               pairfree(&check_tmp);
+
+                               DEBUG2("    users: Checking entry %s at line %d", pl->name, pl->lineno);
+                               /* Check the req to see if we matched */
+                               if (rad_check_password(request)==0) {
+                                       DEBUG2("    users: Matched entry %s at line %d", pl->name, pl->lineno);
+
+                                       found = 1;
+
+                                       /* Free our saved config items */
+                                       pairfree(&check_save);
+
+                                       /*
+                                        * Already copied check items, so
+                                        * just copy reply here
+                                        */
+                                       reply_tmp = paircopy(pl->reply);
+                                       pairxlatmove(request, reply_pairs, &reply_tmp);
+                                       pairfree(&reply_tmp);
+
+                               /* We didn't match here */
+                               } else {
+                                       /* Restore check items */
+                                       pairfree(&request->config_items);
+                                       request->config_items = paircopy(check_save);
+                                       check_pairs = &request->config_items;
+                                       continue;
+                               }
+
+                       /* No usercollide */
+                       } else {
+
+                               DEBUG2("    users: Matched entry %s at line %d", pl->name, pl->lineno);
+                               found = 1;
+                               check_tmp = paircopy(pl->check);
+                               reply_tmp = paircopy(pl->reply);
+                               pairxlatmove(request, reply_pairs, &reply_tmp);
+                               pairmove(check_pairs, &check_tmp);
+                               pairfree(&reply_tmp);
+                               pairfree(&check_tmp); /* should be NULL */
+                       }
+                       /*
+                        *      Fallthrough?
+                        */
+                       if (!fallthrough(pl->reply))
+                               break;
+               }
        }
 
-       config_pairs = &request->config_items;
+       /*
+        *      See if we succeeded.  If we didn't find the user,
+        *      then exit from the module.
+        */
+       if (!found)
+               return RLM_MODULE_NOTFOUND;
 
-       if (!ht) return RLM_MODULE_NOOP;
+       /*
+        *      Remove server internal parameters.
+        */
+       pairdelete(reply_pairs, PW_FALL_THROUGH);
 
-       my_pl.name = name;
-       user_pl = lrad_hash_table_finddata(ht, &my_pl);
-       my_pl.name = "DEFAULT";
-       default_pl = lrad_hash_table_finddata(ht, &my_pl);
+       return RLM_MODULE_OK;
+}
+
+/*
+ *     Pre-Accounting - read the acct_users file for check_items and
+ *     config_items. Reply items are Not Recommended(TM) in acct_users,
+ *     except for Fallthrough, which should work
+ *
+ *     This function is mostly a copy of file_authorize
+ */
+static int file_preacct(void *instance, REQUEST *request)
+{
+       VALUE_PAIR      *namepair;
+       const char      *name;
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      **config_pairs;
+       VALUE_PAIR      **reply_pairs;
+       VALUE_PAIR      *check_tmp;
+       VALUE_PAIR      *reply_tmp;
+       PAIR_LIST       *pl;
+       int             found = 0;
+       struct file_instance *inst = instance;
+
+       namepair = request->username;
+       name = namepair ? (char *) namepair->strvalue : "NONE";
+       request_pairs = request->packet->vps;
+       config_pairs = &request->config_items;
+       reply_pairs = &request->reply->vps;
 
        /*
         *      Find the entry for the user.
         */
-       while (user_pl || default_pl) {
-               const PAIR_LIST *pl;
-
-               if (!default_pl && user_pl) {
-                       pl = user_pl;
-                       match = name;
-                       user_pl = user_pl->next;
-
-               } else if (!user_pl && default_pl) {
-                       pl = default_pl;
-                       match = "DEFAULT";
-                       default_pl = default_pl->next;
-
-               } else if (user_pl->order < default_pl->order) {
-                       pl = user_pl;
-                       match = name;
-                       user_pl = user_pl->next;
-
-               } else {
-                       pl = default_pl;
-                       match = "DEFAULT";
-                       default_pl = default_pl->next;
-               }
+       for (pl = inst->acctusers; pl; pl = pl->next) {
 
-               if (paircompare(request, request_pairs, pl->check, reply_pairs) == 0) {
-                       DEBUG2("    %s: Matched entry %s at line %d",
-                              filename, match, pl->lineno);
+               if (strcmp(name, pl->name) && strcmp(pl->name, "DEFAULT"))
+                       continue;
+
+               if (paircmp(request, request_pairs, pl->check, reply_pairs) == 0) {
+                       DEBUG2("    acct_users: Matched entry %s at line %d",
+                              pl->name, pl->lineno);
                        found = 1;
                        check_tmp = paircopy(pl->check);
                        reply_tmp = paircopy(pl->reply);
                        pairxlatmove(request, reply_pairs, &reply_tmp);
                        pairmove(config_pairs, &check_tmp);
                        pairfree(&reply_tmp);
-                       pairfree(&check_tmp);
-
+                       pairfree(&check_tmp); /* should be NULL */
                        /*
                         *      Fallthrough?
                         */
@@ -483,102 +450,137 @@ static int file_common(struct file_instance *inst, REQUEST *request,
        }
 
        /*
-        *      Remove server internal parameters.
-        */
-       pairdelete(reply_pairs, PW_FALL_THROUGH);
-
-       /*
         *      See if we succeeded.
         */
        if (!found)
                return RLM_MODULE_NOOP; /* on to the next module */
 
        return RLM_MODULE_OK;
-
 }
 
-
 /*
- *     Find the named user in the database.  Create the
- *     set of attribute-value pairs to check and reply with
- *     for this user from the database. The main code only
- *     needs to check the password, the rest is done here.
+ *     Pre-proxy - read the preproxy_users file for check_items and
+ *     config_items.
+ *
+ *     This function is mostly a copy of file_authorize
  */
-static int file_authorize(void *instance, REQUEST *request)
+static int file_preproxy(void *instance, REQUEST *request)
 {
+       VALUE_PAIR      *namepair;
+       const char      *name;
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      **config_pairs;
+       VALUE_PAIR      **reply_pairs;
+       VALUE_PAIR      *check_tmp;
+       VALUE_PAIR      *reply_tmp;
+       PAIR_LIST       *pl;
+       int             found = 0;
        struct file_instance *inst = instance;
 
-       return file_common(inst, request, "users", inst->users,
-                          request->packet->vps, &request->reply->vps);
-}
+       namepair = request->username;
+       name = namepair ? (char *) namepair->strvalue : "NONE";
+       request_pairs = request->packet->vps;
+       config_pairs = &request->config_items;
+       reply_pairs = &request->proxy->vps;
 
+       /*
+        *      Find the entry for the user.
+        */
+       for (pl = inst->preproxy_users; pl; pl = pl->next) {
 
-/*
- *     Pre-Accounting - read the acct_users file for check_items and
- *     config_items. Reply items are Not Recommended(TM) in acct_users,
- *     except for Fallthrough, which should work
- */
-static int file_preacct(void *instance, REQUEST *request)
-{
-       struct file_instance *inst = instance;
+               /*
+                *  No match: skip it.
+                */
+               if (strcmp(name, pl->name) && strcmp(pl->name, "DEFAULT"))
+                       continue;
 
-       return file_common(inst, request, "acct_users", inst->acctusers,
-                          request->packet->vps, &request->reply->vps);
-}
+               if (paircmp(request, request_pairs, pl->check, reply_pairs) == 0) {
+                       VALUE_PAIR *vp;
 
-static int file_preproxy(void *instance, REQUEST *request)
-{
-       struct file_instance *inst = instance;
+                       DEBUG2("    preproxy_users: Matched entry %s at line %d",
+                              pl->name, pl->lineno);
+                       found = 1;
+                       check_tmp = paircopy(pl->check);
+                       reply_tmp = paircopy(pl->reply);
 
-       return file_common(inst, request, "preproxy_users",
-                          inst->preproxy_users,
-                          request->packet->vps, &request->proxy->vps);
-}
+                       for (vp = reply_tmp; vp != NULL; vp = vp->next) {
+                               /*
+                                *      We've got to xlat the string
+                                *      before moving it over.
+                                */
+                               if (vp->flags.do_xlat) {
+                                       int rcode;
+                                       char buffer[sizeof(vp->strvalue)];
 
-static int file_postproxy(void *instance, REQUEST *request)
-{
-       struct file_instance *inst = instance;
+                                       vp->flags.do_xlat = 0;
+                                       rcode = radius_xlat(buffer, sizeof(buffer),
+                                                           vp->strvalue,
+                                                           request, NULL);
 
-       return file_common(inst, request, "postproxy_users",
-                          inst->postproxy_users,
-                          request->proxy_reply->vps, &request->reply->vps);
-}
+                                       /*
+                                        *      Parse the string into
+                                        *      a new value.
+                                        */
+                                       pairparsevalue(vp, buffer);
+                               }
+                       } /* loop over the things to add to the reply */
 
-static int file_authenticate(void *instance, REQUEST *request)
-{
-       struct file_instance *inst = instance;
+                       pairxlatmove(request, reply_pairs, &reply_tmp);
+                       pairmove(config_pairs, &check_tmp);
+                       pairfree(&reply_tmp);
+                       pairfree(&check_tmp); /* should be NULL */
+                       /*
+                        *      Fallthrough?
+                        */
+                       if (!fallthrough(pl->reply))
+                               break;
+               }
+       }
+
+       /*
+        *      See if we succeeded.
+        */
+       if (!found)
+               return RLM_MODULE_NOOP; /* on to the next module */
 
-       return file_common(inst, request, "auth_users",
-                          inst->auth_users,
-                          request->packet->vps, &request->reply->vps);
+       return RLM_MODULE_OK;
 }
 
-static int file_postauth(void *instance, REQUEST *request)
+/*
+ *     Clean up.
+ */
+static int file_detach(void *instance)
 {
        struct file_instance *inst = instance;
-
-       return file_common(inst, request, "postauth_users",
-                          inst->postauth_users,
-                          request->packet->vps, &request->reply->vps);
+       pairlist_free(&inst->users);
+       pairlist_free(&inst->acctusers);
+       pairlist_free(&inst->preproxy_users);
+       free(inst->usersfile);
+       free(inst->acctusersfile);
+       free(inst->preproxy_usersfile);
+       free(inst->compat_mode);
+       free(inst);
+       return 0;
 }
 
 
 /* globally exported name */
 module_t rlm_files = {
-       RLM_MODULE_INIT,
        "files",
        0,                              /* type: reserved */
+       NULL,                           /* initialization */
        file_instantiate,               /* instantiation */
-       file_detach,                    /* detach */
        {
-               file_authenticate,      /* authentication */
+               NULL,                   /* authentication */
                file_authorize,         /* authorization */
                file_preacct,           /* preaccounting */
                NULL,                   /* accounting */
                NULL,                   /* checksimul */
                file_preproxy,          /* pre-proxy */
-               file_postproxy,         /* post-proxy */
-               file_postauth           /* post-auth */
+               NULL,                   /* post-proxy */
+               NULL                    /* post-auth */
        },
+       file_detach,                    /* detach */
+       NULL                            /* destroy */
 };
 
diff --git a/src/modules/rlm_ippool/acconfig.h b/src/modules/rlm_ippool/acconfig.h
new file mode 100644 (file)
index 0000000..376f75b
--- /dev/null
@@ -0,0 +1,5 @@
+/* do we need GDBM_SYNC */
+#undef NEED_GDBM_SYNC
+
+/* do we have gdbm_fdesc */
+#undef HAVE_GDBM_FDESC
index 32fad9e..18af0c2 100644 (file)
@@ -1,22 +1,7 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
-
-/* do we have gdbm_fdesc */
-#undef HAVE_GDBM_FDESC
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
 
 /* do we need GDBM_SYNC */
 #undef NEED_GDBM_SYNC
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+/* do we have gdbm_fdesc */
+#undef HAVE_GDBM_FDESC
index d3f1c8d..f9e4015 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.4 .
+# From configure.in Revision: 1.2 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -901,7 +901,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1821,7 +1821,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1879,7 +1880,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1995,7 +1997,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2049,7 +2052,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2094,7 +2098,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2138,7 +2143,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2451,7 +2457,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2474,8 +2481,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2504,7 +2511,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2582,7 +2590,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2605,8 +2614,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2658,7 +2667,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2681,8 +2691,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2711,7 +2721,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2816,7 +2827,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2839,8 +2851,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -2895,8 +2907,7 @@ _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   $EGREP "found-gdbm-sync" >/dev/null 2>&1; then
 
-
-cat >>confdefs.h <<\_ACEOF
+                       cat >>confdefs.h <<\_ACEOF
 #define NEED_GDBM_SYNC yes
 _ACEOF
 
@@ -2981,7 +2992,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3008,9 +3020,8 @@ echo "${ECHO_T}$ac_cv_func_gdbm_fdesc" >&6
 
        if test "x$ac_cv_func_gdbm_fdesc" = "xyes";
        then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GDBM_FDESC
+               cat >>confdefs.h <<\_ACEOF
+#define HAVE_GDBM_FDESC 1
 _ACEOF
 
        fi
@@ -3839,6 +3850,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3877,12 +3893,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index d12922f..5fb931a 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_ippool.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_ippool])
@@ -8,8 +7,8 @@ if test x$with_[]modname != xno; then
        AC_PROG_CC
        AC_PROG_CPP
 
-       FR_SMART_CHECK_INCLUDE(gdbm.h)
-       FR_SMART_CHECK_LIB(gdbm, gdbm_open)
+       AC_SMART_CHECK_INCLUDE(gdbm.h)
+       AC_SMART_CHECK_LIB(gdbm, gdbm_open)
        if test "x$ac_cv_lib_gdbm_gdbm_open" != "xyes"; then
                fail="$fail libgdbm"
        fi
@@ -24,7 +23,7 @@ if test x$with_[]modname != xno; then
        not found.  this version must use sync by default.
 #endif
                        ], [
-                       AC_DEFINE(NEED_GDBM_SYNC, yes, [do we need GDBM_SYNC])
+                       AC_DEFINE(NEED_GDBM_SYNC, yes
                        AC_MSG_RESULT(needs it.)
                        ], [
                        AC_MSG_RESULT(SYNCs by default.)
@@ -37,7 +36,7 @@ if test x$with_[]modname != xno; then
        AC_CHECK_FUNC(gdbm_fdesc)
        if test "x$ac_cv_func_gdbm_fdesc" = "xyes";
        then
-               AC_DEFINE(HAVE_GDBM_FDESC, [], [do we have gdbm_fdesc])
+               AC_DEFINE(HAVE_GDBM_FDESC)
        fi
        LIBS=$old_LIBS
 
@@ -52,7 +51,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index a7a4baa..48aceae 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2002  Kostas Kalevras <kkalev@noc.ntua.gr>
  *
  * March 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
  *   to request->timestamp and timeout to %{Session-Timeout:-0}. When we search for a free entry
  *   we check if timeout has expired. If it has then we free the entry. We also add a maximum
  *   timeout configuration directive. If it is non zero then we also use that one to free entries.
- * Jul 2004, Kostas Kalevras <kkalev@noc.ntua.gr>
- * - If Pool-Name is set to DEFAULT then always run.
- * Mar 2005, Kostas Kalevras <kkalev@noc.ntua.gr>
- * - Make the key an MD5 of a configurable xlated string. This closes Bug #42
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
 #include "config.h"
+#include "autoconf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
-#include "../../include/md5.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 
 #include <gdbm.h>
+#include <time.h>
 
 #ifdef NEEDS_GDBM_SYNC
 #      define GDBM_SYNCOPT GDBM_SYNC
@@ -82,6 +96,8 @@ RCSID("$Id$")
 
 #define MAX_NAS_NAME_SIZE 64
 
+static const char rcsid[] = "$Id$";
+
 /*
  *     Define a structure for our module configuration.
  *
@@ -93,7 +109,6 @@ typedef struct rlm_ippool_t {
        char *session_db;
        char *ip_index;
        char *name;
-       char *key;
        uint32_t range_start;
        uint32_t range_stop;
        uint32_t netmask;
@@ -127,7 +142,8 @@ typedef struct ippool_info {
 } ippool_info;
 
 typedef struct ippool_key {
-       char key[16];
+       char nas[MAX_NAS_NAME_SIZE];
+       unsigned int port;
 } ippool_key;
 
 /*
@@ -139,10 +155,9 @@ typedef struct ippool_key {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "session-db", PW_TYPE_STRING_PTR, offsetof(rlm_ippool_t,session_db), NULL, NULL },
   { "ip-index", PW_TYPE_STRING_PTR, offsetof(rlm_ippool_t,ip_index), NULL, NULL },
-  { "key", PW_TYPE_STRING_PTR, offsetof(rlm_ippool_t,key), NULL, "%{NAS-IP-Address} %{NAS-Port}" },
   { "range-start", PW_TYPE_IPADDR, offsetof(rlm_ippool_t,range_start), NULL, "0" },
   { "range-stop", PW_TYPE_IPADDR, offsetof(rlm_ippool_t,range_stop), NULL, "0" },
   { "netmask", PW_TYPE_IPADDR, offsetof(rlm_ippool_t,netmask), NULL, "0" },
@@ -152,6 +167,7 @@ static const CONF_PARSER module_config[] = {
   { NULL, -1, 0, NULL, NULL }
 };
 
+
 /*
  *     Do any per-module initialization that is separate to each
  *     configured instance of the module.  e.g. set up connections
@@ -243,7 +259,7 @@ static int ippool_instantiate(CONF_SECTION *conf, void **instance)
                int rcode;
                uint32_t or_result;
                char str[32];
-               char init_str[17];
+               const char *nas_init = "NOT_EXIST";
 
                DEBUG("rlm_ippool: Initializing database");
                for(i=data->range_start,j=~0;i<=data->range_stop;i++,j--){
@@ -260,9 +276,8 @@ static int ippool_instantiate(CONF_SECTION *conf, void **instance)
                                continue;
                        }
 
-                       sprintf(init_str,"%016d",j);
-                       DEBUG("rlm_ippool: Initialized bucket: %s",init_str);
-                       memcpy(key.key, init_str,16);
+                       strcpy(key.nas, nas_init);
+                       key.port = j;
                        key_datum.dptr = (char *) &key;
                        key_datum.dsize = sizeof(ippool_key);
 
@@ -314,38 +329,40 @@ static int ippool_accounting(void *instance, REQUEST *request)
        datum data_datum;
        datum save_datum;
        int acctstatustype = 0;
+       unsigned int port = ~0;
        int rcode;
+       char nas[MAX_NAS_NAME_SIZE];
        ippool_info entry;
        ippool_key key;
        int num = 0;
        VALUE_PAIR *vp;
        char str[32];
-       char key_str[17];
-       char hex_str[35];
-       char xlat_str[MAX_STRING_LEN];
-       MD5_CTX md5_context;
 
 
        if ((vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL)
-               acctstatustype = vp->vp_integer;
+               acctstatustype = vp->lvalue;
        else {
                DEBUG("rlm_ippool: Could not find account status type in packet. Return NOOP.");
                return RLM_MODULE_NOOP;
        }
        switch(acctstatustype){
                case PW_STATUS_STOP:
-                       if (!radius_xlat(xlat_str,MAX_STRING_LEN,data->key, request, NULL)){
-                               DEBUG("rlm_ippool: xlat on the 'key' directive failed");
+                       if ((vp = pairfind(request->packet->vps, PW_NAS_PORT)) != NULL)
+                               port = vp->lvalue;
+                       else {
+                               DEBUG("rlm_ippool: Could not find port number in packet. Return NOOP.");
                                return RLM_MODULE_NOOP;
                        }
-                       MD5Init(&md5_context);
-                       MD5Update(&md5_context, xlat_str, strlen(xlat_str));
-                       MD5Final(key_str, &md5_context);
-                       key_str[17] = '\0';
-                       lrad_bin2hex(key_str,hex_str,16);
-                       hex_str[32] = '\0';
-                       DEBUG("rlm_ippool: MD5 on 'key' directive maps to: %s",hex_str);
-                       memcpy(key.key,key_str,16);
+                       if ((vp = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS)) != NULL)
+                               strncpy(nas, vp->strvalue, MAX_NAS_NAME_SIZE - 1);
+                       else {
+                               if ((vp = pairfind(request->packet->vps, PW_NAS_IDENTIFIER)) != NULL)
+                                       strncpy(nas, vp->strvalue, MAX_NAS_NAME_SIZE - 1);
+                               else {
+                                       DEBUG("rlm_ippool: Could not find nas information in packet. Return NOOP.");
+                                       return RLM_MODULE_NOOP;
+                               }
+                       }
                        break;
                default:
                        /* We don't care about any other accounting packet */
@@ -354,7 +371,10 @@ static int ippool_accounting(void *instance, REQUEST *request)
                        return RLM_MODULE_NOOP;
        }
 
-       DEBUG("rlm_ippool: Searching for an entry for key: '%s'",xlat_str);
+       memset(key.nas,0,MAX_NAS_NAME_SIZE);
+       strncpy(key.nas,nas,MAX_NAS_NAME_SIZE -1 );
+       key.port = port;
+       DEBUG("rlm_ippool: Searching for an entry for nas/port: %s/%u",key.nas,key.port);
        key_datum.dptr = (char *) &key;
        key_datum.dsize = sizeof(ippool_key);
 
@@ -367,7 +387,7 @@ static int ippool_accounting(void *instance, REQUEST *request)
                 */
                memcpy(&entry, data_datum.dptr, sizeof(ippool_info));
                free(data_datum.dptr);
-               DEBUG("rlm_ippool: Deallocated entry for ip: %s",ip_ntoa(str,entry.ipaddr));
+               DEBUG("rlm_ippool: Deallocated entry for ip/port: %s/%u",ip_ntoa(str,entry.ipaddr),port);
                entry.active = 0;
                entry.timestamp = 0;
                entry.timeout = 0;
@@ -433,12 +453,14 @@ static int ippool_accounting(void *instance, REQUEST *request)
 static int ippool_postauth(void *instance, REQUEST *request)
 {
        rlm_ippool_t *data = (rlm_ippool_t *) instance;
+       unsigned int port = 0;
        int delete = 0;
        int found = 0;
        int mppp = 0;
        int extra = 0;
        int rcode;
        int num = 0;
+       char nas[MAX_NAS_NAME_SIZE];
        datum key_datum;
        datum nextkey;
        datum data_datum;
@@ -448,10 +470,6 @@ static int ippool_postauth(void *instance, REQUEST *request)
        VALUE_PAIR *vp;
        char *cli = NULL;
        char str[32];
-       char key_str[17];
-       char hex_str[35];
-       char xlat_str[MAX_STRING_LEN];
-       MD5_CTX md5_context;
 
 
        /* quiet the compiler */
@@ -462,35 +480,49 @@ static int ippool_postauth(void *instance, REQUEST *request)
         * run only if they match
         */
        if ((vp = pairfind(request->config_items, PW_POOL_NAME)) != NULL){
-               if (data->name == NULL || (strcmp(data->name,vp->vp_strvalue) && strcmp(vp->vp_strvalue,"DEFAULT")))
+               if (data->name == NULL || strcmp(data->name,vp->strvalue))
                        return RLM_MODULE_NOOP;
        } else {
                DEBUG("rlm_ippool: Could not find Pool-Name attribute.");
                return RLM_MODULE_NOOP;
        }
 
+       /*
+        * Get the nas ip address
+        * If not fail
+        */
+       if ((vp = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS)) != NULL)
+               strncpy(nas, vp->strvalue, MAX_NAS_NAME_SIZE - 1);
+       else{
+               if ((vp = pairfind(request->packet->vps, PW_NAS_IDENTIFIER)) != NULL)
+                       strncpy(nas, vp->strvalue, MAX_NAS_NAME_SIZE - 1);
+               else{
+                       DEBUG("rlm_ippool: Could not find nas information. Return NOOP.");
+                       return RLM_MODULE_NOOP;
+               }
+       }
 
        /*
         * Find the caller id
         */
        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
-               cli = vp->vp_strvalue;
-
+               cli = vp->strvalue;
 
-       if (!radius_xlat(xlat_str,MAX_STRING_LEN,data->key, request, NULL)){
-               DEBUG("rlm_ippool: xlat on the 'key' directive failed");
+       /*
+        * Find the port
+        * If not fail
+        */
+       if ((vp = pairfind(request->packet->vps, PW_NAS_PORT)) != NULL)
+               port = vp->lvalue;
+       else{
+               DEBUG("rlm_ippool: Could not find nas port information. Return NOOP.");
                return RLM_MODULE_NOOP;
        }
-       MD5Init(&md5_context);
-       MD5Update(&md5_context, xlat_str, strlen(xlat_str));
-       MD5Final(key_str, &md5_context);
-       key_str[17] = '\0';
-       lrad_bin2hex(key_str,hex_str,16);
-       hex_str[32] = '\0';
-       DEBUG("rlm_ippool: MD5 on 'key' directive maps to: %s",hex_str);
-       memcpy(key.key,key_str,16);
-
-       DEBUG("rlm_ippool: Searching for an entry for key: '%s'",hex_str);
+
+       memset(key.nas,0,MAX_NAS_NAME_SIZE);
+       strncpy(key.nas,nas,MAX_NAS_NAME_SIZE -1 );
+       key.port = port;
+       DEBUG("rlm_ippool: Searching for an entry for nas/port: %s/%u",key.nas,key.port);
        key_datum.dptr = (char *) &key;
        key_datum.dsize = sizeof(ippool_key);
 
@@ -505,7 +537,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                memcpy(&entry, data_datum.dptr, sizeof(ippool_info));
                free(data_datum.dptr);
                if (entry.active){
-                       DEBUG("rlm_ippool: Found a stale entry for ip: %s",ip_ntoa(str,entry.ipaddr));
+                       DEBUG("rlm_ippool: Found a stale entry for ip/port: %s/%u",ip_ntoa(str,entry.ipaddr),port);
                        entry.active = 0;
                        entry.timestamp = 0;
                        entry.timeout = 0;
@@ -595,12 +627,15 @@ static int ippool_postauth(void *instance, REQUEST *request)
                                memcpy(&entry,data_datum.dptr, sizeof(ippool_info));
                                free(data_datum.dptr);
                                /*
-                               * If we find an entry for the same caller-id with active=1
+                               * If we find an entry for the same caller-id and nas with active=1
                                * then we use that for multilink (MPPP) to work properly.
                                */
                                if (strcmp(entry.cli,cli) == 0 && entry.active){
-                                       mppp = 1;
-                                       break;
+                                       memcpy(&key,key_datum.dptr,sizeof(ippool_key));
+                                       if (!strcmp(key.nas,nas)){
+                                               mppp = 1;
+                                               break;
+                                       }
                                }
                        }
                        nextkey = gdbm_nextkey(data->gdbm, key_datum);
@@ -621,7 +656,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                                 * Find an entry with active == 0
                                 * or an entry that has expired
                                 */
-                               if (entry.active == 0 || (entry.timestamp && ((entry.timeout &&
+                               if (entry.active == 0 || (entry.timestamp && ((entry.timeout && 
                                request->timestamp >= (entry.timestamp + entry.timeout)) ||
                                (data->max_timeout && request->timestamp >= (entry.timestamp + data->max_timeout))))){
                                        datum tmp;
@@ -634,7 +669,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                                         * If we find an entry in the ip index and the number is zero (meaning
                                         * that we haven't allocated the same ip address to another nas/port pair)
                                         * or if we don't find an entry then delete the session entry so
-                                        * that we can change the key
+                                        * that we can change the key (nas/port)
                                         * Else we don't delete the session entry since we haven't yet deallocated the
                                         * corresponding ip address and we continue our search.
                                         */
@@ -683,7 +718,10 @@ static int ippool_postauth(void *instance, REQUEST *request)
                        datum data_datum_tmp;
                        ippool_key key_tmp;
 
-                       memcpy(key_tmp.key,key_str,16);
+                       memset(key_tmp.nas,0,MAX_NAS_NAME_SIZE);
+                       strncpy(key_tmp.nas,nas,MAX_NAS_NAME_SIZE -1 );
+                       key_tmp.port = port;
+                       DEBUG("rlm_ippool: Searching for an entry for nas/port: %s/%u",key_tmp.nas,key_tmp.port);
                        key_datum_tmp.dptr = (char *) &key_tmp;
                        key_datum_tmp.dsize = sizeof(ippool_key);
 
@@ -691,13 +729,13 @@ static int ippool_postauth(void *instance, REQUEST *request)
                        if (data_datum_tmp.dptr != NULL){
 
                                rcode = gdbm_store(data->gdbm, key_datum, data_datum_tmp, GDBM_REPLACE);
-                               free(data_datum_tmp.dptr);
                                if (rcode < 0) {
                                        radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",
                                                data->session_db, gdbm_strerror(gdbm_errno));
                                                pthread_mutex_unlock(&data->op_mutex);
                                        return RLM_MODULE_FAIL;
                                }
+                               free(data_datum_tmp.dptr);
                        }
                }
                else{
@@ -730,19 +768,21 @@ static int ippool_postauth(void *instance, REQUEST *request)
                free(key_datum.dptr);
                entry.active = 1;
                entry.timestamp = request->timestamp;
-               if ((vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL)
-                       entry.timeout = (time_t) vp->vp_integer;
+               if ((vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL)   
+                       entry.timeout = (time_t) vp->lvalue;
                else
                        entry.timeout = 0;
                if (extra)
                        entry.extra = 1;
                data_datum.dptr = (char *) &entry;
                data_datum.dsize = sizeof(ippool_info);
-               memcpy(key.key, key_str, 16);
+               memset(key.nas,0,MAX_NAS_NAME_SIZE);
+               strncpy(key.nas,nas,MAX_NAS_NAME_SIZE - 1);
+               key.port = port;
                key_datum.dptr = (char *) &key;
                key_datum.dsize = sizeof(ippool_key);
 
-               DEBUG2("rlm_ippool: Allocating ip to key: '%s'",hex_str);
+               DEBUG2("rlm_ippool: Allocating ip to nas/port: %s/%u",key.nas,key.port);
                rcode = gdbm_store(data->gdbm, key_datum, data_datum, GDBM_REPLACE);
                if (rcode < 0) {
                        radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",
@@ -774,20 +814,28 @@ static int ippool_postauth(void *instance, REQUEST *request)
                pthread_mutex_unlock(&data->op_mutex);
 
 
-               DEBUG("rlm_ippool: Allocated ip %s to client key: %s",ip_ntoa(str,entry.ipaddr),hex_str);
-               vp = radius_paircreate(request, &request->reply->vps,
-                                      PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR);
-               vp->vp_ipaddr = entry.ipaddr;
+               DEBUG("rlm_ippool: Allocated ip %s to client on nas %s,port %u",ip_ntoa(str,entry.ipaddr),
+                               key.nas,port);
+               if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) {
+                       radlog(L_ERR|L_CONS, "no memory");
+                       return RLM_MODULE_FAIL;
+               }
+               vp->lvalue = entry.ipaddr;
+               ip_ntoa(vp->strvalue, vp->lvalue);
+               pairadd(&request->reply->vps, vp);
 
                /*
                 *      If there is no Framed-Netmask attribute in the
                 *      reply, add one
                 */
                if (pairfind(request->reply->vps, PW_FRAMED_IP_NETMASK) == NULL) {
-                       vp = radius_paircreate(request, &request->reply->vps,
-                                              PW_FRAMED_IP_NETMASK,
-                                              PW_TYPE_IPADDR);
-                       vp->vp_ipaddr = ntohl(data->netmask);
+                       if ((vp = paircreate(PW_FRAMED_IP_NETMASK, PW_TYPE_IPADDR)) == NULL)
+                               radlog(L_ERR|L_CONS, "no memory");
+                       else {
+                               vp->lvalue = ntohl(data->netmask);
+                               ip_ntoa(vp->strvalue, vp->lvalue);
+                               pairadd(&request->reply->vps, vp);
+                       }
                }
 
        }
@@ -806,6 +854,8 @@ static int ippool_detach(void *instance)
 
        gdbm_close(data->gdbm);
        gdbm_close(data->ip);
+       free(data->session_db);
+       free(data->ip_index);
        pthread_mutex_destroy(&data->op_mutex);
 
        free(instance);
@@ -822,11 +872,10 @@ static int ippool_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_ippool = {
-       RLM_MODULE_INIT,
-       "ippool",
+       "IPPOOL",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        ippool_instantiate,             /* instantiation */
-       ippool_detach,                  /* detach */
        {
                NULL,                   /* authentication */
                NULL,                   /* authorization */
@@ -837,4 +886,6 @@ module_t rlm_ippool = {
                NULL,                   /* post-proxy */
                ippool_postauth         /* post-auth */
        },
+       ippool_detach,                  /* detach */
+       NULL,                           /* destroy */
 };
index 917d609..e6a1b75 100755 (executable)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2003,2006  FreeRADIUS Project, http://www.freeradius.org/
+ * Copyright 2003  FreeRADIUS Project, http://www.freeradius.org/
  * Copyright 2003  Edwin Groothuis, edwin@mavetju.org
  * Permission from Edwin Groothuis for release under GPL is archived here:
  * http://lists.cistron.nl/archives/freeradius-devel/2003/09/frm00247.html
  SUCH DAMAGE.
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/libradius.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
 #include <fcntl.h>
 #include <gdbm.h>
-#include "../../include/md5.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
 
 int active=0;
 
@@ -68,8 +71,6 @@ int cflag=0;
 int rflag=0;
 int vflag=0;
 int nflag=0;
-int oflag=0;
-int uflag=0;
 
 typedef struct ippool_info {
     uint32_t        ipaddr;
@@ -80,33 +81,26 @@ typedef struct ippool_info {
 
 
 #define MAX_NAS_NAME_SIZE 64
-typedef struct old_ippool_key {
+typedef struct ippool_key {
     char nas[MAX_NAS_NAME_SIZE];
     unsigned int port;
-} old_ippool_key;
-typedef struct ippool_key {
-    char key[16];
 } ippool_key;
 
 #define MATCH_IP(ip1,ip2) ((ip1)==NULL || strcmp((ip1),(ip2))==0)
 #define MATCH_ACTIVE(info) ((info).active==1 || !aflag)
 
-void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname, char*NASport,int old);
-void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress, int old);
-void tonewformat(char *sessiondbname,char *newsessiondbname);
+void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname, char*NASport);
+void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress);
 void usage(char *argv0);
 
-void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname, char*NASport, int old) {
+void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname, char*NASport) {
     GDBM_FILE sessiondb;
     GDBM_FILE indexdb;
     datum key_datum,data_datum,save_datum;
        datum nextkey;
     ippool_key key;
-    old_ippool_key old_key;
     ippool_info entry;
     struct in_addr ipaddr;
-    char key_str[17];
-    char hex_str[35];
     int num=0;
        int mppp=0;
     int mode=GDBM_WRITER;
@@ -142,27 +136,11 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
 
        /* Basically from rlm_ippool.c */
 
-       if (old){
-               strlcpy(old_key.nas,NASname,sizeof(old_key.nas));
-               old_key.port = port;
-               key_datum.dptr = (char *) &old_key;
-               key_datum.dsize = sizeof(old_ippool_key);
-       }
-       else{
-               char md5_input_str[MAX_STRING_LEN];
-               MD5_CTX md5_context;
-
-               snprintf(md5_input_str,MAX_STRING_LEN, "%s %s",NASname,NASport);
-               MD5Init(&md5_context);
-               MD5Update(&md5_context, md5_input_str, strlen(md5_input_str));
-               MD5Final(key_str, &md5_context);
-               memcpy(key.key,key_str,16);
-               lrad_bin2hex(key_str,hex_str,16);
-               hex_str[32] = '\0';
-               key_datum.dptr = (char *) &key;
-               key_datum.dsize = sizeof(ippool_key);
-       }
-
+       memset(key.nas,0,MAX_NAS_NAME_SIZE);
+       strncpy(key.nas,NASname,MAX_NAS_NAME_SIZE -1 );
+       key.port = port;
+       key_datum.dptr = (char *) &key;
+       key_datum.dsize = sizeof(ippool_key);
 
        data_datum = gdbm_fetch(sessiondb, key_datum);
        if (data_datum.dptr != NULL){
@@ -170,11 +148,8 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
                memcpy(&entry,data_datum.dptr, sizeof(ippool_info));
                free(data_datum.dptr);
                if (entry.active){
-                       if (old)
-                               printf("rlm_ippool_tool: Deleting stale entry for ip/port %s/%u",
+                       printf("rlm_ippool_tool: Deleting stale entry for ip/port %s/%u",
                                        ipaddress, port);
-                       else
-                               printf("rlm_ippool_tool: Deleting stale entry for key: '%s'",hex_str);
                        entry.active = 0;
                        save_datum.dptr = key_datum.dptr;
                        save_datum.dsize = key_datum.dsize;
@@ -230,14 +205,8 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
                                * then we use that for multilink (MPPP) to work properly.
                                */
                                if (strcmp(entry.cli,cli) == 0 && entry.active){
-                                       if (old){
-                                               memcpy(&old_key,key_datum.dptr,sizeof(ippool_key));
-                                               if (!strcmp(old_key.nas,NASname)){
-                                                       mppp = 1;
-                                                       break;
-                                               }
-                                       }
-                                       else{
+                                       memcpy(&key,key_datum.dptr,sizeof(ippool_key));
+                                       if (!strcmp(key.nas,NASname)){
                                                mppp = 1;
                                                break;
                                        }
@@ -284,20 +253,13 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
        if (key_datum.dptr){
                if (found && ! mppp){
                        datum key_datum_tmp,data_datum_tmp;
-                       old_ippool_key old_key_tmp;
                        ippool_key key_tmp;
-                       if (old){
-                               strlcpy(old_key_tmp.nas,NASname,
-                                       sizeof(old_key_tmp.nas));
-                               old_key_tmp.port=port;
-                               key_datum_tmp.dptr = (char *) &old_key_tmp;
-                               key_datum_tmp.dsize = sizeof(old_ippool_key);
-                       }
-                       else{
-                               memcpy(key_tmp.key,key_str,16);
-                               key_datum_tmp.dptr = (char *) &key_tmp;
-                               key_datum_tmp.dsize = sizeof(ippool_key);
-                       }
+                       memset(key_tmp.nas,0,MAX_NAS_NAME_SIZE);
+                       strncpy(key_tmp.nas,NASname,MAX_NAS_NAME_SIZE - 1);
+                       key_tmp.port=port;
+                       key_datum_tmp.dptr = (char *) &key_tmp;
+                       key_datum_tmp.dsize = sizeof(ippool_key);
+
                        data_datum_tmp = gdbm_fetch(sessiondb, key_datum_tmp);
                        if (data_datum_tmp.dptr != NULL) {
                                rcode = gdbm_store(sessiondb, key_datum, data_datum_tmp, GDBM_REPLACE);
@@ -316,10 +278,8 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
                        else {
                                if (mppp)
                                        extra = 1;
-#if 0
-                               if (!mppp)
-                                       printf("Error in if statements!!!\n");
-#endif
+//                             if (!mppp)
+//                                     printf("Error in if statements!!!\n");
                        }
                }
                free(key_datum.dptr);
@@ -328,20 +288,12 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
                        entry.extra=1;
                data_datum.dptr = (char *) &entry;
                data_datum.dsize = sizeof(ippool_info);
-
-               if (old){
-                       strlcpy(old_key.nas,NASname,sizeof(old_key.nas));
-                       old_key.port = port;
-                       key_datum.dptr = (char *) &old_key;
-                       key_datum.dsize = sizeof(old_ippool_key);
-                       printf("rlm_ippool_tool: Allocating ip to nas/port: %s/%u\n",old_key.nas,old_key.port);
-               }
-               else{
-                       memcpy(key.key,key_str,16);
-                       key_datum.dptr = (char *) &key;
-                       key_datum.dsize = sizeof(ippool_key);
-                       printf("rlm_ippool_tool: Allocating ip to key: '%s'\n",hex_str);
-               }
+               memset(key.nas,0,MAX_NAS_NAME_SIZE);
+               strncpy(key.nas,NASname,MAX_NAS_NAME_SIZE -1 );
+               key.port = port;
+               key_datum.dptr = (char *) &key;
+               key_datum.dsize = sizeof(ippool_key);
+               printf("rlm_ippool_tool: Allocating ip to nas/port: %s/%u\n",key.nas,key.port);
                rcode = gdbm_store(sessiondb, key_datum, data_datum, GDBM_REPLACE);
                if (rcode < 0) {
                        printf("rlm_ippool_tool: Failed storing data to %s: %s\n",
@@ -373,80 +325,22 @@ void addip(char *sessiondbname,char *indexdbname,char *ipaddress, char* NASname,
                        return;
                }
 
-               if (old)
-                       printf("rlm_ippool_tool: Allocated ip %s to client on nas %s,port %u\n",
-                               ipaddress, old_key.nas,port);
-               else
-                       printf("rlm_ippool_tool: Allocated ip %s to key  '%s'\n",ipaddress,hex_str);
+               printf("rlm_ippool_tool: Allocated ip %s to client on nas %s,port %u\n",
+                               ipaddress, key.nas,port);
 
        }
     gdbm_close(indexdb);
     gdbm_close(sessiondb);
 }
-void tonewformat(char *sessiondbname,char *newsessiondbname){
-    GDBM_FILE sessiondb;
-    GDBM_FILE newsessiondb;
-    datum key_datum,keynext_datum,data_datum,newkey_datum;
-    old_ippool_key old_key;
-    ippool_key key;
-    char key_str[17];
-    char hex_str[35];
-    int rcode;
-
-    sessiondb=gdbm_open(sessiondbname,512,GDBM_READER,0,NULL);
-    newsessiondb=gdbm_open(newsessiondbname,512,GDBM_NEWDB,0,NULL);
-
-    if (sessiondb==NULL || newsessiondb==NULL) return;
-
-    memset(key_str,0,17);
-
-    key_datum=gdbm_firstkey(sessiondb);
-    while (key_datum.dptr) {
-       keynext_datum=gdbm_nextkey(sessiondb,key_datum);
-       if (key_datum.dsize==sizeof(struct old_ippool_key)) {
-               char md5_input_str[MAX_STRING_LEN];
-               MD5_CTX md5_context;
-
-               memcpy(&old_key,key_datum.dptr,sizeof(struct old_ippool_key));
-               snprintf(md5_input_str,MAX_STRING_LEN, "%s %d",old_key.nas,old_key.port);
-               MD5Init(&md5_context);
-               MD5Update(&md5_context, md5_input_str, strlen(md5_input_str));
-               MD5Final(key_str, &md5_context);
-               memcpy(key.key,key_str,16);
-               lrad_bin2hex(key_str,hex_str,16);
-               hex_str[32] = '\0';
-               printf("rlm_ippool_tool: Transforming pair nas/port (%s/%d) to md5 '%s'\n",
-                       old_key.nas,old_key.port,hex_str);
-               newkey_datum.dptr = (char *) &key;
-               newkey_datum.dsize = sizeof(ippool_key);
-               data_datum=gdbm_fetch(sessiondb,key_datum);
-               if (data_datum.dptr!=NULL){
-                   rcode=gdbm_store(newsessiondb,newkey_datum,data_datum,GDBM_REPLACE);
-                   if (rcode < 0) {
-                               printf("Failed to update new file %s: %s\n",newsessiondbname,gdbm_strerror(gdbm_errno));
-                               gdbm_close(newsessiondb);
-                               gdbm_close(sessiondb);
-                               return;
-                       }
-               }
-       }
-       key_datum=keynext_datum;
-    }
-    gdbm_close(newsessiondb);
-    gdbm_close(sessiondb);
-}
 
-void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress, int old) {
+void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress) {
     GDBM_FILE sessiondb;
     GDBM_FILE indexdb;
     datum key_datum,keynext_datum,data_datum,save_datum;
-    old_ippool_key old_key;
     ippool_key key;
     ippool_info info;
     struct in_addr ipaddr;
     int num;
-    char key_str[17];
-    char hex_str[35];
     char *ip;
     int mode=GDBM_READER;
     int rcode;
@@ -457,16 +351,11 @@ void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress, int old) {
 
     if (sessiondb==NULL || indexdb==NULL) return;
 
-    memset(key_str,0,17);
-
     key_datum=gdbm_firstkey(sessiondb);
     while (key_datum.dptr) {
        keynext_datum=gdbm_nextkey(sessiondb,key_datum);
-       if (key_datum.dsize==sizeof(struct ippool_key) || key_datum.dsize==sizeof(struct old_ippool_key)) {
-           if (old)
-                memcpy(&old_key,key_datum.dptr,sizeof(struct old_ippool_key));
-           else
-                memcpy(&key,key_datum.dptr,sizeof(struct ippool_key));
+       if (key_datum.dsize==sizeof(struct ippool_key)) {
+           memcpy(&key,key_datum.dptr,sizeof(struct ippool_key));
 
            data_datum=gdbm_fetch(sessiondb,key_datum);
            if (data_datum.dptr!=NULL) {
@@ -476,27 +365,19 @@ void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress, int old) {
                ip=inet_ntoa(ipaddr);
 
                if (info.active) active++;
-               if (vflag && MATCH_IP(ipaddress,ip) && MATCH_ACTIVE(info)){
-                   if (old)
-                       printf("NAS:%s port:0x%x - ",old_key.nas,old_key.port);
-                   else{
-                       memcpy(key_str,key.key,16);
-                       lrad_bin2hex(key_str,hex_str,16);
-                       hex_str[32] = '\0';
-                       printf("KEY: '%s' - ",hex_str);
-                   }
-               }
+               if (vflag && MATCH_IP(ipaddress,ip) && MATCH_ACTIVE(info))
+                   printf("NAS:%s port:0x%x - ",key.nas,key.port);
                if (!vflag && aflag && info.active && MATCH_IP(ipaddress,ip))
                    printf("%s\n",ip);
                else if (vflag && MATCH_IP(ipaddress,ip) && MATCH_ACTIVE(info))
                    printf("ipaddr:%s active:%d cli:%s",
                        inet_ntoa(ipaddr),info.active,info.cli);
 
-               /*
-                * algorythm copied from rlm_ippool.c:
-                * - set active to zero
-                * - set number of sessions to zero
-                */
+               //
+               // algorythm copied from rlm_ippool.c:
+               // - set active to zero
+               // - set number of sessions to zero
+               //
                if (rflag && MATCH_IP(ipaddress,ip)) {
                    info.active=0;
                        save_datum.dptr = key_datum.dptr;
@@ -544,16 +425,8 @@ void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress, int old) {
                if (vflag && MATCH_IP(ipaddress,ip) && MATCH_ACTIVE(info))
                    printf("\n");
            } else
-               if (vflag && ipaddress==NULL){
-                   if (old)
-                       printf("NAS:%s port:0x%x\n",old_key.nas,old_key.port);
-                   else{
-                       memcpy(key_str,key.key,16);
-                       lrad_bin2hex(key_str,hex_str,16);
-                       hex_str[32] = '\0';
-                       printf("KEY: '%s' - ",hex_str);
-                   }
-               }
+               if (vflag && ipaddress==NULL)
+                   printf("NAS:%s port:0x%x\n",key.nas,key.port);
        }
        key_datum=keynext_datum;
     }
@@ -561,19 +434,16 @@ void viewdb(char *sessiondbname,char *indexdbname,char *ipaddress, int old) {
     gdbm_close(sessiondb);
 }
 
-void NEVER_RETURNS usage(char *argv0) {
-    printf("Usage: %s [-a] [-c] [-o] [-v] <session-db> <index-db> [ipaddress]\n",argv0);
+void usage(char *argv0) {
+    printf("Usage: %s [-a] [-c] [-v] <session-db> <index-db> [ipaddress]\n",argv0);
     printf("-a: print all active entries\n");
     printf("-c: report number of active entries\n");
     printf("-r: remove active entries\n");
     printf("-v: verbose report of all entries\n");
-    printf("-o: Assume old database format (nas/port pair, not md5 output)\n");
     printf("If an ipaddress is specified then that address is used to\n");
     printf("limit the actions or output.\n");
     printf("Usage: %s -n  <session-db> <index-db> <ipaddress> <nasIP> <nasPort>\n",argv0);
     printf("-n: Mark the entry nasIP/nasPort as having ipaddress\n");
-    printf("Usage: %s -u <session-db> <new-session-db>\n",argv0);
-    printf("-u: Update old format database to new.\n");
     exit(0);
 }
 
@@ -581,28 +451,24 @@ int main(int argc,char **argv) {
     int ch;
     char *argv0=argv[0];
 
-    while ((ch=getopt(argc,argv,"acrvnou"))!=-1)
+    while ((ch=getopt(argc,argv,"acrvn"))!=-1)
        switch (ch) {
        case 'a': aflag++;break;
        case 'c': cflag++;break;
        case 'r': rflag++;break;
        case 'v': vflag=1;break;
        case 'n': nflag=1;break;
-       case 'o': oflag=1;break;
-       case 'u': uflag=1;break;
        default: usage(argv0);
        }
     argc -= optind;
     argv += optind;
 
-    if ((argc==2 || argc==3) && !nflag && !uflag) {
-               viewdb(argv[0],argv[1],argv[2],oflag);
+    if ((argc==2 || argc==3) && !nflag) {
+               viewdb(argv[0],argv[1],argv[2]);
                if (cflag) printf("%d\n",active);
        } else
                if (argc==5 && nflag)
-                       addip(argv[0],argv[1],argv[2],argv[3],argv[4],oflag);
-               else if (argc==2 && uflag)
-                       tonewformat(argv[0],argv[1]);
+                       addip(argv[0],argv[1],argv[2],argv[3],argv[4]);
                else
                        usage(argv0);
     return 0;
index 5c57b01..9e71b4a 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.8 .
+# From configure.in Revision: 1.7 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -912,7 +912,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1832,7 +1832,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1890,7 +1891,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2006,7 +2008,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2060,7 +2063,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2105,7 +2109,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2149,7 +2154,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2514,7 +2520,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2537,8 +2544,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2567,7 +2574,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2645,7 +2653,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2668,8 +2677,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2724,7 +2733,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2747,8 +2757,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2777,7 +2787,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2882,7 +2893,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2905,8 +2917,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -2962,7 +2974,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2985,8 +2998,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -3015,7 +3028,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3120,7 +3134,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3143,8 +3158,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -3205,7 +3220,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3228,8 +3244,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -3258,7 +3274,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3363,7 +3380,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3386,8 +3404,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -3444,7 +3462,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3467,8 +3486,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -3497,7 +3516,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3602,7 +3622,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3625,8 +3646,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -4480,6 +4501,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4518,12 +4544,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index bc9f21e..a3b82fd 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_krb5.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_krb5])
@@ -51,16 +50,16 @@ if test x$with_[]modname != xno; then
        )
 
        smart_try_dir=$rlm_krb5_include_dir
-       FR_SMART_CHECK_INCLUDE(krb5.h)
+       AC_SMART_CHECK_INCLUDE(krb5.h)
 
        smart_try_dir=$rlm_krb5_lib_dir
 
-       FR_SMART_CHECK_LIB(k5crypto, krb5_encrypt_data)
+       AC_SMART_CHECK_LIB(k5crypto, krb5_encrypt_data)
        if test "x$ac_cv_lib_k5crypto_krb5_encrypt_data" = "xyes"; then
                krb5libcrypto="-lk5crypto"
        fi
 
-       FR_SMART_CHECK_LIB(crypto, DH_new)
+       AC_SMART_CHECK_LIB(crypto, DH_new)
        if test "x$ac_cv_lib_crypto_DH_new" = "xyes"; then
                krb5libcrypto="-lcrypto"
        fi
@@ -69,12 +68,12 @@ if test x$with_[]modname != xno; then
                AC_MSG_WARN([neither krb5 'k5crypto' nor 'crypto' libraries are found!])
        fi
 
-       FR_SMART_CHECK_LIB(com_err, set_com_err_hook)
+       AC_SMART_CHECK_LIB(com_err, set_com_err_hook)
        if test "x$ac_cv_lib_com_err_set_com_err_hook" != "xyes"; then
-               AC_MSG_WARN([the comm_err library isn't found!])
+               AC_MSG_WARN([the comm_err library isn't found!]) 
        fi
 
-       FR_SMART_CHECK_LIB(krb5, krb5_init_context)
+       AC_SMART_CHECK_LIB(krb5, krb5_init_context)
        if test "x$ac_cv_lib_krb5_krb5_init_context" != "xyes"; then
                fail="$fail krb5"
        fi
@@ -90,7 +89,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index a5ed511..3ce1e32 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Nathan Neulinger <nneul@umr.edu>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
+static const char rcsid[] = "$Id$";
+
+#include       "autoconf.h"
+#include       "libradius.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "radiusd.h"
+#include       "modules.h"
 
 /* krb5 includes */
 #include <krb5.h>
@@ -38,7 +45,7 @@ typedef struct rlm_krb5_t {
        krb5_context *context;
 } rlm_krb5_t;
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        { "keytab", PW_TYPE_STRING_PTR,
          offsetof(rlm_krb5_t,keytab), NULL, NULL },
        { "service_principal", PW_TYPE_STRING_PTR,
@@ -68,7 +75,7 @@ static int verify_krb5_tgt(krb5_context context, rlm_krb5_t *instance,
                        *servername = '\0';
                }
 
-               strlcpy(service,instance->service_princ,sizeof(service));
+               strncpy(service,instance->service_princ,sizeof(service));
                service[sizeof(service)-1] = '\0';
 
                if (servername != NULL) {
@@ -86,7 +93,7 @@ static int verify_krb5_tgt(krb5_context context, rlm_krb5_t *instance,
                return RLM_MODULE_REJECT;
        }
 
-       strlcpy(phost, krb5_princ_component(c, princ, 1)->data, BUFSIZ);
+       strncpy(phost, krb5_princ_component(c, princ, 1)->data, BUFSIZ);
        phost[BUFSIZ - 1] = '\0';
 
        /*
@@ -239,7 +246,7 @@ static int krb5_auth(void *instance, REQUEST *request)
         *  Ensure that we're being passed a plain-text password,
         *  and not anything else.
         */
-       if (request->password->attribute != PW_USER_PASSWORD) {
+       if (request->password->attribute != PW_PASSWORD) {
                radlog(L_AUTH, "rlm_krb5: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
                return RLM_MODULE_INVALID;
        }
@@ -247,8 +254,8 @@ static int krb5_auth(void *instance, REQUEST *request)
        /*
         *      shortcuts
         */
-       user = request->username->vp_strvalue;
-       pass = request->password->vp_strvalue;
+       user = request->username->strvalue;
+       pass = request->password->strvalue;
 
        /* Generate a unique cache_name */
        memset(cache_name, 0, sizeof(cache_name));
@@ -348,7 +355,7 @@ static int krb5_auth(void *instance, REQUEST *request)
         *  Ensure that we're being passed a plain-text password,
         *  and not anything else.
         */
-       if (request->password->attribute != PW_USER_PASSWORD) {
+       if (request->password->attribute != PW_PASSWORD) {
                radlog(L_AUTH, "rlm_krb5: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
                return RLM_MODULE_INVALID;
        }
@@ -356,8 +363,8 @@ static int krb5_auth(void *instance, REQUEST *request)
        /*
         *      shortcuts
         */
-       user = request->username->vp_strvalue;
-       pass = request->password->vp_strvalue;
+       user = request->username->strvalue;
+       pass = request->password->strvalue;
 
        if ( (r = krb5_parse_name(context, user, &userP)) ) {
                radlog(L_AUTH, "rlm_krb5: [%s] krb5_parse_name failed: %s",
@@ -393,19 +400,20 @@ static int krb5_auth(void *instance, REQUEST *request)
 #endif /* HEIMDAL_KRB5 */
 
 module_t rlm_krb5 = {
-       RLM_MODULE_INIT,
-       "Kerberos",
-       RLM_TYPE_THREAD_UNSAFE, /* type: not thread safe */
-       krb5_instantiate,               /* instantiation */
-       krb5_detach,                    /* detach */
-       {
-               krb5_auth,              /* authenticate */
-               NULL,                   /* authorize */
-               NULL,                   /* pre-accounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "Kerberos",
+  RLM_TYPE_THREAD_UNSAFE,      /* type: not thread safe */
+  NULL,                                /* initialize */
+  krb5_instantiate,            /* instantiation */
+  {
+         krb5_auth,            /* authenticate */
+         NULL,                 /* authorize */
+         NULL,                 /* pre-accounting */
+         NULL,                 /* accounting */
+         NULL,                 /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  krb5_detach,                 /* detach */
+  NULL,                                /* destroy */
 };
index 53aa0ba..f948915 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.15 .
+# From configure.in Revision: 1.10.2.4 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -910,7 +910,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1833,7 +1833,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1891,7 +1892,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2007,7 +2009,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2061,7 +2064,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2106,7 +2110,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2150,7 +2155,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2315,7 +2321,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2382,7 +2389,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2459,7 +2467,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2482,8 +2491,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2512,7 +2521,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2617,7 +2627,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2640,8 +2651,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -2697,7 +2708,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2720,8 +2732,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2750,7 +2762,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2855,7 +2868,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2878,8 +2892,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -2938,7 +2952,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2961,8 +2976,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2991,7 +3006,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3069,7 +3085,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3092,8 +3109,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -3178,7 +3195,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3271,7 +3289,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3364,7 +3383,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3429,7 +3449,7 @@ if test "${with_edir+set}" = set; then
   withval="$with_edir"
    case "$withval" in
     yes)
-       SMART_CFLAGS="$SMART_CFLAGS -DNOVELL_UNIVERSAL_PASSWORD"
+       SMART_CFLAGS="$SMART_CFLAGS -DNOVELL_UNIVERSAL_PASSWORD -DNOVELL"
        edir="edir_ldapext.c"
         ;;
     *)
@@ -4254,6 +4274,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4292,12 +4317,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 2465f9d..a6bfe2f 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_ldap.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_ldap])
@@ -8,19 +7,14 @@ SMART_LIBS=
 SMART_CLFAGS=
 if test x$with_[]modname != xno; then
 
-       dnl ############################################################
-       dnl # Check for compiler
-       dnl ############################################################
        AC_PROG_CC
 
-       dnl ############################################################
-       dnl # Check for command line options
-       dnl ############################################################
+       AC_CHECK_LIB(resolv, inet_aton)
 
        dnl extra argument: --with-rlm-ldap-lib-dir
        rlm_ldap_lib_dir=
        AC_ARG_WITH(rlm-ldap-lib-dir,
-       [  --with-rlm-ldap-lib-dir=DIR       directory for LDAP library files []],
+       [  --with-rlm-ldap-lib-dir=DIR       Directory for LDAP library files []],
        [ case "$withval" in
            no)
                AC_MSG_ERROR(Need rlm-ldap-lib-dir)
@@ -34,9 +28,9 @@ if test x$with_[]modname != xno; then
        )
 
        dnl extra argument: --with-rlm-ldap-include-dir
-       rlm_ldap_include_dir=
+       rlm_ldap_inc_dir=
        AC_ARG_WITH(rlm-ldap-include-dir,
-       [  --with-rlm-ldap-include-dir=DIR   directory for LDAP include files []],
+       [  --with-rlm-ldap-include-dir=DIR   Directory for LDAP include files []],
        [ case "$withval" in
            no)
                AC_MSG_ERROR(Need rlm-ldap-include-dir)
@@ -49,82 +43,57 @@ if test x$with_[]modname != xno; then
          esac ]
        )
 
-       dnl extra argument: --enable-shared --disable-shared
-       AC_ENABLE_SHARED
-
-       dnl OpenLDAP doesn't provide an autoconf test for their libldap,
-       dnl and we can't reasonably check for all the dependancies for
-       dnl every version and every set of options.
-       if test "x$enable_shared" = "xno"; then
-               AC_MSG_WARN(Static linking with libldap will probably result in unresolved symbols.)
-       fi
+       smart_try_dir=$rlm_ldap_include_dir
+       AC_SMART_CHECK_INCLUDE(lber.h)
+       AC_SMART_CHECK_INCLUDE(ldap.h)
 
-       dnl extra argument: --with-threads
-       rlm_ldap_with_threads=yes
-       AC_ARG_WITH(threads,
-       [  --with-threads          use threads, if available. (default=yes) ],
-       [ case "$withval" in
-           no)
-               rlm_ldap_with_threads=no
-               ;;
-           *)
-               ;;
-           esac ])
-
-       dnl ############################################################
-       dnl # Check for libraries
-       dnl ############################################################
-
-       dnl pthread stuff is usually in -lpthread
-       dnl or in -lc_r, on *BSD
-       if test "x$rlm_ldap_with_threads" = "xyes"; then
-           AC_CHECK_LIB(pthread, pthread_create,
-                        [ LIBS="-lpthread $LIBS" ],
-                        AC_CHECK_LIB(c_r, pthread_create,
-                                     [ LIBS="-lc_r $LIBS" ],
-                                     [ rlm_ldap_with_threads="no" ]
-                                     )
-                        )
-       fi
+       AC_SMART_CHECK_LIB(sasl, sasl_encode)
+       AC_SMART_CHECK_LIB(crypto, DH_new)
+       AC_SMART_CHECK_LIB(ssl, SSL_new)
 
-       dnl Try only "-lldap_r" or "-lldap"
-       dnl Static linking will probably not work, but nobody ever
-       dnl complained about it.
        smart_try_dir=$rlm_ldap_lib_dir
-       if test "x$rlm_ldap_with_threads" = "xyes"; then
-           FR_SMART_CHECK_LIB(ldap_r, ldap_init)
-           if test "x$ac_cv_lib_ldap_r_ldap_init" != "xyes"; then
-               fail="$fail libldap_r"
-           fi
-       else
-           FR_SMART_CHECK_LIB(ldap, ldap_init)
-           if test "x$ac_cv_lib_ldap_ldap_init" != "xyes"; then
-               fail="$fail libldap"
-           fi
-       fi
+       AC_SMART_CHECK_LIB(lber, ber_init)
+        if test "x$ac_cv_lib_lber_ber_init" != "xyes"; then
+         fail="$fail liblber"
+        else
+          if test "x$ac_cv_header_pthread_h" = "xyes"; then
+           AC_SMART_CHECK_LIB(ldap_r, ldap_init)
+            if test "x$ac_cv_lib_ldap_r_ldap_init" != "xyes"; then
+             fail="$fail libldap_r"
+           else
+               libldap=ldap_r
+            fi
+          else
+           AC_SMART_CHECK_LIB(ldap, ldap_init)
+            if test "x$ac_cv_lib_ldap_ldap_init" != "xyes"; then
+             fail="$fail libldap"
+           else
+               libldap=ldap
+           fi
+          fi
+        fi
+
+       if test x"$libldap" != "x"; then
+         AC_SMART_CHECK_LIB("$libldap", ldap_start_tls_s)
+
+         if test "x${ac_cv_lib_ldap_ldap_start_tls_s}${ac_cv_lib_ldap_r_ldap_start_tls_s}" != "x"; then
+            SMART_CFLAGS="$SMART_CFLAGS -DHAVE_LDAP_START_TLS"
+         fi
+      
+         AC_SMART_CHECK_LIB("$libldap", ldap_initialize)
+
+         if test "x${ac_cv_lib_ldap_ldap_initialize}${ac_cv_lib_ldap_r_ldap_initialize}" != "x"; then
+            SMART_CFLAGS="$SMART_CFLAGS -DHAVE_LDAP_INITIALIZE"
+         fi
+      
+         AC_SMART_CHECK_LIB("$libldap", ldap_int_tls_config)
+
+         if test "x${ac_cv_lib_ldap_ldap_int_tls_config}${ac_cv_lib_ldap_r_ldap_int_tls_config}" != "x"; then
+            SMART_CFLAGS="$SMART_CFLAGS -DHAVE_LDAP_INT_TLS_CONFIG"
+         fi
 
-       dnl ############################################################
-       dnl # Check for header files
-       dnl ############################################################
-
-       smart_try_dir=$rlm_ldap_include_dir
-       FR_SMART_CHECK_INCLUDE(ldap.h)
-       if test "$ac_cv_header_ldap_h" != "yes"; then
-         fail="$fail ldap.h"
        fi
 
-       dnl ############################################################
-       dnl # Check for library functions
-       dnl ############################################################
-
-       if test "x$fail" = "x"; then
-           AC_CHECK_FUNC(ldap_start_tls_s,
-               [ SMART_CFLAGS="$SMART_CFLAGS -DHAVE_LDAP_START_TLS" ])
-           AC_CHECK_FUNC(ldap_initialize,
-               [ SMART_CFLAGS="$SMART_CFLAGS -DHAVE_LDAP_INITIALIZE" ])
-           AC_CHECK_FUNC(ldap_int_tls_config,
-               [ SMART_CFLAGS="$SMART_CFLAGS -DHAVE_LDAP_INT_TLS_CONFIG" ])
-       fi
 
        targetname=modname
 else
@@ -139,10 +108,10 @@ if test x"$fail" != x""; then
                AC_MSG_WARN([silently not building ]modname[.])
                AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.])
                if test x"$headersuggestion" != x; then
-                       AC_MSG_WARN([$headersuggestion])
+                       AC_MSG_WARN([$headersuggestion]) 
                fi
                if test x"$libsuggestion" != x; then
-                       AC_MSG_WARN([$libsuggestion])
+                       AC_MSG_WARN([$libsuggestion]) 
                fi
                targetname=""
        fi
@@ -152,7 +121,7 @@ dnl extra argument: --with-edir
 dnl If using Novell eDirectory, enable UP and Novell specific code
 WITH_EDIRECTORY=no
 AC_ARG_WITH(edir,
-[  --with-edir             enable Novell eDirectory integration.  (default=no) ],
+[  --with-edir           Enable Novell eDirectory integration.  (default=no) ],
 [ case "$withval" in
     yes)
        SMART_CFLAGS="$SMART_CFLAGS -DNOVELL_UNIVERSAL_PASSWORD -DNOVELL"
index 8b4b7f5..31eefa7 100644 (file)
@@ -1,8 +1,8 @@
-/*
+/* 
  * Copyright (C) 2002-2004 Novell, Inc.
  *
  * edir_ldapext.c  LDAP extension for reading eDirectory universal password
- *
+ * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as published
  * by the Free Software Foundation.
  *
  * To contact Novell about this file by physical or electronic mail, you may
  * find current contact  information at www.novell.com.
- *
- * Copyright 2006 The FreeRADIUS Server Project.
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+ */ 
 
 #include <ldap.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <strings.h>
-
 /* NMAS error codes */
 #define NMAS_E_BASE                       (-1600)
 
@@ -54,9 +47,9 @@ RCSID("$Id$")
 /* OID of LDAP extension call to perform NMAS authentication */
 #define RADAUTH_OID_NMAS_AUTH_REQUEST         "2.16.840.1.113719.1.510.100.1"
 #define RADAUTH_OID_NMAS_AUTH_REPLY           "2.16.840.1.113719.1.510.100.2"
-
+                                                                                                                             
 #define RADAUTH_LDAP_EXT_VERSION 1
-
+                                                                                                                             
 #define REQUEST_CHALLENGED 1
 
 
@@ -139,8 +132,8 @@ int berEncodePasswordData(
                err = 0;
        }
 
-       /*
-        * Convert the BER we just built to a berval that we'll send with the extended request.
+       /* 
+        * Convert the BER we just built to a berval that we'll send with the extended request. 
         */
        if(ber_flatten(requestBer, requestBV) == LBER_ERROR)
        {
@@ -206,7 +199,7 @@ int berDecodeLoginData(
                                memcpy(retData, retOctStr, retOctStrLen);
                        }
                        else if (!err)
-                       {
+                       {       
                                err = NMAS_E_BUFFER_OVERFLOW;
                        }
 
@@ -317,7 +310,7 @@ int nmasldap_get_password(
        /* Do we have a good returned berval? */
        if(!replyBV)
        {
-               /*
+               /* 
                 * No; returned berval means we experienced a rather drastic error.
                 * Return operations error.
                 */
@@ -401,7 +394,7 @@ int berEncodeAuthData(
 {
         int err = 0, rc=0;
         BerElement *requestBer = NULL;
-
+                                                                                                                             
         char    * utf8ObjPtr = NULL;
         int     utf8ObjSize = 0;
         char    * utf8PwdPtr = NULL;
@@ -413,29 +406,29 @@ int berEncodeAuthData(
         char    * utf8SeqPtr = NULL;
         int     utf8SeqSize = 0;
         int state_present = 0;
-
+                                                                                                                             
         utf8ObjSize = strlen(objectDN)+1;
         utf8ObjPtr = objectDN;
-
+                                                                                                                             
         utf8PwdSize = strlen(pwd);
         utf8PwdPtr = pwd;
-
+                                                                                                                             
         utf8SeqSize = strlen(sequence)+1;
         utf8SeqPtr = sequence;
-
+                                                                                                                             
         utf8NasIPSize = strlen(NasIP)+1;
         utf8NasIPPtr = NasIP;
-
+                                                                                                                             
         /* Allocate a BerElement for the request parameters.*/
         if((requestBer = ber_alloc()) == NULL)
         {
                 err = NMAS_E_FRAG_FAILURE;
                 goto Cleanup;
         }
-
+                                                                                                                             
         /* BER encode the NMAS Version, the objectDN, and the password */
         rc = ber_printf(requestBer, "{ioooo", RADAUTH_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize, utf8SeqPtr, utf8SeqSize, utf8NasIPPtr, utf8NasIPSize);
-
+                                                                                                                             
         if( *auth_state == -2)
         {
                 utf8StateSize = strlen(state)+1;
@@ -447,7 +440,7 @@ int berEncodeAuthData(
         {
                 rc = ber_printf(requestBer, "i}", state_present);
         }
-
+                                                                                                                             
         if (rc < 0)
         {
                 err = NMAS_E_FRAG_FAILURE;
@@ -465,14 +458,14 @@ int berEncodeAuthData(
                 err = NMAS_E_FRAG_FAILURE;
                 goto Cleanup;
         }
-
+                                                                                                                             
 Cleanup:
-
+                                                                                                                             
         if(requestBer)
         {
                 ber_free(requestBer, 1);
         }
-
+                                                                                                                             
         return err;
 } /* End of berEncodeAuthData */
 
@@ -500,7 +493,7 @@ int berDecodeAuthData(
         int rc=0, err = 0;
         BerElement *replyBer = NULL;
         struct berval   challenge = {0};
-
+                                                                                                                             
         if((replyBer = ber_init(replyBV)) == NULL)
         {
                 err = NMAS_E_SYSTEM_RESOURCES; // fix err code
@@ -525,16 +518,16 @@ int berDecodeAuthData(
                         }
                 }
         }
-
+                                                                                                                             
 Cleanup:
         if(replyBer)
         {
                 ber_free(replyBer, 1);
         }
-
+                                                                                                                             
         return err;
 }/* End of berDecodeLoginData */
-
+                                                                                                                             
 /* -----------------------------------------------------------------------
  *      radLdapXtnNMASAuth()
  *      ==============================
@@ -555,34 +548,34 @@ int radLdapXtnNMASAuth(
 )
 {
         int err = 0;
-
+                                                                                                                             
         struct berval *requestBV = NULL;
         char *replyOID = NULL;
         struct berval *replyBV = NULL;
         int errCode;
         char *challenge;
         size_t challengesize;
-
+                                                                                                                             
         challengesize = *statesize;
         challenge = (char *)malloc(challengesize+2);
                 if(challenge == NULL)
                         {
                                 return NMAS_E_INSUFFICIENT_MEMORY;
                         }
-
+                                                                                                                             
          /* Validate char    parameters. */
         if(objectDN == NULL || (strlen(objectDN) == 0) || statesize == NULL || NasIPaddr == NULL || ld == NULL)
         {
                 return NMAS_E_INVALID_PARAMETER;
         }
-
+                                                                                                                             
         err = berEncodeAuthData(&requestBV, objectDN, pwd, sequence, NasIPaddr, state, auth_state);
-
+                                                                                                                             
         if(err)
         {
                 goto Cleanup;
         }
-
+                                                                                                                             
         /* Call the ldap_extended_operation (synchronously) */
         if((err = ldap_extended_operation_s(ld, RADAUTH_OID_NMAS_AUTH_REQUEST, requestBV, NULL, NULL, &replyOID, &replyBV))!=0)
         {
@@ -594,14 +587,14 @@ int radLdapXtnNMASAuth(
                 err = NMAS_E_NOT_SUPPORTED; // change error values
                 goto Cleanup;
         }
-
+                                                                                                                             
         /* Is this what we were expecting to get back. */
         if(strcmp(replyOID, RADAUTH_OID_NMAS_AUTH_REPLY))
         {
                 err = NMAS_E_NOT_SUPPORTED; // change return value
                 goto Cleanup;
         }
-
+                                                                                                                             
         /* Do we have a good returned berval? */
         if(!replyBV)
         {
@@ -613,7 +606,7 @@ int radLdapXtnNMASAuth(
                 goto Cleanup;
         }
         err = berDecodeAuthData(replyBV, &errCode, &challengesize, challenge, auth_state);
-
+                                                                                                                             
 /* errCode return error in case of AUTH-REJECT */
         if (!err && challengesize!= 0)
         {
@@ -624,35 +617,35 @@ int radLdapXtnNMASAuth(
                 }
                 *statesize = challengesize; /* does not include null termination */
         }
-
+                                                                                                                             
 Cleanup:
         /* Free memory allocated for challenge  */
         if(challenge)
         {
                 free(challenge);
         }
-
+                                                                                                                             
         if(replyBV)
         {
                 ber_bvfree(replyBV);
         }
-
+                                                                                                                             
         /* Free the return OID string if one was returned. */
         if(replyOID)
         {
                 ldap_memfree(replyOID);
         }
-
+                                                                                                                             
         /* Free memory allocated while building the request ber and berval. */
         if(requestBV)
         {
                 ber_bvfree(requestBV);
         }
-
+                                                                                                                             
 #ifdef  NOT_N_PLAT_NLM
         SetThreadGroupID(currentThreadGroupID);
 #endif
-
+                                                                                                                             
         /* Return the appropriate error/success code. */
         return err;
 }/* End of radLdapXtnNMASAuth */
index 86385be..3460cfa 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *   Copyright 2004,2006 The FreeRADIUS Server Project.
+ * This module is based on LDAP patch to Cistron radiusd by James Golovich
+ * <james@wwnet.net>, which in turn was based mostly on a Mysql+Cistron patch
+ * from <oyarzun@wilmington.net>
+ *
+ * 17 Jan 2000,        Adrian Pavlykevych <pam@polynet.lviv.ua>
+ *     - OpenLDAP SDK porting, basic TLS support, LDAP authorization,
+ *       fault tolerance with multiple LDAP server support
+ * 24 May 2000,        Adrian Pavlykevych <pam@polynet.lviv.ua>
+ *     - Converting to new configuration file format, futher improvements
+ *       in fault tolerance, threaded operation
+ * 12 Dec 2000,        Adrian Pavlykevych <pam@polynet.lviv.ua>
+ *     - Added preliminary support for multiple instances
+ *     - moved all instance configuration into dynamicly allocated structure
+ *     - Removed connection maintenance thread and all attempts for multihreading
+ *       the module itself. OpenLDAP SDK is not thread safe when used with shared
+ *       LDAP connection.
+ *     - Added configuration option for defining LDAP attribute of user object,
+ *       which controls remote access.
+ * 16 Feb 2001, Hannu Laurila <hannu.laurila@japo.fi>
+ *     - LDAP<->RADIUS attribute mappings are now read from a file
+ *     - Support for generic RADIUS check and reply attribute.
+ * Jun 2001, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Fix: check and reply attributes from LDAP _replace_ existing ones
+ *     - Added "default_profile" directive, which points to radiusProfile
+ *       object, which contains default values for RADIUS users
+ *     - Added "profile_attribute" directive, which specifies user object
+ *       attribute pointing to radiusProfile object.
+ * Nov 2001, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Added support for adding the user password to the check. Based on
+ *       the password_header directive rlm_ldap will strip the
+ *       password header if needed. This will make support for CHAP much easier.
+ *     - Added module messages when we reject a user.
+ *     - Added ldap_groupcmp to allow searching for user group membership.
+ *     - Added ldap_xlat to allow ldap urls in xlat strings. Something like:
+ *       %{ldap:ldap:///dc=company,dc=com?cn?sub?uid=user}
+ * Nov 2001, Gordon Tetlow <gordont@gnf.org>
+ *     - Do an xlat on the access_group attribute.
+ * Dec 2001, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Added ldap caching for the default/regular profiles and group entries.
+ *     - Fixed a memory leak in ldap_xlat.
+ *     - Removed dict_attrbyname from ldap_pairget. They are not needed.
+ *     - Moved the radius_xlat's for filter and basedn in ldap_authenticate() to
+ *       the right place.
+ *     - Made the module thread safe. We create a connection pool and each thread
+ *       will call ldap_get_conn to lock one of the ldap connections and release with
+ *       a call to ldap_release_conn when it has finished.
+ *     - Request only the user attributes that interest us (radius attributes,regular
+ *       profile,user password and access attribute).
+ * Mar 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Fixed a bug where the ldap server will kill the idle connections from the ldap
+ *       connection pool. We now check if ldap_search returns LDAP_SERVER_DOWN and try to
+ *       reconnect if it does. Bug noted by Dan Perik <dan_perik-work@ntm.org.pg>
+ * May 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Instead of the Group attribute we now have the Ldap-Group attribute, to avoid
+ *       collisions with other modules
+ *     - If perform_search fails check the ld != NULL before using it. Based on a bug report
+ *       by John <jhogenmiller@pennswoods.net>
+ * Jun 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add the ability to do a paircmp on the check items. Add a compare_check_items boolean
+ *       configuration directive which defaults to no. If it is set then we will do a compare
+ *     - Add another configuration directive. access_attr_used_for_allow. If it is set to yes
+ *       then the access_attr will be used to allow user access. If it is set to no then it will
+ *       be used to deny user access.
+ *     - Remember to free inst->atts in ldap_detach()
+ *     - Add a forgotten ldap_free_urldesc in ldap_xlat()
+ *     - Add a variable locked in the LDAP_CONN structure. We use this to avoid deadlocks. The mutex
+ *       we are using is of type fast and can deadlock if the same thread tries to relock it. That
+ *       could happen in case of calls to xlat.
+ *     - When ldap_search returns NO_SUCH_OBJECT don't return fail but notfound
+ * Jul 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Fix the logic when we get an LDAP_SERVER_DOWN or we have conn->ld == NULL in perform_search
+ *     - Try to minimize the penalty of having the ldap server go down. The comments before
+ *       MAX_FAILED_CONNS_* definitions should explain things.
+ *     - Check for a number of error codes from ldap_search and log corresponding error messages
+ *       We should only reconnect when that can help things.
+ *     - In ldap_groupcmp instead of first searching for the group object and then checking user
+ *       group membership combine them in one ldap search operation. That should make group
+ *       membership checks a lot faster.
+ *     - Remember to do ldap_release_conn and ldap_msgfree when we do paircmp and the result is reject
+ * Aug 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add support for group membership attribute inside the user entry in ldap_groupcmp. The attribute
+ *       can either contain the name or the DN of the group. Added the groupmembership_attribute
+ *       configuration directive
+ *     - Move the ldap_{get,release}_conn in ldap_groupcmp so that we hold a connection for the minimum time.
+ *     - Now that ldap_groupcmp is complete we really don't need access_group. Removed it.
+ *     - Remember to free groupmembership_attribute in ldap_detach
+ *     - Don't delete existing generic attributes in ldap_pairget when adding new ones. Since generic attributes
+ *       have operators we don't need to try to be cleaver.
+ * Sep 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Fix a crash in ldap_pairget when the attribute value is larger than the buffer size
+ *       Bug report by Stefan Radovanovici <sra@rtsffm.com>
+ *     - If we add a check item then use the == operator. Based on an idea by Allister Maguire <amaguire@gnc.net.nz>
+ *     - Only add a failure message for bind as user failed in ldap_authenticate if the result of ldap_connect was
+ *       RLM_MODULE_REJECT
+ *     - Make tls_mode a configurable option. Patch from John <jhogenmiller@pennswoods.net>
+ *     - Allow multiple regular profiles for an entry
+ * Oct 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Disable cache after searching for the default profile
+ *     - Use the MAX_FAILED_CONNS_* in ldap_authenticate() when calling ldap_connect()
+ * Nov 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Set LDAP version to V3 before binding. Now freeradius should work with openldap21
+ * Dec 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Set default values for the server and basedn parameters
+ * Feb 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add support for ldap_initialize. That way we can specify the server as an ldap url.
+ *       Based on ideas from Derrik Pates <dpates@dsdk12.net>
+ * Mar 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add an ldap_escape_func. Escape the * character from the filter so that we can avoid
+ *       the trivial DoS of username=*
+ *     - Remove the caching code. It does not exist in openldap21.
+ *       Based on a report from Mike Denka <mdenk@whidbey.net>
+ * May 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Don't do a double free on the attribute maps. Bug noted by Derrik Pates <dpates@dsdk12.net>
+ *     - Apply a patch from Alexander M. Pravking <fduch@antar.bryansk.ru> to do an xlat on the
+ *       retrieved attributes.
+ * Aug 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - In case of a bad search filter, print out the corresponding filter
+ * Sep 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Compile even if we don't have pthread's
+ * Oct 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add a new configuration directive, base_filter which is used for base scope searches
+ *       (When searching for the default/regular profiles for example)
+ * Nov 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add a new configuration directive, do_xlat (default: yes). If set we use pairxlatmove
+ *       on the radius attributes, else we fall back to the plain old pairadd. That way people
+ *       can fall back on the 0.8.1 behaviour without making changes to their ldap database or
+ *       gain a little performance by not using pairxlatmove
+ * Dec 2003, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - Add a patch from Jon Miner <miner@doit.wisc.edu> to add the ability to configure
+ *       various LDAP TLS options
+ *     - Only call pairfree if we are using pairxlatmove not for pairadd
+ * Mar 2004, Kostas Kalevras <kkalev@noc.ntua.gr>
+ *     - If we are passed an empty password log a module failure message not an error message
+ * Apr 2004, Kostas Kalveras <kkalev@noc.ntua.gr>
+ *     - Add a patch from Tarun Bhushan <tarun.bhushan@macquarie.com> to add a tls_mode boolean
+ *       directive so that we can enable TLS connetions even if port is not set to 636
+ *     - Add an error message if ldap_initialize() is not available and we are passed a URL like
+ *       'server' directive.
+ *     - Add a per instance Ldap-Group attribute (of the form <instance>-Ldap-Group) and register
+ *       a corresponding ldap_groupcmp function
+ *     - Small change to ldap_get_conn to fix problems on some platforms
  */
+static const char rcsid[] = "$Id$";
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <sys/time.h>
+#include       <netinet/in.h>
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <netdb.h>
 #include       <pwd.h>
+#include       <time.h>
 #include       <ctype.h>
+#include       <string.h>
 
 #include       <lber.h>
 #include        <ldap.h>
 
+#include       <errno.h>
+#include       <unistd.h>
+#include       <pthread.h>
+
+#include        "libradius.h"
+#include       "radiusd.h"
+#include       "conffile.h"
+#include       "modules.h"
+#include       "rad_assert.h"
+
 #ifndef HAVE_PTHREAD_H
 /*
  *      This is a lot simpler than putting ifdef's around
@@ -41,8 +197,6 @@ RCSID("$Id$")
 #define pthread_mutex_unlock(a)
 #define pthread_mutex_init(a,b)
 #define pthread_mutex_destroy(a)
-#else
-#include       <pthread.h>
 #endif
 
 
@@ -92,21 +246,20 @@ int nmasldap_get_password(
 #endif
 
 #ifdef NOVELL
-
+                                                                                                                             
 #define REQUEST_ACCEPTED   0
 #define REQUEST_CHALLENGED 1
 #define REQUEST_REJECTED   2
 #define MAX_CHALLENGE_LEN  128
 
 int radLdapXtnNMASAuth( LDAP *, char *, char *, char *, char *, size_t *, char *, int * );
-
+                                                                                                                             
 #endif
 
 /* linked list of mappings between RADIUS attributes and LDAP attributes */
 struct TLDAP_RADIUS {
        char*                 attr;
        char*                 radius_attr;
-       LRAD_TOKEN            operator;
        struct TLDAP_RADIUS*  next;
 };
 typedef struct TLDAP_RADIUS TLDAP_RADIUS;
@@ -146,7 +299,6 @@ typedef struct {
        char           *access_attr;
        char           *passwd_hdr;
        char           *passwd_attr;
-       int             auto_header;
        char           *dictionary_mapping;
        char           *groupname_attr;
        char           *groupmemb_filt;
@@ -167,144 +319,54 @@ typedef struct {
        char            *tls_randfile;
        char            *tls_require_cert;
 #ifdef NOVELL
-       int              edir_account_policy_check;
+       int                     edir_account_policy_check;
 #endif
-       int              set_auth_type;
-}  ldap_instance;
+       int             set_auth_type;
+}               ldap_instance;
 
 /* The default setting for TLS Certificate Verification */
 #define TLS_DEFAULT_VERIFY "allow"
 
-static CONF_PARSER tls_config[] = {
-       {"start_tls", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,start_tls), NULL, "no"},
-       {"cacertfile", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_cacertfile), NULL, NULL},
-       {"cacertdir", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_cacertdir), NULL, NULL},
-       {"certfile", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_certfile), NULL, NULL},
-       {"keyfile", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_keyfile), NULL, NULL},
-       {"randfile", PW_TYPE_STRING_PTR, /* OK if it changes on HUP */
-        offsetof(ldap_instance,tls_randfile), NULL, NULL},
-       {"require_cert", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,tls_require_cert), NULL, TLS_DEFAULT_VERIFY},
-       { NULL, -1, 0, NULL, NULL }
-};
-
-static const CONF_PARSER module_config[] = {
-       {"server", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,server), NULL, "localhost"},
-       {"port", PW_TYPE_INTEGER,
-        offsetof(ldap_instance,port), NULL, "389"},
-       {"password", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,password), NULL, ""},
-       {"identity", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,login), NULL, ""},
-
-       /*
-        *      Timeouts & stuff.
-        */
+static CONF_PARSER module_config[] = {
+       {"server", PW_TYPE_STRING_PTR, offsetof(ldap_instance,server), NULL, "localhost"},
+       {"port", PW_TYPE_INTEGER, offsetof(ldap_instance,port), NULL, "389"},
        /* wait forever on network activity */
-       {"net_timeout", PW_TYPE_INTEGER,
-        offsetof(ldap_instance,net_timeout.tv_sec), NULL, "10"},
+       {"net_timeout", PW_TYPE_INTEGER, offsetof(ldap_instance,net_timeout.tv_sec), NULL, "10"},
        /* wait forever for search results */
-       {"timeout", PW_TYPE_INTEGER,
-        offsetof(ldap_instance,timeout.tv_sec), NULL, "20"},
+       {"timeout", PW_TYPE_INTEGER, offsetof(ldap_instance,timeout.tv_sec), NULL, "20"},
        /* allow server unlimited time for search (server-side limit) */
-       {"timelimit", PW_TYPE_INTEGER,
-        offsetof(ldap_instance,timelimit), NULL, "20"},
-
-       /*
-        *      TLS configuration  The first few are here for backwards
-        *      compatibility.  The last is the new subsection.
-        */
-       {"tls_mode", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,tls_mode), NULL, "no"},
-
-       {"start_tls", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,start_tls), NULL, "no"},
-       {"tls_cacertfile", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_cacertfile), NULL, NULL},
-       {"tls_cacertdir", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_cacertdir), NULL, NULL},
-       {"tls_certfile", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_certfile), NULL, NULL},
-       {"tls_keyfile", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,tls_keyfile), NULL, NULL},
-       {"tls_randfile", PW_TYPE_STRING_PTR, /* OK if it changes on HUP */
-        offsetof(ldap_instance,tls_randfile), NULL, NULL},
-       {"tls_require_cert", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,tls_require_cert), NULL, TLS_DEFAULT_VERIFY},
-       { "tls", PW_TYPE_SUBSECTION, 0, NULL, (const void *) tls_config },
-
-       /*
-        *      DN's and filters.
-        */
-       {"basedn", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,basedn), NULL, "o=notexist"},
-       {"filter", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,filter), NULL, "(uid=%u)"},
-       {"base_filter", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,base_filter), NULL, "(objectclass=radiusprofile)"},
-       {"default_profile", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,default_profile), NULL, NULL},
-       {"profile_attribute", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,profile_attr), NULL, NULL},
-
-       /*
-        *      Getting passwords from the database
-        */
-       {"password_header", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,passwd_hdr), NULL, NULL},
-       {"password_attribute", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,passwd_attr), NULL, NULL},
-       {"auto_header", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,auto_header), NULL, "no"},
-
-       /*
-        *      Access limitations
-        */
+       {"timelimit", PW_TYPE_INTEGER, offsetof(ldap_instance,timelimit), NULL, "20"},
+       {"identity", PW_TYPE_STRING_PTR, offsetof(ldap_instance,login), NULL, ""},
+       {"tls_mode", PW_TYPE_BOOLEAN, offsetof(ldap_instance,tls_mode), NULL, "no"},
+       {"start_tls", PW_TYPE_BOOLEAN, offsetof(ldap_instance,start_tls), NULL, "no"},
+       {"tls_cacertfile", PW_TYPE_STRING_PTR, offsetof(ldap_instance,tls_cacertfile), NULL, NULL},
+       {"tls_cacertdir", PW_TYPE_STRING_PTR, offsetof(ldap_instance,tls_cacertdir), NULL, NULL},
+       {"tls_certfile", PW_TYPE_STRING_PTR, offsetof(ldap_instance,tls_certfile), NULL, NULL},
+       {"tls_keyfile", PW_TYPE_STRING_PTR, offsetof(ldap_instance,tls_keyfile), NULL, NULL},
+       {"tls_randfile", PW_TYPE_STRING_PTR, offsetof(ldap_instance,tls_randfile), NULL, NULL},
+       {"tls_require_cert", PW_TYPE_STRING_PTR, offsetof(ldap_instance,tls_require_cert), NULL, TLS_DEFAULT_VERIFY},
+       {"password", PW_TYPE_STRING_PTR, offsetof(ldap_instance,password), NULL, ""},
+       {"basedn", PW_TYPE_STRING_PTR, offsetof(ldap_instance,basedn), NULL, "o=notexist"},
+       {"filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance,filter), NULL, "(uid=%u)"},
+       {"base_filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance,base_filter), NULL, "(objectclass=radiusprofile)"},
+       {"default_profile", PW_TYPE_STRING_PTR, offsetof(ldap_instance,default_profile), NULL, NULL},
+       {"profile_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance,profile_attr), NULL, NULL},
+       {"password_header", PW_TYPE_STRING_PTR, offsetof(ldap_instance,passwd_hdr), NULL, NULL},
+       {"password_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance,passwd_attr), NULL, NULL},
        /* LDAP attribute name that controls remote access */
-       {"access_attr", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,access_attr), NULL, NULL},
-       {"access_attr_used_for_allow", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,default_allow), NULL, "yes"},
-
-       /*
-        *      Group checks.  These could probably be done
-        *      via dynamic xlat's.
-        */
-       {"groupname_attribute", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,groupname_attr), NULL, "cn"},
-       {"groupmembership_filter", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,groupmemb_filt), NULL, "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"},
-       {"groupmembership_attribute", PW_TYPE_STRING_PTR,
-        offsetof(ldap_instance,groupmemb_attr), NULL, NULL},
-
+       {"access_attr", PW_TYPE_STRING_PTR, offsetof(ldap_instance,access_attr), NULL, NULL},
        /* file with mapping between LDAP and RADIUS attributes */
-       {"dictionary_mapping", PW_TYPE_FILENAME,
-        offsetof(ldap_instance,dictionary_mapping), NULL, "${confdir}/ldap.attrmap"},
-
-       /*
-        *      Debugging flags to the server
-        */
-       {"ldap_debug", PW_TYPE_INTEGER,
-        offsetof(ldap_instance,ldap_debug), NULL, "0x0000"},
-       {"ldap_connections_number", PW_TYPE_INTEGER,
-        offsetof(ldap_instance,num_conns), NULL, "5"},
-       {"compare_check_items", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,do_comp), NULL, "no"},
-       {"do_xlat", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,do_xlat), NULL, "yes"},
-
+       {"groupname_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance,groupname_attr), NULL, "cn"},
+       {"groupmembership_filter", PW_TYPE_STRING_PTR, offsetof(ldap_instance,groupmemb_filt), NULL, "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"},
+       {"groupmembership_attribute", PW_TYPE_STRING_PTR, offsetof(ldap_instance,groupmemb_attr), NULL, NULL},
+       {"dictionary_mapping", PW_TYPE_STRING_PTR, offsetof(ldap_instance,dictionary_mapping), NULL, "${confdir}/ldap.attrmap"},
+       {"ldap_debug", PW_TYPE_INTEGER, offsetof(ldap_instance,ldap_debug), NULL, "0x0000"},
+       {"ldap_connections_number", PW_TYPE_INTEGER, offsetof(ldap_instance,num_conns), NULL, "5"},
+       {"compare_check_items", PW_TYPE_BOOLEAN, offsetof(ldap_instance,do_comp), NULL, "no"},
+       {"access_attr_used_for_allow", PW_TYPE_BOOLEAN, offsetof(ldap_instance,default_allow), NULL, "yes"},
+       {"do_xlat", PW_TYPE_BOOLEAN, offsetof(ldap_instance,do_xlat), NULL, "yes"},
 #ifdef NOVELL
-       /*
-        *      Novell magic.
-        */
-       {"edir_account_policy_check", PW_TYPE_BOOLEAN,
-        offsetof(ldap_instance,edir_account_policy_check), NULL, "yes"},
+       {"edir_account_policy_check", PW_TYPE_BOOLEAN, offsetof(ldap_instance,edir_account_policy_check), NULL, "yes"},
 #endif
 
        {"set_auth_type", PW_TYPE_BOOLEAN, offsetof(ldap_instance,set_auth_type), NULL, "yes"},
@@ -318,7 +380,7 @@ static const CONF_PARSER module_config[] = {
 #ifdef FIELDCPY
 static void     fieldcpy(char *, char **);
 #endif
-static VALUE_PAIR *ldap_pairget(LDAP *, LDAPMessage *, TLDAP_RADIUS *,VALUE_PAIR **,int);
+static VALUE_PAIR *ldap_pairget(LDAP *, LDAPMessage *, TLDAP_RADIUS *,VALUE_PAIR **,char);
 static int ldap_groupcmp(void *, REQUEST *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **);
 static int ldap_xlat(void *, REQUEST *, char *, char *, size_t, RADIUS_ESCAPE_STRING);
 static LDAP    *ldap_connect(void *instance, const char *, const char *, int, int *, char **);
@@ -331,13 +393,7 @@ static inline int ldap_get_conn(LDAP_CONN *conns,LDAP_CONN **ret,void *instance)
 
        for(i=0;i<inst->num_conns;i++){
                DEBUG("rlm_ldap: ldap_get_conn: Checking Id: %d",i);
-               if ((pthread_mutex_trylock(&conns[i].mutex) == 0)) {
-                       if (conns[i].locked == 1) {
-                               /* connection is already being used */
-                               pthread_mutex_unlock(&(conns[i].mutex));
-                               continue;
-                       }
-                       /* found an unused connection */
+               if (conns[i].locked == 0 && pthread_mutex_trylock(&(conns[i].mutex)) == 0){
                        *ret = &conns[i];
                        conns[i].locked = 1;
                        DEBUG("rlm_ldap: ldap_get_conn: Got Id: %d",i);
@@ -374,7 +430,8 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
        int att_map[3] = {0,0,0};
        TLDAP_RADIUS *pair;
        ATTR_FLAGS flags;
-       const char *xlat_name;
+       char *xlat_name;
+       DICT_VALUE *dv;
 
        inst = rad_malloc(sizeof *inst);
        if (!inst) {
@@ -389,7 +446,7 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
 
        if (inst->server == NULL) {
                radlog(L_ERR, "rlm_ldap: missing 'server' directive.");
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
        inst->is_url = 0;
@@ -399,7 +456,7 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
                inst->port = 0;
 #else
                radlog(L_ERR, "rlm_ldap: 'server' directive is in URL form but ldap_initialize() is not available.");
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
 #endif
        }
@@ -428,20 +485,19 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
                /*
                 * Allocate room for <instance>-Ldap-Group
                 */
-               group_name = rad_malloc((strlen(xlat_name) + 1 + 11) * sizeof(char));
+               group_name = malloc((strlen(xlat_name) + 1 + 11) * sizeof(char));
+               rad_assert(group_name != NULL);
                sprintf(group_name,"%s-Ldap-Group",xlat_name);
                DEBUG("rlm_ldap: Creating new attribute %s",group_name);
                dict_addattr(group_name, 0, PW_TYPE_STRING, -1, flags);
                dattr = dict_attrbyname(group_name);
                if (dattr == NULL){
                        radlog(L_ERR, "rlm_ldap: Failed to create attribute %s",group_name);
-                       free(group_name);
-                       free(inst);     /* FIXME: detach */
+                       free(inst);
                        return -1;
                }
                DEBUG("rlm_ldap: Registering ldap_groupcmp for %s",group_name);
                paircompare_register(dattr->attr, PW_USER_NAME, ldap_groupcmp, inst);
-               free(group_name);
        }
        else {
                xlat_name = cf_section_name1(conf);
@@ -456,52 +512,45 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
         *      This automagically catches the case where LDAP is listed
         *      in "authorize", but not "authenticate".
         */
-       if (inst->set_auth_type) {
-               DICT_VALUE *dv = dict_valbyname(PW_AUTH_TYPE, xlat_name);
-               if (!dv) {
+       dv = dict_valbyname(PW_AUTH_TYPE, xlat_name);
+       if (!dv) {
+               if (inst->set_auth_type) {
                        DEBUG2("rlm_ldap: Over-riding set_auth_type, as we're not listed in the \"authenticate\" section.");
-                       inst->set_auth_type = 0;
                }
-       } /* else no need to look up the value */
+         inst->set_auth_type = 0;
+       }
 
 #ifdef NOVELL
        /*
-        *      (LDAP_Instance, V1) attribute-value pair in the config
-        *      items list means that the 'authorize' method of the
-        *      instance 'V1' of the LDAP module has processed this
-        *      request.
+        * (LDAP_Instance, V1) attribute-value pair in the config items list means
+        * that the 'authorize' method of the instance 'V1' of the LDAP module has
+        * processed this request.
         */
        dict_addattr("LDAP-Instance", 0, PW_TYPE_STRING, -1, flags);
-
        /*
-        *      ('eDir-APC', '1') in config items list
-        *      Do not perform eDirectory account policy check (APC)
-        *
-        *      ('eDir-APC', '2') in config items list
-        *      Perform eDirectory APC
-        *
-        *      ('eDir-APC', '3') in config items list
-        *      eDirectory APC has been completed
+        * ('eDir-APC', '1') in config items list => Do not perform eDirectory account
+        *                                           policy check (APC)
+        * ('eDir-APC', '2') in config items list => Perform eDirectory APC
+        * ('eDir-APC', '3') in config items list => eDirectory APC has been completed
         */
        dict_addattr("eDir-APC", 0, PW_TYPE_STRING, -1, flags);
-       /*
-        *      eDir-Auth-Option allows for a different NMAS Authentication method to be used instead of password
-        */
-       dict_addattr("eDir-Auth-Option", 0, PW_TYPE_STRING, -1, flags);
+
+dict_addattr("eDir-Auth-Option", 0, PW_TYPE_STRING, -1, flags);
+
 #endif
 
        if (inst->num_conns <= 0){
                radlog(L_ERR, "rlm_ldap: Invalid ldap connections number passed.");
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
-       inst->conns = malloc(sizeof(*(inst->conns))*inst->num_conns);
+       inst->conns = (LDAP_CONN *)malloc(sizeof(LDAP_CONN)*inst->num_conns);
        if (inst->conns == NULL){
                radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
-       for(i = 0; i < inst->num_conns; i++){
+       for(;i<inst->num_conns;i++){
                inst->conns[i].bound = 0;
                inst->conns[i].locked = 0;
                inst->conns[i].failed_conns = 0;
@@ -511,16 +560,15 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
 
 #ifdef NOVELL
        /*
-        *      'inst->apc_conns' is a separate connection pool to be
-        *      used for performing eDirectory account policy check in
-        *      the 'postauth' method. This avoids changing the
-        *      (RADIUS server) credentials associated with the
-        *      'inst->conns' connection pool.
+        * 'inst->apc_conns' is a separate connection pool to be used for performing
+        * eDirectory account policy check in the 'postauth' method. This avoids
+        * changing the (RADIUS server) credentials associated with the 'inst->conns'
+        * connection pool.
         */
-       inst->apc_conns = malloc(sizeof(*(inst->apc_conns))*inst->num_conns);
+       inst->apc_conns = (LDAP_CONN *)malloc(sizeof(LDAP_CONN)*inst->num_conns);
        if (inst->apc_conns == NULL){
                radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
        for(i = 0; i < inst->num_conns; i++){
@@ -535,14 +583,13 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
        if (read_mappings(inst) != 0) {
                radlog(L_ERR, "rlm_ldap: Reading dictionary mappings from file %s failed",
                       inst->dictionary_mapping);
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
-       if ((inst->check_item_map == NULL) &&
-           (inst->reply_item_map == NULL)) {
+       if (inst->check_item_map == NULL && inst->reply_item_map == NULL){
                radlog(L_ERR, "rlm_ldap: dictionary mappings file %s did not contain any mappings",
                        inst->dictionary_mapping);
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
 
@@ -565,12 +612,13 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
        if (inst->access_attr)
                atts_num++;
 #ifdef NOVELL
-               atts_num++;     /* eDirectory Authentication Option attribute */
+       atts_num++;     /* eDirectory Authentication Option attribute */
 #endif
+       
        inst->atts = (char **)malloc(sizeof(char *)*(atts_num + 1));
        if (inst->atts == NULL){
                radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");
-               free(inst);     /* FIXME: detach */
+               free(inst);
                return -1;
        }
        pair = inst->check_item_map;
@@ -579,7 +627,7 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
 #ifdef NOVELL
        for(i=0;i<atts_num - 1;i++){
 #else
-       for(i=0;i<atts_num;i++){
+       for(i=0;i<atts_num;i++){
 #endif
                if (i <= check_map_num ){
                        inst->atts[i] = pair->attr;
@@ -622,9 +670,9 @@ ldap_instantiate(CONF_SECTION * conf, void **instance)
 
 
 /*
- *     read_mappings(...) reads a ldap<->radius mappings file to
- *     inst->reply_item_map and inst->check_item_map
+ * read_mappings(...) reads a ldap<->radius mappings file to inst->reply_item_map and inst->check_item_map
  */
+
 #define MAX_LINE_LEN 160
 #define GENERIC_ATTRIBUTE_ID "$GENERIC$"
 
@@ -633,16 +681,9 @@ read_mappings(ldap_instance* inst)
 {
        FILE* mapfile;
        char *filename;
-
-       /*
-        *      All buffers are of MAX_LINE_LEN so we can use sscanf
-        *      without being afraid of buffer overflows
-        */
-       char buf[MAX_LINE_LEN], itemType[MAX_LINE_LEN];
-       char radiusAttribute[MAX_LINE_LEN], ldapAttribute[MAX_LINE_LEN];
+       /* all buffers are of MAX_LINE_LEN so we can use sscanf without being afraid of buffer overflows */
+       char buf[MAX_LINE_LEN], itemType[MAX_LINE_LEN], radiusAttribute[MAX_LINE_LEN], ldapAttribute[MAX_LINE_LEN];
        int linenumber;
-       LRAD_TOKEN operator;
-       char opstring[MAX_LINE_LEN];
 
        /* open the mappings file for reading */
 
@@ -651,14 +692,13 @@ read_mappings(ldap_instance* inst)
        mapfile = fopen(filename, "r");
 
        if (mapfile == NULL) {
-               radlog(L_ERR, "rlm_ldap: Opening file %s failed", filename);
+               radlog(L_ERR, "rlm_ldap: Opening file %s failed: %s",
+                      filename, strerror(errno));
                return -1; /* error */
        }
 
-       /*
-        *      read file line by line. Note that if line length
-        *      exceeds MAX_LINE_LEN, line numbers will be mixed up
-        */
+       /* read file line by line. Note that if line length exceed MAX_LINE_LEN, line numbers will be mixed up */
+
        linenumber = 0;
 
        while (fgets(buf, sizeof buf, mapfile)!=NULL) {
@@ -676,41 +716,23 @@ read_mappings(ldap_instance* inst)
                if (buf[0] == 0) continue;
 
                /* extract tokens from the string */
-               token_count = sscanf(buf, "%s %s %s %s",
-                                    itemType, radiusAttribute,
-                                    ldapAttribute, opstring);
+               token_count = sscanf(buf, "%s %s %s", itemType, radiusAttribute, ldapAttribute);
 
                if (token_count <= 0) /* no tokens */
                        continue;
 
-               if ((token_count < 3) || (token_count > 4)) {
-                       radlog(L_ERR, "rlm_ldap: Skipping %s line %i: %s",
-                              filename, linenumber, buf);
-                       radlog(L_ERR, "rlm_ldap: Expected 3 to 4 tokens "
+               if (token_count != 3) {
+                       radlog(L_ERR, "rlm_ldap: Skipping %s line %i: %s", filename, linenumber, buf);
+                       radlog(L_ERR, "rlm_ldap: Expected 3 tokens "
                               "(Item type, RADIUS Attribute and LDAP Attribute) but found only %i", token_count);
                        continue;
                }
 
-               if (token_count == 3) {
-                       operator = T_OP_INVALID; /* use defaults */
-               } else {
-                       char *ptr;
-
-                       ptr = opstring;
-                       operator = gettoken(&ptr, buf, sizeof(buf));
-                       if ((operator < T_OP_ADD) || (operator > T_OP_CMP_EQ)) {
-                               radlog(L_ERR, "rlm_ldap: file %s: skipping line %i: unknown or invalid operator %s",
-                                      filename, linenumber, opstring);
-                               continue;
-                       }
-               }
-
                /* create new TLDAP_RADIUS list node */
-               pair = rad_malloc(sizeof(*pair));
+               pair = rad_malloc(sizeof(TLDAP_RADIUS));
 
                pair->attr = strdup(ldapAttribute);
                pair->radius_attr = strdup(radiusAttribute);
-               pair->operator = operator;
 
                if ( (pair->attr == NULL) || (pair->radius_attr == NULL) ) {
                        radlog(L_ERR, "rlm_ldap: Out of memory");
@@ -746,9 +768,9 @@ read_mappings(ldap_instance* inst)
        return 0; /* success */
 }
 
-static int perform_search(void *instance, LDAP_CONN *conn,
-                         char *search_basedn, int scope, char *filter,
-                         char **attrs, LDAPMessage ** result)
+static int
+perform_search(void *instance, LDAP_CONN *conn, char *search_basedn, int scope, char *filter,
+               char **attrs, LDAPMessage ** result)
 {
        int             res = RLM_MODULE_OK;
        int             ldap_errno = 0;
@@ -785,10 +807,8 @@ retry:
                conn->bound = 1;
                conn->failed_conns = 0;
        }
-       DEBUG2("rlm_ldap: performing search in %s, with filter %s",
-              search_basedn ? search_basedn : "(null)" , filter);
-       switch (ldap_search_st(conn->ld, search_basedn, scope, filter,
-                              attrs, 0, &(inst->timeout), result)) {
+       DEBUG2("rlm_ldap: performing search in %s, with filter %s", search_basedn ? search_basedn : "(null)" , filter);
+       switch (ldap_search_st(conn->ld, search_basedn, scope, filter, attrs, 0, &(inst->timeout), result)) {
        case LDAP_SUCCESS:
        case LDAP_NO_SUCH_OBJECT:
                break;
@@ -823,14 +843,12 @@ retry:
        case LDAP_UNAVAILABLE:
                /* We don't need to reconnect in these cases so we don't set conn->bound */
                ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
-               radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s",
-                      ldap_err2string(ldap_errno));
+               radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s", ldap_err2string(ldap_errno));
                ldap_msgfree(*result);
                return (RLM_MODULE_FAIL);
        default:
                ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
-               radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s",
-                      ldap_err2string(ldap_errno));
+               radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s", ldap_err2string(ldap_errno));
                conn->bound = 0;
                ldap_msgfree(*result);
                return (RLM_MODULE_FAIL);
@@ -896,12 +914,11 @@ static int ldap_escape_func(char *out, int outlen, const char *in)
 }
 
 /*
- *     ldap_groupcmp(). Implement the Ldap-Group == "group" filter
+ * ldap_groupcmp(). Implement the Ldap-Group == "group" filter
  */
-static int ldap_groupcmp(void *instance, REQUEST *req,
-                        UNUSED VALUE_PAIR *request, VALUE_PAIR *check,
-                        UNUSED VALUE_PAIR *check_pairs,
-                        UNUSED VALUE_PAIR **reply_pairs)
+
+static int ldap_groupcmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
+                VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 {
         char            filter[MAX_FILTER_STR_LEN];
         char            gr_filter[MAX_FILTER_STR_LEN];
@@ -918,11 +935,11 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
        VALUE_PAIR      *vp_user_dn;
        VALUE_PAIR      **request_pairs;
 
-       request_pairs = &req->config_items;
+       request_pairs = &req->packet->vps;
 
        DEBUG("rlm_ldap: Entering ldap_groupcmp()");
 
-       if (check->vp_strvalue == NULL || check->length == 0){
+       if (check->strvalue == NULL || check->length == 0){
                 DEBUG("rlm_ldap::ldap_groupcmp: Illegal group name");
                 return 1;
         }
@@ -968,41 +985,36 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
                         return 1;
                 }
                ldap_release_conn(conn_id,inst->conns);
-
                 /*
-                *      Adding new attribute containing DN for LDAP
-                *      object associated with given username
-                */
-                pairadd(request_pairs, pairmake("Ldap-UserDn", user_dn,
-                                               T_OP_EQ));
+                * Adding new attribute containing DN for LDAP object associated with
+                * given username
+                */
+                pairadd(request_pairs, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
                 ldap_memfree(user_dn);
                 ldap_msgfree(result);
         }
 
-        if(!radius_xlat(gr_filter, sizeof(gr_filter),
-                       inst->groupmemb_filt, req, ldap_escape_func)) {
+        if(!radius_xlat(gr_filter, sizeof(gr_filter), inst->groupmemb_filt, req, ldap_escape_func)){
                 DEBUG("rlm_ldap::ldap_groupcmp: unable to create filter.");
                 return 1;
         }
 
-       if (strchr((char *)check->vp_strvalue,',') != NULL) {
+       if (strchr((char *)check->strvalue,',') != NULL) {
                /* This looks like a DN */
                snprintf(filter,sizeof(filter), "%s",gr_filter);
-               snprintf(basedn,sizeof(basedn), "%s",(char *)check->vp_strvalue);
+               snprintf(basedn,sizeof(basedn), "%s",(char *)check->strvalue);
        } else
-               snprintf(filter,sizeof(filter), "(&(%s=%s)%s)",
-                        inst->groupname_attr,
-                        (char *)check->vp_strvalue,gr_filter);
+               snprintf(filter,sizeof(filter), "(&(%s=%s)%s)",inst->groupname_attr,(char *)check->strvalue,gr_filter);
 
-       if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1) {
+       if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1){
                radlog(L_ERR, "rlm_ldap: All ldap connections are in use");
                return 1;
        }
 
        if ((res = perform_search(inst, conn, basedn, LDAP_SCOPE_SUBTREE,
-                               filter, attrs, &result)) == RLM_MODULE_OK) {
+                               filter, attrs, &result)) == RLM_MODULE_OK){
                DEBUG("rlm_ldap::ldap_groupcmp: User found in group %s",
-                               (char *)check->vp_strvalue);
+                               (char *)check->strvalue);
                ldap_msgfree(result);
                ldap_release_conn(conn_id,inst->conns);
                return 0;
@@ -1016,12 +1028,11 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
        }
 
        if (inst->groupmemb_attr == NULL){
-               /*
-                *      Search returned NOTFOUND and searching for
-                *      membership using user object attributes is not
-                *      specified in config file
+               /* search returned NOTFOUND and searching for membership
+                * using user object attributes is not specified in config
+                * file
                 */
-               DEBUG("rlm_ldap::ldap_groupcmp: Group %s not found or user is not a member.",(char *)check->vp_strvalue);
+               DEBUG("rlm_ldap::ldap_groupcmp: Group %s not found or user is not a member.",(char *)check->strvalue);
                return 1;
        }
 
@@ -1030,9 +1041,8 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
                radlog(L_ERR, "rlm_ldap: Add ldap connections are in use");
                return 1;
        }
-       if ((res = perform_search(inst, conn, vp_user_dn->vp_strvalue,
-                                 LDAP_SCOPE_BASE, filter, group_attrs,
-                                 &result)) != RLM_MODULE_OK) {
+       if ((res = perform_search(inst, conn, vp_user_dn->strvalue, LDAP_SCOPE_BASE,
+                                       filter, group_attrs,&result)) != RLM_MODULE_OK){
                DEBUG("rlm_ldap::ldap_groupcmp: Search returned error");
                ldap_release_conn(conn_id, inst->conns);
                return 1;
@@ -1044,23 +1054,22 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
                ldap_msgfree(result);
                return 1;
        }
-       if ((vals = ldap_get_values(conn->ld, msg,
-                                   inst->groupmemb_attr)) != NULL) {
+       if ((vals = ldap_get_values(conn->ld, msg, inst->groupmemb_attr)) != NULL) {
                unsigned int i = 0;
                char found = 0;
-
                for (;i < ldap_count_values(vals);i++){
                        if (strchr(vals[i],',') != NULL){
                                /* This looks like a DN */
                                LDAPMessage *gr_result = NULL;
                                snprintf(filter,sizeof(filter), "(%s=%s)",
                                        inst->groupname_attr,
-                                       (char *)check->vp_strvalue);
+                                       (char *)check->strvalue);
                                if ((res = perform_search(inst, conn, vals[i],
                                                LDAP_SCOPE_BASE, filter,
                                                attrs, &gr_result)) != RLM_MODULE_OK){
-                                       if (res != RLM_MODULE_NOTFOUND) {
-                                               DEBUG("rlm_ldap::ldap_groupcmp: Search returned error");
+                                       if (res != RLM_MODULE_NOTFOUND){
+                                               DEBUG("rlm_ldap::ldap_groupcmp: \
+                                                       Search returned error");
                                                ldap_value_free(vals);
                                                ldap_msgfree(result);
                                                ldap_release_conn(conn_id,inst->conns);
@@ -1072,7 +1081,7 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
                                        break;
                                }
                        } else {
-                               if (strcmp(vals[i],(char *)check->vp_strvalue) == 0){
+                               if (strcmp(vals[i],(char *)check->strvalue) == 0){
                                        found = 1;
                                        break;
                                }
@@ -1081,8 +1090,9 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
                ldap_value_free(vals);
                ldap_msgfree(result);
                if (found == 0){
-                       DEBUG("rlm_ldap::groupcmp: Group %s not found or user not a member",
-                               (char *)check->vp_strvalue);
+                       DEBUG("rlm_ldap::groupcmp: Group %s not found \
+                               or user not a member",
+                               (char *)check->strvalue);
                        ldap_release_conn(conn_id,inst->conns);
                        return 1;
                }
@@ -1093,7 +1103,7 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
                        return 1;
        }
 
-       DEBUG("rlm_ldap::ldap_groupcmp: User found in group %s",(char *)check->vp_strvalue);
+       DEBUG("rlm_ldap::ldap_groupcmp: User found in group %s",(char *)check->strvalue);
        ldap_release_conn(conn_id,inst->conns);
 
         return 0;
@@ -1103,8 +1113,9 @@ static int ldap_groupcmp(void *instance, REQUEST *req,
  * ldap_xlat()
  * Do an xlat on an LDAP URL
  */
-static int ldap_xlat(void *instance, REQUEST *request, char *fmt,
-                    char *out, size_t freespace, RADIUS_ESCAPE_STRING func)
+
+static int ldap_xlat(void *instance, REQUEST *request, char *fmt, char *out,
+                    size_t freespace, RADIUS_ESCAPE_STRING func)
 {
        char url[MAX_FILTER_STR_LEN];
        int res;
@@ -1130,18 +1141,16 @@ static int ldap_xlat(void *instance, REQUEST *request, char *fmt,
                radlog (L_ERR, "rlm_ldap: LDAP URL parse failed.\n");
                return 0;
        }
-       if (ldap_url->lud_attrs == NULL || ldap_url->lud_attrs[0] == NULL ||
-           ( ldap_url->lud_attrs[1] != NULL ||
-             ( ! strlen(ldap_url->lud_attrs[0]) ||
+       if (ldap_url->lud_attrs == NULL || ldap_url->lud_attrs[0] == NULL || \
+               ( ldap_url->lud_attrs[1] != NULL || ( ! strlen(ldap_url->lud_attrs[0]) || \
                ! strcmp(ldap_url->lud_attrs[0],"*") ) ) ){
                radlog (L_ERR, "rlm_ldap: Invalid Attribute(s) request.\n");
                ldap_free_urldesc(ldap_url);
                return 0;
        }
        if (ldap_url->lud_host){
-               if (strncmp(inst->server,ldap_url->lud_host,
-                           strlen(inst->server)) != 0 ||
-                   ldap_url->lud_port != inst->port) {
+               if (strncmp(inst->server,ldap_url->lud_host,strlen(inst->server)) != 0 || \
+                               ldap_url->lud_port != inst->port){
                        DEBUG("rlm_ldap: Requested server/port is not known to this module instance.");
                        ldap_free_urldesc(ldap_url);
                        return 0;
@@ -1182,7 +1191,7 @@ static int ldap_xlat(void *instance, REQUEST *request, char *fmt,
                        return 0;
                }
                DEBUG("rlm_ldap: Adding attribute %s, value: %s",ldap_url->lud_attrs[0],vals[0]);
-               strlcpy(out,vals[0],ret);
+               strncpy(out,vals[0],ret);
                ldap_value_free(vals);
        }
        else
@@ -1198,23 +1207,6 @@ static int ldap_xlat(void *instance, REQUEST *request, char *fmt,
 }
 
 
-/*
- *     For auto-header discovery.
- */
-static const LRAD_NAME_NUMBER header_names[] = {
-       { "{clear}",    PW_CLEARTEXT_PASSWORD },
-       { "{cleartext}", PW_CLEARTEXT_PASSWORD },
-       { "{md5}",      PW_MD5_PASSWORD },
-       { "{smd5}",     PW_SMD5_PASSWORD },
-       { "{crypt}",    PW_CRYPT_PASSWORD },
-       { "{sha}",      PW_SHA_PASSWORD },
-       { "{ssha}",     PW_SSHA_PASSWORD },
-       { "{nt}",       PW_NT_PASSWORD },
-       { "{ns-mta-md5}", PW_NS_MTA_MD5_PASSWORD },
-       { NULL, 0 }
-};
-
-
 /******************************************************************************
  *
  *      Function: rlm_ldap_authorize
@@ -1222,7 +1214,8 @@ static const LRAD_NAME_NUMBER header_names[] = {
  *      Purpose: Check if user is authorized for remote access
  *
  ******************************************************************************/
-static int ldap_authorize(void *instance, REQUEST * request)
+static int
+ldap_authorize(void *instance, REQUEST * request)
 {
        LDAPMessage     *result = NULL;
        LDAPMessage     *msg = NULL;
@@ -1259,12 +1252,12 @@ static int ldap_authorize(void *instance, REQUEST * request)
        /*
         * Check for valid input, zero length names not permitted
         */
-       if (request->username->vp_strvalue == 0) {
+       if (request->username->strvalue == 0) {
                radlog(L_ERR, "rlm_ldap: zero length username not permitted\n");
                return RLM_MODULE_INVALID;
        }
        DEBUG("rlm_ldap: performing user authorization for %s",
-              request->username->vp_strvalue);
+              request->username->strvalue);
 
        if (!radius_xlat(filter, sizeof(filter), inst->filter,
                         request, ldap_escape_func)) {
@@ -1308,7 +1301,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
         * Adding new attribute containing DN for LDAP object associated with
         * given username
         */
-       pairadd(check_pairs, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
+       pairadd(&request->packet->vps, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
        ldap_memfree(user_dn);
 
 
@@ -1316,7 +1309,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
        if (inst->access_attr) {
                if ((vals = ldap_get_values(conn->ld, msg, inst->access_attr)) != NULL) {
                        if (inst->default_allow){
-                               DEBUG("rlm_ldap: checking if remote access for %s is allowed by %s", request->username->vp_strvalue, inst->access_attr);
+                               DEBUG("rlm_ldap: checking if remote access for %s is allowed by %s", request->username->strvalue, inst->access_attr);
                                if (!strncmp(vals[0], "FALSE", 5)) {
                                        DEBUG("rlm_ldap: dialup access disabled");
                                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: Access Attribute denies access");
@@ -1361,9 +1354,9 @@ static int ldap_authorize(void *instance, REQUEST * request)
        if (inst->default_profile || user_profile){
                char *profile = inst->default_profile;
 
-               strlcpy(filter,inst->base_filter,sizeof(filter));
+               strNcpy(filter,inst->base_filter,sizeof(filter));
                if (user_profile)
-                       profile = user_profile->vp_strvalue;
+                       profile = user_profile->strvalue;
                if (profile && strlen(profile)){
                        if ((res = perform_search(instance, conn,
                                profile, LDAP_SCOPE_BASE,
@@ -1402,7 +1395,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
        if (inst->profile_attr){
                if ((vals = ldap_get_values(conn->ld, msg, inst->profile_attr)) != NULL) {
                        unsigned int i=0;
-                       strlcpy(filter,inst->base_filter,sizeof(filter));
+                       strNcpy(filter,inst->base_filter,sizeof(filter));
                        while(vals[i] != NULL && strlen(vals[i])){
                                if ((res = perform_search(instance, conn,
                                        vals[i], LDAP_SCOPE_BASE,
@@ -1433,78 +1426,51 @@ static int ldap_authorize(void *instance, REQUEST * request)
                        ldap_value_free(vals);
                }
        }
-       if (inst->passwd_attr && strlen(inst->passwd_attr)) {
+       if (inst->passwd_attr && strlen(inst->passwd_attr)){
 #ifdef NOVELL_UNIVERSAL_PASSWORD
-               if (strcasecmp(inst->passwd_attr,"nspmPassword") != 0) {
+               if(strcasecmp(inst->passwd_attr,"nspmPassword")!= 0){
 #endif
-                       VALUE_PAIR *passwd_item;
-                       char **passwd_vals;
-                       char *value = NULL;
-                       int i;
-
-                       /*
-                        *      Read the password from the DB, and
-                        *      add it to the request.
-                        */
-                       passwd_vals = ldap_get_values(conn->ld,msg,
-                                                     inst->passwd_attr);
+               VALUE_PAIR *passwd_item;
 
-                       /*
-                        *      Loop over what we received, and parse it.
-                        */
-                       if (passwd_vals) for (i = 0;
-                                             passwd_vals[i] != NULL;
-                                             i++) {
-                               int attr = PW_USER_PASSWORD;
-
-                               if (strlen(passwd_vals[i]) == 0)
-                                       continue;
-
-                               value = passwd_vals[i];
-
-                               if (inst->auto_header) {
-                                       char *p;
-                                       char autobuf[16];
-
-                                       p = strchr(value, '}');
-                                       if (!p) continue;
-                                       if ((p - value + 1) >= sizeof(autobuf))
-                                               continue; /* paranoia */
-                                       memcpy(autobuf, value, p - value + 1);
-                                       autobuf[p - value + 1] = '\0';
-
-                                       attr = lrad_str2int(header_names,
-                                                           autobuf, 0);
-                                       if (!attr) continue;
-                                       value = p + 1;
-                                       goto create_attr;
-
-                               } else if (inst->passwd_hdr &&
-                                          strlen(inst->passwd_hdr)) {
-                                       if (strncasecmp(value,
-                                                       inst->passwd_hdr,
-                                                       strlen(inst->passwd_hdr)) == 0) {
-                                               value += strlen(inst->passwd_hdr);
-                                       } else {
-                                               DEBUG("rlm_ldap: Password header not found in password %s for user %s", passwd_vals[0], request->username->vp_strvalue);
+               if ((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL){
+                       char **passwd_vals;
+                       char *passwd_val = NULL;
+                       int passwd_len;
+
+                       if ((passwd_vals = ldap_get_values(conn->ld,msg,inst->passwd_attr)) != NULL){
+                               unsigned int i=0;
+                               while(passwd_vals[i] != NULL){
+                                       if (strlen(passwd_vals[i])){
+                                               passwd_val = passwd_vals[i];
+
+                                               if (inst->passwd_hdr && strlen(inst->passwd_hdr)){
+                                                       passwd_val = strstr(passwd_val,inst->passwd_hdr);
+                                                       if (passwd_val != NULL)
+                                                               passwd_val += strlen(inst->passwd_hdr);
+                                                       else
+                                                               DEBUG("rlm_ldap: Password header not found in password %s for user %s", passwd_vals[0],request->username->strvalue);
+                                               }
+                                               if (passwd_val){
+                                                       if ((passwd_item = paircreate(PW_PASSWORD,PW_TYPE_STRING)) == NULL){
+                                                               radlog(L_ERR|L_CONS, "no memory");
+                                                               ldap_value_free(passwd_vals);
+                                                               ldap_msgfree(result);
+                                                               ldap_release_conn(conn_id,inst->conns);
+                                                               return RLM_MODULE_FAIL;
+                                                       }
+                                                       added_known_password = 1;
+                                                       passwd_len = strlen(passwd_val);
+                                                       strncpy(passwd_item->strvalue,passwd_val,MAX_STRING_LEN - 1);
+                                                       passwd_item->length = (passwd_len > (MAX_STRING_LEN - 1)) ? (MAX_STRING_LEN - 1) : passwd_len;
+                                                       pairadd(&request->config_items,passwd_item);
+                                                       DEBUG("rlm_ldap: Added password %s in check items",passwd_item->strvalue);
+                                               }
                                        }
+                                       i++;
                                }
-                               if (!value) continue;
-
-                       create_attr:
-                               passwd_item = radius_paircreate(request,
-                                                               &request->config_items,
-                                                               attr,
-                                                               PW_TYPE_STRING);
-                               strlcpy(passwd_item->vp_strvalue, value,
-                                       sizeof(passwd_item->vp_strvalue));
-                               passwd_item->length = strlen(passwd_item->vp_strvalue);
-                               DEBUG("rlm_ldap: Added %s = %s in check items",
-                                     passwd_item->name,
-                                     passwd_item->vp_strvalue);
-                               added_known_password = 1;
+                               ldap_value_free(passwd_vals);
                        }
-                       ldap_value_free(passwd_vals);
+               }
 #ifdef NOVELL_UNIVERSAL_PASSWORD
                }
                else{
@@ -1520,13 +1486,13 @@ static int ldap_authorize(void *instance, REQUEST * request)
 
                        res = 0;
 
-                       if ((passwd_item = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD)) == NULL){
-
+                       if ((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL){
+                       
                                universal_password = rad_malloc(universal_password_len);
                                memset(universal_password, 0, universal_password_len);
 
-                               vp_user_dn = pairfind(request->config_items,PW_LDAP_USERDN);
-                               res = nmasldap_get_password(conn->ld,vp_user_dn->vp_strvalue,&universal_password_len,universal_password);
+                               vp_user_dn = pairfind(request->packet->vps,PW_LDAP_USERDN);
+                               res = nmasldap_get_password(conn->ld,vp_user_dn->strvalue,&universal_password_len,universal_password);
 
                                if (res == 0){
                                        passwd_val = universal_password;
@@ -1537,14 +1503,24 @@ static int ldap_authorize(void *instance, REQUEST * request)
                                                if (passwd_val != NULL)
                                                        passwd_val += strlen((char*)inst->passwd_hdr);
                                                else
-                                                       DEBUG("rlm_ldap: Password header not found in password %s for user %s ",passwd_val,request->username->vp_strvalue);
+                                                       DEBUG("rlm_ldap: Password header not found in password %s for user %s ",passwd_val,request->username->strvalue);
                                        }
 
                                        if (passwd_val){
-                                               passwd_item = radius_paircreate(request, &request->config_items, PW_CLEARTEXT_PASSWORD, PW_TYPE_STRING);
-                                               strlcpy(passwd_item->vp_strvalue,passwd_val,sizeof(passwd_item->vp_strvalue));
-                                               passwd_item->length = strlen(passwd_item->vp_strvalue);
+                                               if ((passwd_item = paircreate(PW_PASSWORD,PW_TYPE_STRING)) == NULL){
+                                                       radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");
+                                                       ldap_msgfree(result);
+                                                       ldap_release_conn(conn_id,inst->conns);
+                                                       memset(universal_password, 0, universal_password_len);
+                                                       free(universal_password);
+                                                       return RLM_MODULE_FAIL;
+                                               }
+
                                                added_known_password = 1;
+                                               passwd_len = strlen(passwd_val);
+                                               strncpy(passwd_item->strvalue,passwd_val,MAX_STRING_LEN - 1);
+                                               passwd_item->length = (passwd_len > (MAX_STRING_LEN - 1)) ? (MAX_STRING_LEN - 1) : passwd_len;
+                                               pairadd(&request->config_items,passwd_item);
 
 #ifdef NOVELL
                                                {
@@ -1563,29 +1539,46 @@ static int ldap_authorize(void *instance, REQUEST * request)
                                                                 * The authorize method of no other LDAP module instance has
                                                                 * processed this request.
                                                                 */
-                                                               vp_inset = radius_paircreate(request, &request->config_items, inst_attr, PW_TYPE_STRING);
-                                                               strlcpy(vp_inst->vp_strvalue, inst->xlat_name, sizeof(vp_inst->vp_strvalue));
-                                                               vp_inst->length = strlen(vp_inst->vp_strvalue);
+                                                               if ((vp_inst = paircreate(inst_attr, PW_TYPE_STRING)) == NULL){
+                                                                       radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");
+                                                                       ldap_msgfree(result);
+                                                                       ldap_release_conn(conn_id, inst->conns);
+                                                                       memset(universal_password, 0, universal_password_len);
+                                                                       free(universal_password);
+                                                                       return RLM_MODULE_FAIL;
+                                                               }
+                                                               strcpy(vp_inst->strvalue, inst->xlat_name);
+                                                               vp_inst->length = strlen(vp_inst->strvalue);
+                                                               pairadd(&request->config_items, vp_inst);
 
                                                                /*
                                                                 * Inform the authenticate / post-auth method about the presence
                                                                 * of UP in the config items list and whether eDirectory account
                                                                 * policy check is to be performed or not.
                                                                 */
-                                                               vp_apc = radius_paircreate(request, &request->config_items, apc_attr, PW_TYPE_STRING);
+                                                               if ((vp_apc = paircreate(apc_attr, PW_TYPE_STRING)) == NULL){
+                                                                       radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");
+                                                                       ldap_msgfree(result);
+                                                                       ldap_release_conn(conn_id, inst->conns);
+                                                                       memset(universal_password, 0, universal_password_len);
+                                                                       free(universal_password);
+                                                                       return RLM_MODULE_FAIL;
+                                                               }
+
                                                                if(!inst->edir_account_policy_check){
                                                                        /* Do nothing */
-                                                                       strcpy(vp_apc->vp_strvalue, "1");
+                                                                       strcpy(vp_apc->strvalue, "1");
                                                                }else{
                                                                        /* Perform eDirectory account-policy check */
-                                                                       strcpy(vp_apc->vp_strvalue, "2");
+                                                                       strcpy(vp_apc->strvalue, "2");
                                                                }
                                                                vp_apc->length = 1;
+                                                               pairadd(&request->config_items, vp_apc);
                                                        }
                                                }
 #endif
 
-                                               DEBUG("rlm_ldap: Added the eDirectory password %s in check items as %s",passwd_item->vp_strvalue,passwd_item->name);
+                                               DEBUG("rlm_ldap: Added the eDirectory password in check items");
                                        }
                                }
                                else {
@@ -1595,7 +1588,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
                                memset(universal_password, 0, universal_password_len);
                                free(universal_password);
                        }
-               }
+               }                       
 #endif
        }
 
@@ -1625,6 +1618,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
        }
 #endif
 
+
        DEBUG("rlm_ldap: looking for check items in directory...");
 
        if ((check_tmp = ldap_pairget(conn->ld, msg, inst->check_item_map,check_pairs,1)) != NULL) {
@@ -1649,7 +1643,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
                        pairadd(reply_pairs,reply_tmp);
        }
 
-       if (inst->do_comp && paircompare(request,request->packet->vps,*check_pairs,reply_pairs) != 0){
+       if (inst->do_comp && paircmp(request,request->packet->vps,*check_pairs,reply_pairs) != 0){
 #ifdef NOVELL
                /* Don't perform eDirectory APC if RADIUS authorize fails */
                int apc_attr;
@@ -1661,7 +1655,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
 
                vp_apc = pairfind(request->config_items, apc_attr);
                if(vp_apc)
-                       vp_apc->vp_strvalue[0] = '1';
+                       vp_apc->strvalue[0] = '1';
 #endif
 
                DEBUG("rlm_ldap: Pairs do not match. Rejecting user.");
@@ -1690,7 +1684,7 @@ static int ldap_authorize(void *instance, REQUEST * request)
        }
 
        DEBUG("rlm_ldap: user %s authorized to use remote access",
-             request->username->vp_strvalue);
+             request->username->strvalue);
        ldap_msgfree(result);
        ldap_release_conn(conn_id,inst->conns);
 
@@ -1704,7 +1698,8 @@ static int ldap_authorize(void *instance, REQUEST * request)
  *     Purpose: Check the user's password against ldap database
  *
  *****************************************************************************/
-static int ldap_authenticate(void *instance, REQUEST * request)
+static int
+ldap_authenticate(void *instance, REQUEST * request)
 {
        LDAP           *ld_user;
        LDAPMessage    *result, *msg;
@@ -1712,7 +1707,7 @@ static int ldap_authenticate(void *instance, REQUEST * request)
        char           *user_dn, *attrs[] = {"uid", NULL};
        char            filter[MAX_FILTER_STR_LEN];
        char            basedn[MAX_FILTER_STR_LEN];
-       int             res;
+       int             res;
        VALUE_PAIR     *vp_user_dn;
        VALUE_PAIR      *module_fmsg_vp;
        char            module_fmsg[MAX_STRING_LEN];
@@ -1736,13 +1731,10 @@ static int ldap_authenticate(void *instance, REQUEST * request)
 
        if (!request->password){
                radlog(L_AUTH, "rlm_ldap: Attribute \"User-Password\" is required for authentication.");
-               DEBUG2("  You seem to have set \"Auth-Type := LDAP\" somewhere.");
-               DEBUG2("  THAT CONFIGURATION IS WRONG.  DELETE IT.");
-               DEBUG2("  YOU ARE PREVENTING THE SERVER FROM WORKING PROPERLY.");
                return RLM_MODULE_INVALID;
        }
 
-       if(request->password->attribute != PW_USER_PASSWORD) {
+       if(request->password->attribute != PW_PASSWORD) {
                radlog(L_AUTH, "rlm_ldap: Attribute \"User-Password\" is required for authentication. Cannot use \"%s\".", request->password->name);
                return RLM_MODULE_INVALID;
        }
@@ -1767,10 +1759,9 @@ static int ldap_authenticate(void *instance, REQUEST * request)
 
 
        DEBUG("rlm_ldap: login attempt by \"%s\" with password \"%s\"",
-              request->username->vp_strvalue, request->password->vp_strvalue);
+              request->username->strvalue, request->password->strvalue);
 
-       while ((vp_user_dn = pairfind(request->config_items,
-                                     PW_LDAP_USERDN)) == NULL) {
+       while((vp_user_dn = pairfind(request->packet->vps, PW_LDAP_USERDN)) == NULL) {
                if (!radius_xlat(filter, sizeof(filter), inst->filter,
                                request, ldap_escape_func)) {
                        radlog (L_ERR, "rlm_ldap: unable to create filter.\n");
@@ -1808,19 +1799,20 @@ static int ldap_authenticate(void *instance, REQUEST * request)
                        return RLM_MODULE_FAIL;
                }
                ldap_release_conn(conn_id,inst->conns);
-               pairadd(&request->config_items, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
+               pairadd(&request->packet->vps, pairmake("Ldap-UserDn", user_dn, T_OP_EQ));
                ldap_memfree(user_dn);
                ldap_msgfree(result);
        }
 
-       user_dn = vp_user_dn->vp_strvalue;
+       user_dn = vp_user_dn->strvalue;
 
        DEBUG("rlm_ldap: user DN: %s", user_dn);
 
 #ifndef NOVELL
-       ld_user = ldap_connect(instance, user_dn, request->password->vp_strvalue,
+       ld_user = ldap_connect(instance, user_dn, request->password->strvalue,
                               1, &res, NULL);
 #else
+
        /* Don't perform eDirectory APC again after attempting to bind here. */
        {
                int apc_attr;
@@ -1839,8 +1831,8 @@ static int ldap_authenticate(void *instance, REQUEST * request)
                dattr = dict_attrbyname("eDir-APC");
                apc_attr = dattr->attr;
                vp_apc = pairfind(request->config_items, apc_attr);
-               if(vp_apc && vp_apc->vp_strvalue[0] == '2')
-                       vp_apc->vp_strvalue[0] = '3';
+               if(vp_apc && vp_apc->strvalue[0] == '2')
+                       vp_apc->strvalue[0] = '3';
 
                res = 0;
 
@@ -1960,7 +1952,7 @@ retry:
                                }
                        }
                }
-       }
+       }
 
        ld_user = ldap_connect(instance, user_dn, request->password->strvalue,
                        1, &res, &err);
@@ -1971,6 +1963,7 @@ retry:
                pairadd(&request->reply->vps, pairmake("Reply-Message", err, T_OP_EQ));
                ldap_memfree((void *)err);
        }
+
 #endif
 
        if (ld_user == NULL){
@@ -1988,7 +1981,7 @@ retry:
        }
 
        DEBUG("rlm_ldap: user %s authenticated succesfully",
-             request->username->vp_strvalue);
+             request->username->strvalue);
        ldap_unbind_s(ld_user);
        inst->failed_conns = 0;
 
@@ -2004,7 +1997,8 @@ retry:
  *     to eDirectory.
  *
  *****************************************************************************/
-static int ldap_postauth(void *instance, REQUEST * request)
+static int
+ldap_postauth(void *instance, REQUEST * request)
 {
        int res = RLM_MODULE_FAIL;
        int inst_attr, apc_attr;
@@ -2025,12 +2019,12 @@ static int ldap_postauth(void *instance, REQUEST * request)
         * Check if the password in the config items list is the user's UP which has
         * been read in the authorize method of this instance of the LDAP module.
         */
-       if((vp_inst == NULL) || strcmp(vp_inst->vp_strvalue, inst->xlat_name))
+       if((vp_inst == NULL) || strcmp(vp_inst->strvalue, inst->xlat_name))
                return RLM_MODULE_NOOP;
 
        vp_apc = pairfind(request->config_items, apc_attr);
 
-       switch(vp_apc->vp_strvalue[0]){
+       switch(vp_apc->strvalue[0]){
                case '1':
                        /* Account policy check not enabled */
                case '3':
@@ -2044,28 +2038,28 @@ static int ldap_postauth(void *instance, REQUEST * request)
                                VALUE_PAIR *vp_fdn, *vp_pwd;
                                DICT_ATTR *da;
 
-                               if (request->reply->code == PW_AUTHENTICATION_REJECT) {
-                                 /* Bind to eDirectory as the RADIUS user with a wrong password. */
-                                 vp_pwd = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
-                                 strcpy(password, vp_pwd->vp_strvalue);
-                                 if (strlen(password) > 0) {
-                                         if (password[0] != 'a') {
-                                                 password[0] = 'a';
-                                         } else {
-                                                 password[0] = 'b';
-                                         }
-                                 } else {
-                                         strcpy(password, "dummy_password");
-                                 }
-                                 res = RLM_MODULE_REJECT;
-                               } else {
+                               if(request->reply->code == PW_AUTHENTICATION_REJECT){
+                                       /* Bind to eDirectory as the RADIUS user with a wrong password. */
+                                       vp_pwd = pairfind(request->config_items, PW_PASSWORD);
+                                       strcpy(password, vp_pwd->strvalue);
+                                       if(strlen(password) > 0){
+                                               if(password[0] != 'a'){
+                                                       password[0] = 'a';
+                                               }else{
+                                                       password[0] = 'b';
+                                               }
+                                       }else{
+                                               strcpy(password, "dummy_password");
+                                       }
+                                       res = RLM_MODULE_REJECT;
+                               }else{
                                        /* Bind to eDirectory as the RADIUS user using the user's UP */
-                                       vp_pwd = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
-                                       if (vp_pwd == NULL) {
+                                       vp_pwd = pairfind(request->config_items, PW_PASSWORD);
+                                       if(vp_pwd == NULL){
                                                DEBUG("rlm_ldap: User's Universal Password not in config items list.");
                                                return RLM_MODULE_FAIL;
                                        }
-                                       strcpy(password, vp_pwd->vp_strvalue);
+                                       strcpy(password, vp_pwd->strvalue);
                                }
 
                                if ((da = dict_attrbyname("Ldap-UserDn")) == NULL) {
@@ -2074,7 +2068,7 @@ static int ldap_postauth(void *instance, REQUEST * request)
                                }
 
                                vp_fdn = pairfind(request->packet->vps, da->attr);
-                               if (vp_fdn == NULL) {
+                               if(vp_fdn == NULL){
                                        DEBUG("rlm_ldap: User's FQDN not in config items list.");
                                        return RLM_MODULE_FAIL;
                                }
@@ -2085,49 +2079,47 @@ static int ldap_postauth(void *instance, REQUEST * request)
                                }
 
                                /*
-                                *      If there is an existing LDAP
-                                *      connection to the directory,
-                                *      bind over it. Otherwise,
-                                *      establish a new connection.
+                                * If there is an existing LDAP connection to the directory, bind over
+                                * it. Otherwise, establish a new connection.
                                 */
-                       postauth_reconnect:
+postauth_reconnect:
                                if (!conn->bound || conn->ld == NULL) {
                                        DEBUG2("rlm_ldap: attempting LDAP reconnection");
                                        if (conn->ld){
                                                DEBUG2("rlm_ldap: closing existing LDAP connection");
                                                ldap_unbind_s(conn->ld);
                                        }
-                                       if ((conn->ld = ldap_connect(instance, (char *)vp_fdn->vp_strvalue, password, 0, &res, &error_msg)) == NULL) {
+                                       if ((conn->ld = ldap_connect(instance, (char *)vp_fdn->strvalue, password, 0, &res, &error_msg)) == NULL) {
                                                radlog(L_ERR, "rlm_ldap: eDirectory account policy check failed.");
 
-                                               if (error_msg != NULL) {
+                                               if(error_msg != NULL){
                                                        DEBUG("rlm_ldap: %s", error_msg);
                                                        pairadd(&request->reply->vps, pairmake("Reply-Message", error_msg, T_OP_EQ));
                                                        ldap_memfree((void *)error_msg);
                                                }
 
-                                               vp_apc->vp_strvalue[0] = '3';
+                                               vp_apc->strvalue[0] = '3';
                                                ldap_release_conn(conn_id, inst->apc_conns);
                                                return RLM_MODULE_REJECT;
                                        }
                                        conn->bound = 1;
-                               } else if((err = ldap_simple_bind_s(conn->ld, (char *)vp_fdn->vp_strvalue, password)) != LDAP_SUCCESS) {
-                                       if (err == LDAP_SERVER_DOWN) {
+                               }else if((err = ldap_simple_bind_s(conn->ld, (char *)vp_fdn->strvalue, password)) != LDAP_SUCCESS){
+                                       if(err == LDAP_SERVER_DOWN){
                                                conn->bound = 0;
                                                goto postauth_reconnect;
                                        }
                                        DEBUG("rlm_ldap: eDirectory account policy check failed.");
                                        ldap_get_option(conn->ld, LDAP_OPT_ERROR_STRING, &error_msg);
-                                       if (error_msg != NULL) {
+                                       if(error_msg != NULL){
                                                DEBUG("rlm_ldap: %s", error_msg);
                                                pairadd(&request->reply->vps, pairmake("Reply-Message", error_msg, T_OP_EQ));
                                                ldap_memfree((void *)error_msg);
                                        }
-                                       vp_apc->vp_strvalue[0] = '3';
+                                       vp_apc->strvalue[0] = '3';
                                        ldap_release_conn(conn_id, inst->apc_conns);
                                        return RLM_MODULE_REJECT;
                                }
-                               vp_apc->vp_strvalue[0] = '3';
+                               vp_apc->strvalue[0] = '3';
                                ldap_release_conn(conn_id, inst->apc_conns);
                                return RLM_MODULE_OK;
                        }
@@ -2136,8 +2128,8 @@ static int ldap_postauth(void *instance, REQUEST * request)
 }
 #endif
 
-static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
-                         int auth, int *result, char **err)
+static LDAP    *
+ldap_connect(void *instance, const char *dn, const char *password, int auth, int *result, char **err)
 {
        ldap_instance  *inst = instance;
        LDAP           *ld = NULL;
@@ -2154,7 +2146,8 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
                        return (NULL);
                }
 #endif
-       } else {
+       }
+       else{
                DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth);
                if ((ld = ldap_init(inst->server, inst->port)) == NULL) {
                        radlog(L_ERR, "rlm_ldap: ldap_init() failed");
@@ -2162,120 +2155,111 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
                        return (NULL);
                }
        }
-       if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT,
-                           (void *) &(inst->net_timeout)) != LDAP_OPT_SUCCESS) {
+       if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, (void *) &(inst->net_timeout)) != LDAP_OPT_SUCCESS) {
                radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_NETWORK_TIMEOUT %ld.%ld", inst->net_timeout.tv_sec, inst->net_timeout.tv_usec);
        }
-
-       if (ldap_set_option(ld, LDAP_OPT_TIMELIMIT,
-                           (void *) &(inst->timelimit)) != LDAP_OPT_SUCCESS) {
+       if (ldap_set_option(ld, LDAP_OPT_TIMELIMIT, (void *) &(inst->timelimit)) != LDAP_OPT_SUCCESS) {
                radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_TIMELIMIT %d", inst->timelimit);
        }
-
        if (inst->ldap_debug && ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &(inst->ldap_debug)) != LDAP_OPT_SUCCESS) {
                radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_DEBUG_LEVEL %d", inst->ldap_debug);
        }
-
        ldap_version = LDAP_VERSION3;
-       if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
-                           &ldap_version) != LDAP_OPT_SUCCESS) {
+       if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version) != LDAP_OPT_SUCCESS) {
                radlog(L_ERR, "rlm_ldap: Could not set LDAP version to V3");
        }
-
 #ifdef HAVE_LDAP_START_TLS
-        if (inst->tls_mode) {
+        if(inst->tls_mode) {
                DEBUG("rlm_ldap: setting TLS mode to %d", inst->tls_mode);
-               if (ldap_set_option(ld, LDAP_OPT_X_TLS,
-                                   (void *) &(inst->tls_mode)) != LDAP_OPT_SUCCESS) {
+               if(ldap_set_option(ld, LDAP_OPT_X_TLS,
+                          (void *) &(inst->tls_mode)) != LDAP_OPT_SUCCESS) {
                        ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
                        radlog(L_ERR, "rlm_ldap: could not set LDAP_OPT_X_TLS option %s", ldap_err2string(ldap_errno));
                }
        }
 
-       if (inst->tls_cacertfile != NULL) {
+       if(inst->tls_cacertfile != NULL) {
                DEBUG("rlm_ldap: setting TLS CACert File to %s", inst->tls_cacertfile);
 
                if ( ldap_set_option( NULL, LDAP_OPT_X_TLS_CACERTFILE,
-                                     (void *) inst->tls_cacertfile )
-                    != LDAP_OPT_SUCCESS) {
+                                                         (void *) inst->tls_cacertfile )
+                        != LDAP_OPT_SUCCESS) {
                        radlog(L_ERR, "rlm_ldap: could not set "
-                              "LDAP_OPT_X_TLS_CACERTFILE option to %s", inst->tls_cacertfile);
+                                  "LDAP_OPT_X_TLS_CACERTFILE option to %s", inst->tls_cacertfile);
                }
        }
 
-       if (inst->tls_cacertdir != NULL) {
+       if(inst->tls_cacertdir != NULL) {
                DEBUG("rlm_ldap: setting TLS CACert Directory to %s", inst->tls_cacertdir);
 
                if ( ldap_set_option( NULL, LDAP_OPT_X_TLS_CACERTDIR,
-                                     (void *) inst->tls_cacertdir )
-                    != LDAP_OPT_SUCCESS) {
+                                                         (void *) inst->tls_cacertdir )
+                        != LDAP_OPT_SUCCESS) {
                        radlog(L_ERR, "rlm_ldap: could not set "
-                              "LDAP_OPT_X_TLS_CACERTDIR option to %s", inst->tls_cacertdir);
+                                  "LDAP_OPT_X_TLS_CACERTDIR option to %s", inst->tls_cacertdir);
                }
        }
 
-       if (strcmp(TLS_DEFAULT_VERIFY, inst->tls_require_cert ) != 0 ) {
+       if( strcmp( TLS_DEFAULT_VERIFY, inst->tls_require_cert ) != 0 ) {
                DEBUG("rlm_ldap: setting TLS Require Cert to %s",
-                     inst->tls_require_cert);
+                         inst->tls_require_cert);
        }
 
 
 #ifdef HAVE_LDAP_INT_TLS_CONFIG
-       if (ldap_int_tls_config(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
-                               (inst->tls_require_cert)) != LDAP_OPT_SUCCESS) {
+
+       if ( ldap_int_tls_config( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+                                                         (inst->tls_require_cert) )
+                != LDAP_OPT_SUCCESS) {
                radlog(L_ERR, "rlm_ldap: could not set "
-                      "LDAP_OPT_X_TLS_REQUIRE_CERT option to %s",
-                      inst->tls_require_cert);
+                          "LDAP_OPT_X_TLS_REQUIRE_CERT option to %s",
+                          inst->tls_require_cert);
        }
+
 #endif
 
-       if (inst->tls_certfile != NULL) {
+       if(inst->tls_certfile != NULL) {
                DEBUG("rlm_ldap: setting TLS Cert File to %s", inst->tls_certfile);
 
-               if (ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE,
-                                   (void *) inst->tls_certfile)
-                   != LDAP_OPT_SUCCESS) {
+               if ( ldap_set_option( NULL, LDAP_OPT_X_TLS_CERTFILE,
+                                                         (void *) inst->tls_certfile )
+                        != LDAP_OPT_SUCCESS) {
                        radlog(L_ERR, "rlm_ldap: could not set "
-                              "LDAP_OPT_X_TLS_CERTFILE option to %s",
-                              inst->tls_certfile);
+                                  "LDAP_OPT_X_TLS_CERTFILE option to %s",
+                                  inst->tls_certfile);
                }
        }
 
-       if (inst->tls_keyfile != NULL) {
-               DEBUG("rlm_ldap: setting TLS Key File to %s",
-                     inst->tls_keyfile);
+       if(inst->tls_keyfile != NULL) {
+               DEBUG("rlm_ldap: setting TLS Key File to %s", inst->tls_keyfile);
 
                if ( ldap_set_option( NULL, LDAP_OPT_X_TLS_KEYFILE,
-                                     (void *) inst->tls_keyfile )
-                    != LDAP_OPT_SUCCESS) {
+                                                         (void *) inst->tls_keyfile )
+                        != LDAP_OPT_SUCCESS) {
                        radlog(L_ERR, "rlm_ldap: could not set "
-                              "LDAP_OPT_X_TLS_KEYFILE option to %s",
-                              inst->tls_keyfile);
+                                  "LDAP_OPT_X_TLS_KEYFILE option to %s",
+                                  inst->tls_keyfile);
                }
        }
 
-       if (inst->tls_randfile != NULL) {
-               DEBUG("rlm_ldap: setting TLS Key File to %s",
-                     inst->tls_randfile);
+       if(inst->tls_randfile != NULL) {
+               DEBUG("rlm_ldap: setting TLS Key File to %s", inst->tls_randfile);
 
-               if (ldap_set_option(NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
-                                   (void *) inst->tls_randfile)
-                   != LDAP_OPT_SUCCESS) {
+               if ( ldap_set_option( NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
+                                                         (void *) inst->tls_randfile )
+                        != LDAP_OPT_SUCCESS) {
                        radlog(L_ERR, "rlm_ldap: could not set "
-                              "LDAP_OPT_X_TLS_RANDOM_FILE option to %s",
-                              inst->tls_randfile);
+                                  "LDAP_OPT_X_TLS_RANDOM_FILE option to %s",
+                                  inst->tls_randfile);
                }
        }
-
        if (inst->start_tls) {
                DEBUG("rlm_ldap: starting TLS");
                rc = ldap_start_tls_s(ld, NULL, NULL);
                if (rc != LDAP_SUCCESS) {
                        DEBUG("rlm_ldap: ldap_start_tls_s()");
-                       ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER,
-                                       &ldap_errno);
-                       radlog(L_ERR, "rlm_ldap: could not start TLS %s",
-                              ldap_err2string(ldap_errno));
+                       ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
+                       radlog(L_ERR, "rlm_ldap: could not start TLS %s", ldap_err2string(ldap_errno));
                        *result = RLM_MODULE_FAIL;
                        ldap_unbind_s(ld);
                        return (NULL);
@@ -2284,13 +2268,11 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
 #endif /* HAVE_LDAP_START_TLS */
 
        if (inst->is_url){
-               DEBUG("rlm_ldap: bind as %s/%s to %s",
-                     dn, password, inst->server);
-       } else {
-               DEBUG("rlm_ldap: bind as %s/%s to %s:%d",
-                     dn, password, inst->server, inst->port);
+               DEBUG("rlm_ldap: bind as %s/%s to %s", dn, password, inst->server);
+       }
+       else{
+               DEBUG("rlm_ldap: bind as %s/%s to %s:%d", dn, password, inst->server, inst->port);
        }
-
        msgid = ldap_bind(ld, dn, password,LDAP_AUTH_SIMPLE);
        if (msgid == -1) {
                ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
@@ -2313,7 +2295,7 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
 
        rc = ldap_result(ld, msgid, 1, &(inst->timeout), &res);
 
-       if (rc < 1) {
+       if(rc < 1) {
                DEBUG("rlm_ldap: ldap_result()");
                ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
                if(err != NULL){
@@ -2324,14 +2306,13 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
                                dn, inst->server, (rc == 0) ? "timeout" : ldap_err2string(ldap_errno));
                } else {
                        radlog(L_ERR, "rlm_ldap: %s bind to %s:%d failed: %s",
-                              dn, inst->server, inst->port,
+                               dn, inst->server, inst->port,
                                (rc == 0) ? "timeout" : ldap_err2string(ldap_errno));
                }
                *result = RLM_MODULE_FAIL;
                ldap_unbind_s(ld);
                return (NULL);
        }
-
        ldap_errno = ldap_result2error(ld, res, 1);
        switch (ldap_errno) {
        case LDAP_SUCCESS:
@@ -2343,7 +2324,8 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
                if (auth){
                        DEBUG("rlm_ldap: Bind failed with invalid credentials");
                        *result = RLM_MODULE_REJECT;
-               } else {
+               }
+               else {
                        radlog(L_ERR, "rlm_ldap: LDAP login failed: check identity, password settings in ldap section of radiusd.conf");
                        *result = RLM_MODULE_FAIL;
                }
@@ -2353,14 +2335,13 @@ static LDAP *ldap_connect(void *instance, const char *dn, const char *password,
                break;
 
        default:
-               if (inst->is_url) {
+               if (inst->is_url)
                        radlog(L_ERR,"rlm_ldap: %s bind to %s failed %s",
                                dn, inst->server, ldap_err2string(ldap_errno));
-               } else {
+               else
                        radlog(L_ERR,"rlm_ldap: %s bind to %s:%d failed %s",
                                dn, inst->server, inst->port,
                                ldap_err2string(ldap_errno));
-               }
                *result = RLM_MODULE_FAIL;
                if(err != NULL){
                        ldap_get_option(ld, LDAP_OPT_ERROR_STRING, err);
@@ -2385,10 +2366,38 @@ ldap_detach(void *instance)
        ldap_instance  *inst = instance;
        TLDAP_RADIUS *pair, *nextpair;
 
-       if (inst->conns) {
-               int i;
+       if (inst->server)
+               free((char *) inst->server);
+       if (inst->login)
+               free((char *) inst->login);
+       if (inst->password)
+               free((char *) inst->password);
+       if (inst->basedn)
+               free((char *) inst->basedn);
+       if (inst->dictionary_mapping)
+               free(inst->dictionary_mapping);
+       if (inst->filter)
+               free((char *) inst->filter);
+       if (inst->base_filter)
+               free((char *) inst->base_filter);
+       if (inst->passwd_hdr)
+               free((char *) inst->passwd_hdr);
+       if (inst->passwd_attr)
+               free((char *) inst->passwd_attr);
+       if (inst->groupname_attr)
+               free((char *) inst->groupname_attr);
+       if (inst->groupmemb_filt)
+               free((char *) inst->groupmemb_filt);
+       if (inst->groupmemb_attr)
+               free((char *) inst->groupmemb_attr);
+       if (inst->access_attr)
+               free((char *) inst->access_attr);
+       if (inst->profile_attr)
+               free((char *) inst->profile_attr);
+       if (inst->conns){
+               int i=0;
 
-               for (i = 0;i < inst->num_conns; i++) {
+               for(;i<inst->num_conns;i++){
                        if (inst->conns[i].ld){
                                ldap_unbind_s(inst->conns[i].ld);
                        }
@@ -2398,10 +2407,10 @@ ldap_detach(void *instance)
        }
 
 #ifdef NOVELL
-       if (inst->apc_conns){
+       if (inst->apc_conns){ 
                int i;
 
-               for (i = 0; i < inst->num_conns; i++) {
+               for(i = 0; i < inst->num_conns; i++){
                        if (inst->apc_conns[i].ld){
                                ldap_unbind_s(inst->apc_conns[i].ld);
                        }
@@ -2443,7 +2452,6 @@ ldap_detach(void *instance)
        return 0;
 }
 
-
 #ifdef FIELDCPY
 static void
 fieldcpy(char *string, char **uptr)
@@ -2475,42 +2483,16 @@ fieldcpy(char *string, char **uptr)
        return;
 }
 #endif
-
-/*
- *     Copied from src/lib/token.c
- */
-static const LRAD_NAME_NUMBER tokens[] = {
-       { "=~", T_OP_REG_EQ,    }, /* order is important! */
-       { "!~", T_OP_REG_NE,    },
-       { "{",  T_LCBRACE,      },
-       { "}",  T_RCBRACE,      },
-       { "(",  T_LBRACE,       },
-       { ")",  T_RBRACE,       },
-       { ",",  T_COMMA,        },
-       { "+=", T_OP_ADD,       },
-       { "-=", T_OP_SUB,       },
-       { ":=", T_OP_SET,       },
-       { "=*", T_OP_CMP_TRUE,  },
-       { "!*", T_OP_CMP_FALSE, },
-       { "==", T_OP_CMP_EQ,    },
-       { "=",  T_OP_EQ,        },
-       { "!=", T_OP_NE,        },
-       { ">=", T_OP_GE,        },
-       { ">",  T_OP_GT,        },
-       { "<=", T_OP_LE,        },
-       { "<",  T_OP_LT,        },
-       { NULL, 0}
-};
-
 /*****************************************************************************
  *     Get RADIUS attributes from LDAP object
  *     ( according to draft-adoba-radius-05.txt
  *       <http://www.ietf.org/internet-drafts/draft-adoba-radius-05.txt> )
  *
  *****************************************************************************/
-static VALUE_PAIR *ldap_pairget(LDAP *ld, LDAPMessage *entry,
-                               TLDAP_RADIUS *item_map,
-                               VALUE_PAIR **pairs, int is_check)
+
+static VALUE_PAIR *
+ldap_pairget(LDAP * ld, LDAPMessage * entry,
+            TLDAP_RADIUS * item_map, VALUE_PAIR **pairs,char is_check)
 {
        char          **vals;
        int             vals_count;
@@ -2524,7 +2506,6 @@ static VALUE_PAIR *ldap_pairget(LDAP *ld, LDAPMessage *entry,
        VALUE_PAIR     *pairlist = NULL;
        VALUE_PAIR     *newpair = NULL;
        char            do_xlat = FALSE;
-       char            print_buffer[2048];
 
        /*
         *      check if there is a mapping from this LDAP attribute
@@ -2579,9 +2560,7 @@ static VALUE_PAIR *ldap_pairget(LDAP *ld, LDAPMessage *entry,
                                operator = gettoken(&ptr, buf, sizeof(buf));
                                if (operator < T_EQSTART || operator > T_EQEND) {
                                        /* no leading operator found */
-                                       if (element->operator != T_OP_INVALID)
-                                               operator = element->operator;
-                                       else if (is_check)
+                                       if (is_check)
                                                operator = T_OP_CMP_EQ;
                                        else
                                                operator = T_OP_EQ;
@@ -2622,6 +2601,8 @@ static VALUE_PAIR *ldap_pairget(LDAP *ld, LDAPMessage *entry,
                                        continue;
                                }
 
+                               DEBUG("rlm_ldap: Adding %s as %s, value %s & op=%d", element->attr, element->radius_attr, value, operator);
+
                                /*
                                 *      Create the pair.
                                 */
@@ -2632,18 +2613,12 @@ static VALUE_PAIR *ldap_pairget(LDAP *ld, LDAPMessage *entry,
                                        radlog(L_ERR, "rlm_ldap: Failed to create the pair: %s", librad_errstr);
                                        continue;
                                }
-
                                if (do_xlat) {
                                        newpair->flags.do_xlat = 1;
-                                       strlcpy(newpair->vp_strvalue, buf,
-                                               sizeof(newpair->vp_strvalue));
+                                       strNcpy(newpair->strvalue, buf,
+                                               sizeof(newpair->strvalue));
                                        newpair->length = 0;
                                }
-                               vp_prints(print_buffer, sizeof(print_buffer),
-                                         newpair);
-                               DEBUG("rlm_ldap: LDAP attribute %s as RADIUS attribute %s",
-                                     element->attr, print_buffer);
-
 
                                /*
                                 *      Add the pair into the packet.
@@ -2661,12 +2636,11 @@ static VALUE_PAIR *ldap_pairget(LDAP *ld, LDAPMessage *entry,
 }
 
 /* globally exported name */
-module_t rlm_ldap = {
-       RLM_MODULE_INIT,
+module_t        rlm_ldap = {
        "LDAP",
        RLM_TYPE_THREAD_SAFE,   /* type: reserved        */
+       NULL,                   /* initialization        */
        ldap_instantiate,       /* instantiation         */
-       ldap_detach,            /* detach                */
        {
                ldap_authenticate,      /* authentication        */
                ldap_authorize,         /* authorization         */
@@ -2676,9 +2650,11 @@ module_t rlm_ldap = {
                NULL,                   /* pre-proxy             */
                NULL,                   /* post-proxy            */
 #ifdef NOVELL
-               ldap_postauth           /* post-auth             */
+               ldap_postauth                   /* post-auth             */
 #else
                NULL
 #endif
        },
+       ldap_detach,            /* detach                */
+       NULL,                   /* destroy               */
 };
diff --git a/src/modules/rlm_linelog/Makefile b/src/modules/rlm_linelog/Makefile
deleted file mode 100755 (executable)
index a863f82..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile
-#
-# Version:     $Id$
-#
-
-TARGET         = rlm_linelog
-SRCS           = rlm_linelog.c
-
-include ../rules.mak
diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c
deleted file mode 100755 (executable)
index bdb9dfd..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * rlm_linelog.c
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004,2006  The FreeRADIUS server project
- * Copyright 2004  Alan DeKok <aland@freeradius.org>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-/*
- *     Define a structure for our module configuration.
- *
- *     These variables do not need to be in a structure, but it's
- *     a lot cleaner to do so, and a pointer to the structure can
- *     be used as the instance handle.
- */
-typedef struct rlm_linelog_t {
-       char            *filename;
-       char            *line;
-} rlm_linelog_t;
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-       { "filename",  PW_TYPE_STRING_PTR,
-         offsetof(rlm_linelog_t,filename), NULL,  NULL},
-       { "format",  PW_TYPE_STRING_PTR,
-         offsetof(rlm_linelog_t,line), NULL,  NULL},
-       { NULL, -1, 0, NULL, NULL }             /* end the list */
-};
-
-
-static int linelog_detach(void *instance)
-{
-       rlm_linelog_t *inst = instance;
-
-
-       free(inst);
-       return 0;
-}
-
-/*
- *     Instantiate the module.
- */
-static int linelog_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_linelog_t *inst;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       inst = rad_malloc(sizeof(*inst));
-       memset(inst, 0, sizeof(*inst));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, inst, module_config) < 0) {
-               linelog_detach(inst);
-               return -1;
-       }
-
-       *instance = inst;
-
-       return 0;
-}
-
-
-/*
- *     Escape unprintable characters.
- */
-static int linelog_escape_func(char *out, int outlen, const char *in)
-{
-       int len = 0;
-
-       if (outlen == 0) return 0;
-       if (outlen == 1) {
-               *out = '\0';
-               return 0;
-       }
-
-       while (in[0]) {
-               if (in[0] >= ' ') {
-                       if (in[0] == '\\') {
-                               if (outlen <= 2) break;
-                               outlen--;
-                               *out++ = '\\';
-                               len++;
-                       }
-
-                       outlen--;
-                       if (outlen == 1) break;
-                       *out++ = *in++;
-                       len++;
-                       continue;
-               }
-
-               switch (in[0]) {
-               case '\n':
-                       if (outlen <= 2) break;
-                       *out++ = '\\';
-                       *out++ = 'n';
-                       in++;
-                       len += 2;
-                       break;
-
-               case '\r':
-                       if (outlen <= 2) break;
-                       *out++ = '\\';
-                       *out++ = 'r';
-                       in++;
-                       len += 2;
-                       break;
-
-               default:
-                       if (outlen <= 4) break;
-                       snprintf(out, outlen,  "\\%03o", *in);
-                       in++;
-                       out += 4;
-                       outlen -= 4;
-                       len += 4;
-                       break;
-               }
-       }
-
-       *out = '\0';
-       return len;
-}
-
-static int do_linelog(void *instance, REQUEST *request)
-{
-       int fd;
-       char buffer[4096];
-       char line[1024];
-       rlm_linelog_t *inst;
-
-       inst = (rlm_linelog_t*) instance;
-
-       /*
-        *      FIXME: Check length.
-        */
-       radius_xlat(buffer, sizeof(buffer), inst->filename, request, NULL);
-
-       fd = open(buffer, O_WRONLY | O_APPEND | O_CREAT, 0600);
-       if (fd == -1) {
-               radlog(L_ERR, "rlm_linelog: Failed to open %s: %s",
-                      buffer, strerror(errno));
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      FIXME: Check length.
-        */
-       radius_xlat(line, sizeof(line) - 1, inst->line, request,
-                   linelog_escape_func);
-       strcat(line, "\n");
-
-       write(fd, line, strlen(line));
-       close(fd);
-
-       return RLM_MODULE_OK;
-}
-
-
-/*
- *     Externally visible module definition.
- */
-module_t rlm_linelog = {
-       RLM_MODULE_INIT,
-       "linelog",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       linelog_instantiate,            /* instantiation */
-       linelog_detach,                 /* detach */
-       {
-               do_linelog,     /* authentication */
-               do_linelog,     /* authorization */
-               do_linelog,     /* preaccounting */
-               do_linelog,     /* accounting */
-               NULL,           /* checksimul */
-               do_linelog,     /* pre-proxy */
-               do_linelog,     /* post-proxy */
-               do_linelog      /* post-auth */
-       },
-};
diff --git a/src/modules/rlm_logintime/Makefile b/src/modules/rlm_logintime/Makefile
deleted file mode 100644 (file)
index 0706c20..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-TARGET  = rlm_logintime
-SRCS    = rlm_logintime.c timestr.c
-
-include ../rules.mak
diff --git a/src/modules/rlm_logintime/rlm_logintime.c b/src/modules/rlm_logintime/rlm_logintime.c
deleted file mode 100644 (file)
index f0dfe2a..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * rlm_logintime.c
- *
- * Version:  $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2001,2006  The FreeRADIUS server project
- * Copyright 2004  Kostas Kalevras <kkalev@noc.ntua.gr>
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-#include <ctype.h>
-
-/*
- *     Define a structure for our module configuration.
- *
- *     These variables do not need to be in a structure, but it's
- *     a lot cleaner to do so, and a pointer to the structure can
- *     be used as the instance handle.
- */
-typedef struct rlm_logintime_t {
-       char *msg;              /* The Reply-Message passed back to the user
-                                * if the account is outside allowed timestamp */
-       int min_time;
-} rlm_logintime_t;
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-  { "reply-message", PW_TYPE_STRING_PTR, offsetof(rlm_logintime_t,msg), NULL,
-       "You are calling outside your allowed timespan\r\n"},
-  { "minimum-timeout", PW_TYPE_INTEGER, offsetof(rlm_logintime_t,min_time), NULL, "60" },
-  { NULL, -1, 0, NULL, NULL }
-};
-
-static int logintime_detach(void *instance);
-
-/*
- *      Compare the current time to a range.
- */
-static int timecmp(void *instance,
-               REQUEST *req,
-               VALUE_PAIR *request, VALUE_PAIR *check,
-               VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
-{
-       instance = instance;
-       request = request;      /* shut the compiler up */
-       check_pairs = check_pairs;
-       reply_pairs = reply_pairs;
-
-       /*
-        *      If there's a request, use that timestamp.
-        */
-       if (timestr_match((char *)check->vp_strvalue,
-       req ? req->timestamp : time(NULL)) >= 0)
-               return 0;
-
-       return -1;
-}
-
-
-/*
- *     Time-Of-Day support
- */
-static int time_of_day(void *instance,
-                      REQUEST *req,
-                      VALUE_PAIR *request, VALUE_PAIR *check,
-                      VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
-{
-       int scan;
-       int hhmmss, when;
-       char *p;
-       struct tm *tm, s_tm;
-
-       instance = instance;
-       request = request;      /* shut the compiler up */
-       check_pairs = check_pairs;
-       reply_pairs = reply_pairs;
-
-       /*
-        *      Must be called with a request pointer.
-        */
-       if (!req) return -1;
-
-       if (strspn(check->vp_strvalue, "0123456789: ") != strlen(check->vp_strvalue)) {
-               DEBUG("rlm_logintime: Bad Time-Of-Day value \"%s\"",
-                     check->vp_strvalue);
-               return -1;
-       }
-
-       tm = localtime_r(&req->timestamp, &s_tm);
-       hhmmss = (tm->tm_hour * 3600) + (tm->tm_min * 60) + tm->tm_sec;
-
-       /*
-        *      Time of day is a 24-hour clock
-        */
-       p = check->vp_strvalue;
-       scan = atoi(p);
-       p = strchr(p, ':');
-       if ((scan > 23) || !p) {
-               DEBUG("rlm_logintime: Bad Time-Of-Day value \"%s\"",
-                     check->vp_strvalue);
-               return -1;
-       }
-       when = scan * 3600;
-       p++;
-
-       scan = atoi(p);
-       if (scan > 59) {
-               DEBUG("rlm_logintime: Bad Time-Of-Day value \"%s\"",
-                     check->vp_strvalue);
-               return -1;
-       }
-       when += scan * 60;
-
-       p = strchr(p, ':');
-       if (p) {
-               scan = atoi(p + 1);
-               if (scan > 59) {
-                       DEBUG("rlm_logintime: Bad Time-Of-Day value \"%s\"",
-                             check->vp_strvalue);
-                       return -1;
-               }
-               when += scan;
-       }
-
-       fprintf(stderr, "returning %d - %d\n",
-               hhmmss, when);
-
-       return hhmmss - when;
-}
-
-/*
- *      Check if account has expired, and if user may login now.
- */
-static int logintime_authorize(void *instance, REQUEST *request)
-{
-       rlm_logintime_t *data = (rlm_logintime_t *)instance;
-       VALUE_PAIR *check_item = NULL;
-       int r;
-
-       if ((check_item = pairfind(request->config_items, PW_LOGIN_TIME)) != NULL) {
-
-               /*
-                *      Authentication is OK. Now see if this
-                *      user may login at this time of the day.
-                */
-               DEBUG("rlm_logintime: Checking Login-Time: '%s'",check_item->vp_strvalue);
-               r = timestr_match((char *)check_item->vp_strvalue,
-               request->timestamp);
-               if (r == 0) {   /* unlimited */
-                       /*
-                        *      Do nothing: login-time is OK.
-                        */
-
-               /*
-                *      Session-Timeout needs to be at least
-                *      60 seconds, some terminal servers
-                *      ignore smaller values.
-                */
-                       DEBUG("rlm_logintime: timestr returned unlimited");
-               } else if (r < data->min_time) {
-                       char logstr[MAX_STRING_LEN];
-                       VALUE_PAIR *module_fmsg_vp;
-
-                       /*
-                        *      User called outside allowed time interval.
-                        */
-
-                       DEBUG("rlm_logintime: timestr returned reject");
-                       if (data->msg && data->msg[0]){
-                               char msg[MAX_STRING_LEN];
-                               VALUE_PAIR *tmp;
-
-                               if (!radius_xlat(msg, sizeof(msg), data->msg, request, NULL)) {
-                                       radlog(L_ERR, "rlm_logintime: xlat failed.");
-                                       return RLM_MODULE_FAIL;
-                               }
-                               pairfree(&request->reply->vps);
-                               tmp = pairmake("Reply-Message", msg, T_OP_SET);
-                               request->reply->vps = tmp;
-                       }
-
-                       snprintf(logstr, sizeof(logstr), "Outside allowed timespan (time allowed %s)",
-                       check_item->vp_strvalue);
-                       module_fmsg_vp = pairmake("Module-Failure-Message", logstr, T_OP_EQ);
-                       pairadd(&request->packet->vps, module_fmsg_vp);
-
-                       return RLM_MODULE_REJECT;
-
-               } else if (r > 0) {
-                       VALUE_PAIR *reply_item;
-
-                       /*
-                        *      User is allowed, but set Session-Timeout.
-                        */
-                       DEBUG("rlm_logintime: timestr returned accept");
-                       if ((reply_item = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL) {
-                               if (reply_item->vp_integer > (unsigned) r)
-                                       reply_item->vp_integer = r;
-                       } else {
-                               reply_item = radius_paircreate(request,
-                                                              &request->reply->vps,
-                                                              PW_SESSION_TIMEOUT,
-                                                              PW_TYPE_INTEGER);
-                               reply_item->vp_integer = r;
-                       }
-                       DEBUG("rlm_logintime: Session-Timeout set to: %d",r);
-               }
-       }
-       else
-               return RLM_MODULE_NOOP;
-
-       return RLM_MODULE_OK;
-}
-
-
-/*
- *     Do any per-module initialization that is separate to each
- *     configured instance of the module.  e.g. set up connections
- *     to external databases, read configuration files, set up
- *     dictionary entries, etc.
- *
- *     If configuration information is given in the config section
- *     that must be referenced in later calls, store a handle to it
- *     in *instance otherwise put a null pointer there.
- */
-static int logintime_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_logintime_t *data;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       data = rad_malloc(sizeof(*data));
-       if (!data) {
-               radlog(L_ERR, "rlm_logintime: rad_malloc() failed.");
-               return -1;
-       }
-       memset(data, 0, sizeof(*data));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, data, module_config) < 0) {
-               free(data);
-               radlog(L_ERR, "rlm_logintime: Configuration parsing failed.");
-               return -1;
-       }
-
-       if (data->min_time == 0){
-               radlog(L_ERR, "rlm_logintime: Minimum timeout should be non zero.");
-               free(data);
-               return -1;
-       }
-
-       /*
-        * Register a Current-Time comparison function
-        */
-       paircompare_register(PW_CURRENT_TIME, 0, timecmp, data);
-       paircompare_register(PW_TIME_OF_DAY, 0, time_of_day, data);
-
-       *instance = data;
-
-       return 0;
-}
-
-static int logintime_detach(void *instance)
-{
-       rlm_logintime_t *data = (rlm_logintime_t *) instance;
-
-       paircompare_unregister(PW_CURRENT_TIME, timecmp);
-       paircompare_unregister(PW_TIME_OF_DAY, time_of_day);
-       free(instance);
-       return 0;
-}
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- *
- *     If the module needs to temporarily modify it's instantiation
- *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
- *     The server will then take care of ensuring that the module
- *     is single-threaded.
- */
-module_t rlm_logintime = {
-       RLM_MODULE_INIT,
-       "logintime",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       logintime_instantiate,          /* instantiation */
-       logintime_detach,               /* detach */
-       {
-               NULL,                   /* authentication */
-               logintime_authorize,    /* authorization */
-               NULL,                   /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
-};
index a3232ad..c08d34c 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2001,2006  The FreeRADIUS server project
+ * Copyright 2000,2001  The FreeRADIUS server project
  */
 
 
 
 /*  MPPE support from Takahiro Wagatsuma <waga@sic.shibaura-it.ac.jp> */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
-#include        <freeradius-devel/md5.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
 #include       <ctype.h>
 
+#include       "radiusd.h"
+#include       "modules.h"
+
+#include        "md4.h"
+#include        "md5.h"
+#include       "sha1.h"
+#include       "rad_assert.h"
+
 #include       "smbdes.h"
 
+static const char rcsid[] = "$Id$";
+
+static const char *letters = "0123456789ABCDEF";
+
+/*
+ *     hex2bin converts hexadecimal strings into binary
+ */
+static int hex2bin (const char *szHex, unsigned char* szBin, int len)
+{
+       char * c1, * c2;
+       int i;
+
+       for (i = 0; i < len; i++) {
+               if( !(c1 = memchr(letters, toupper((int) szHex[i << 1]), 16)) ||
+                   !(c2 = memchr(letters, toupper((int) szHex[(i << 1) + 1]), 16)))
+                    break;
+                 szBin[i] = ((c1-letters)<<4) + (c2-letters);
+        }
+        return i;
+}
+
+/*
+ *     bin2hex creates hexadecimal presentation
+ *     of binary data
+ */
+static void bin2hex (const unsigned char *szBin, char *szHex, int len)
+{
+       int i;
+       for (i = 0; i < len; i++) {
+               szHex[i<<1] = letters[szBin[i] >> 4];
+               szHex[(i<<1) + 1] = letters[szBin[i] & 0x0F];
+       }
+}
+
+
 /* Allowable account control bits */
 #define ACB_DISABLED   0x0001  /* 1 = User account disabled */
 #define ACB_HOMDIRREQ  0x0002  /* 1 = Home directory required */
@@ -172,12 +213,12 @@ static void ntpwdhash (unsigned char *szHash, const char *szPassword)
  *     implements RFC2759 ChallengeHash()
  *     generates 64 bit challenge
  */
-static void challenge_hash( const uint8_t *peer_challenge,
-                           const uint8_t *auth_challenge,
-                           const char *user_name, uint8_t *challenge )
+static void challenge_hash( const char *peer_challenge,
+                           const char *auth_challenge,
+                           const char *user_name, char *challenge )
 {
        SHA1_CTX Context;
-       uint8_t hash[20];
+       unsigned char hash[20];
 
        SHA1Init(&Context);
        SHA1Update(&Context, peer_challenge, 16);
@@ -193,30 +234,27 @@ static void challenge_hash( const uint8_t *peer_challenge,
  *     returns 42-octet response string
  */
 static void auth_response(const char *username,
-                         const uint8_t *nt_hash_hash,
-                         uint8_t *ntresponse,
+                         const unsigned char *nt_hash_hash,
+                         unsigned char *ntresponse,
                          char *peer_challenge, char *auth_challenge,
                          char *response)
 {
        SHA1_CTX Context;
-       static const uint8_t magic1[39] =
+       const unsigned char magic1[39] =
        {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
         0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
         0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
         0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74};
 
-       static const uint8_t magic2[41] =
+       const unsigned char magic2[41] =
        {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
         0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
         0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
         0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
         0x6E};
 
-       static const char hex[16] = "0123456789ABCDEF";
-
-       int i;
         char challenge[8];
-       uint8_t digest[20];
+       unsigned char digest[20];
 
        SHA1Init(&Context);
        SHA1Update(&Context, nt_hash_hash, 16);
@@ -239,14 +277,7 @@ static void auth_response(const char *username,
         */
        response[0] = 'S';
        response[1] = '=';
-
-       /*
-        *      The hexadecimal digits [A-F] MUST be uppercase.
-        */
-       for (i = 0; i < sizeof(digest); i++) {
-               response[2 + (i * 2)] = hex[(digest[i] >> 4) & 0x0f];
-               response[3 + (i * 2)] = hex[digest[i] & 0x0f];
-       }
+       bin2hex(digest, response + 2, 20);
 }
 
 
@@ -272,7 +303,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                       char *fmt, char *out, size_t outlen,
                       RADIUS_ESCAPE_STRING func)
 {
-       size_t          i, data_len;
+       int             i, data_len;
        uint8_t         *data = NULL;
        uint8_t         buffer[32];
        VALUE_PAIR      *user_name;
@@ -287,7 +318,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
         *      Challenge means MS-CHAPv1 challenge, or
         *      hash of MS-CHAPv2 challenge, and peer challenge.
         */
-       if (strncasecmp(fmt, "Challenge", 9) == 0) {
+       if (strcasecmp(fmt, "Challenge") == 0) {
                chap_challenge = pairfind(request->packet->vps,
                                          PW_MSCHAP_CHALLENGE);
                if (!chap_challenge) {
@@ -300,9 +331,8 @@ static int mschap_xlat(void *instance, REQUEST *request,
                 *      for MS-CHAPv2
                 */
                if (chap_challenge->length == 8) {
-                       DEBUG2(" mschap1: %02x",
-                              chap_challenge->vp_octets[0]);
-                       data = chap_challenge->vp_octets;
+                       DEBUG2(" mschap1: %02x", chap_challenge->strvalue[0]);
+                       data = chap_challenge->strvalue;
                        data_len = 8;
 
                        /*
@@ -312,7 +342,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                } else if (chap_challenge->length == 16) {
                        char *username_string;
 
-                       DEBUG2(" mschap2: %02x", chap_challenge->vp_octets[0]);
+                       DEBUG2(" mschap2: %02x", chap_challenge->strvalue[0]);
                        response = pairfind(request->packet->vps,
                                            PW_MSCHAP2_RESPONSE);
                        if (!response) {
@@ -338,15 +368,15 @@ static int mschap_xlat(void *instance, REQUEST *request,
                        /*
                         *      with_ntdomain_hack moved here, too.
                         */
-                       if ((username_string = strchr(user_name->vp_strvalue, '\\')) != NULL) {
+                       if ((username_string = strchr(user_name->strvalue, '\\')) != NULL) {
                                if (inst->with_ntdomain_hack) {
                                        username_string++;
                                } else {
                                        DEBUG2("  rlm_mschap: NT Domain delimeter found, should we have enabled with_ntdomain_hack?");
-                                       username_string = user_name->vp_strvalue;
+                                       username_string = user_name->strvalue;
                                }
                        } else {
-                               username_string = user_name->vp_strvalue;
+                               username_string = user_name->strvalue;
                        }
 
                        /*
@@ -354,8 +384,8 @@ static int mschap_xlat(void *instance, REQUEST *request,
                         *      from the MS-CHAPv2 peer challenge,
                         *      our challenge, and the user name.
                         */
-                       challenge_hash(response->vp_octets + 2,
-                                      chap_challenge->vp_octets,
+                       challenge_hash(response->strvalue + 2,
+                                      chap_challenge->strvalue,
                                       username_string, buffer);
                        data = buffer;
                        data_len = 8;
@@ -363,12 +393,12 @@ static int mschap_xlat(void *instance, REQUEST *request,
                        DEBUG2("  rlm_mschap: Invalid MS-CHAP challenge length");
                        return 0;
                }
-
+               
                /*
                 *      Get the MS-CHAPv1 response, or the MS-CHAPv2
                 *      response.
                 */
-       } else if (strncasecmp(fmt, "NT-Response", 11) == 0) {
+       } else if (strcasecmp(fmt, "NT-Response") == 0) {
                response = pairfind(request->packet->vps,
                                    PW_MSCHAP_RESPONSE);
                if (!response) response = pairfind(request->packet->vps,
@@ -383,7 +413,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                 *      if the second octet says so.
                 */
                if ((response->attribute == PW_MSCHAP_RESPONSE) &&
-                   ((response->vp_octets[1] & 0x01) == 0)) {
+                   ((response->strvalue[1] & 0x01) == 0)) {
                        DEBUG2("  rlm_mschap: No NT-Response in MS-CHAP-Response");
                        return 0;
                }
@@ -393,14 +423,14 @@ static int mschap_xlat(void *instance, REQUEST *request,
                 *      the NT-Response at the same offset, and are
                 *      the same length.
                 */
-               data = response->vp_octets + 26;
+               data = response->strvalue + 26;
                data_len = 24;
-
+               
                /*
                 *      LM-Response is deprecated, and exists only
                 *      in MS-CHAPv1, and not often there.
                 */
-       } else if (strncasecmp(fmt, "LM-Response", 11) == 0) {
+       } else if (strcasecmp(fmt, "LM-Response") == 0) {
                response = pairfind(request->packet->vps,
                                    PW_MSCHAP_RESPONSE);
                if (!response) {
@@ -412,17 +442,17 @@ static int mschap_xlat(void *instance, REQUEST *request,
                 *      For MS-CHAPv1, the NT-Response exists only
                 *      if the second octet says so.
                 */
-               if ((response->vp_octets[1] & 0x01) != 0) {
+               if ((response->strvalue[1] & 0x01) != 0) {
                        DEBUG2("  rlm_mschap: No LM-Response in MS-CHAP-Response");
                        return 0;
                }
-               data = response->vp_octets + 2;
+               data = response->strvalue + 2;
                data_len = 24;
 
                /*
                 *      Pull the NT-Domain out of the User-Name, if it exists.
                 */
-       } else if (strncasecmp(fmt, "NT-Domain", 9) == 0) {
+       } else if (strcasecmp(fmt, "NT-Domain") == 0) {
                char *p, *q;
 
                user_name = pairfind(request->packet->vps, PW_USER_NAME);
@@ -430,22 +460,22 @@ static int mschap_xlat(void *instance, REQUEST *request,
                        DEBUG2("  rlm_mschap: No User-Name was found in the request.");
                        return 0;
                }
-
+               
                /*
                 *      First check to see if this is a host/ style User-Name
                 *      (a la Kerberos host principal)
                 */
-               if (strncmp(user_name->vp_strvalue, "host/", 5) == 0) {
+               if (strncmp(user_name->strvalue, "host/", 5) == 0) {
                        /*
                         *      If we're getting a User-Name formatted in this way,
                         *      it's likely due to PEAP.  The Windows Domain will be
                         *      the first domain component following the hostname,
                         *      or the machine name itself if only a hostname is supplied
                         */
-                       p = strchr(user_name->vp_strvalue, '.');
+                       p = strchr(user_name->strvalue, '.');
                        if (!p) {
                                DEBUG2("  rlm_mschap: setting NT-Domain to same as machine name");
-                               strlcpy(out, user_name->vp_strvalue + 5, outlen);
+                               strNcpy(out, user_name->strvalue + 5, outlen);
                        } else {
                                p++;    /* skip the period */
                                q = strchr(p, '.');
@@ -454,11 +484,11 @@ static int mschap_xlat(void *instance, REQUEST *request,
                                 * only if another period was found
                                 */
                                if (q) *q = '\0';
-                               strlcpy(out, p, outlen);
+                               strNcpy(out, p, outlen);
                                if (q) *q = '.';
                        }
                } else {
-                       p = strchr(user_name->vp_strvalue, '\\');
+                       p = strchr(user_name->strvalue, '\\');
                        if (!p) {
                                DEBUG2("  rlm_mschap: No NT-Domain was found in the User-Name.");
                                return 0;
@@ -468,7 +498,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                         *      Hack.  This is simpler than the alternatives.
                         */
                        *p = '\0';
-                       strlcpy(out, user_name->vp_strvalue, outlen);
+                       strNcpy(out, user_name->strvalue, outlen);
                        *p = '\\';
                }
 
@@ -477,7 +507,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                /*
                 *      Pull the User-Name out of the User-Name...
                 */
-       } else if (strncasecmp(fmt, "User-Name", 9) == 0) {
+       } else if (strcasecmp(fmt, "User-Name") == 0) {
                char *p;
 
                user_name = pairfind(request->packet->vps, PW_USER_NAME);
@@ -485,12 +515,12 @@ static int mschap_xlat(void *instance, REQUEST *request,
                        DEBUG2("  rlm_mschap: No User-Name was found in the request.");
                        return 0;
                }
-
+               
                /*
                 *      First check to see if this is a host/ style User-Name
                 *      (a la Kerberos host principal)
                 */
-               if (strncmp(user_name->vp_strvalue, "host/", 5) == 0) {
+               if (strncmp(user_name->strvalue, "host/", 5) == 0) {
                        /*
                         *      If we're getting a User-Name formatted in this way,
                         *      it's likely due to PEAP.  When authenticating this against
@@ -501,22 +531,22 @@ static int mschap_xlat(void *instance, REQUEST *request,
                         *      from that point to the first period into a string and appending
                         *      a $ to the end.
                         */
-                       p = strchr(user_name->vp_strvalue, '.');
+                       p = strchr(user_name->strvalue, '.');
                        /*
                         * use the same hack as above
                         * only if a period was found
                         */
                        if (p) *p = '\0';
-                       snprintf(out, outlen, "%s$", user_name->vp_strvalue + 5);
+                       snprintf(out, outlen, "%s$", user_name->strvalue + 5);
                        if (p) *p = '.';
                } else {
-                       p = strchr(user_name->vp_strvalue, '\\');
+                       p = strchr(user_name->strvalue, '\\');
                        if (p) {
                                p++;    /* skip the backslash */
                        } else {
-                               p = user_name->vp_strvalue; /* use the whole User-Name */
+                               p = user_name->strvalue; /* use the whole User-Name */
                        }
-                       strlcpy(out, p, outlen);
+                       strNcpy(out, p, outlen);
                }
 
                return strlen(out);
@@ -547,7 +577,7 @@ static int mschap_xlat(void *instance, REQUEST *request,
                p = fmt + 8;    /* 7 is the length of 'LM-Hash' */
                if ((p == '\0') || (outlen <= 32))
                        return 0;
-
+                       
                DEBUG("rlm_mschap: LM-Hash: %s",p);
                smbdes_lmpwdhash(p,buffer);
                lrad_bin2hex(buffer, out, 16);
@@ -578,18 +608,18 @@ static int mschap_xlat(void *instance, REQUEST *request,
        }
 
        /*
-        *
+        *      
         */
        for (i = 0; i < data_len; i++) {
                sprintf(out + (2 * i), "%02x", data[i]);
        }
        out[data_len * 2] = '\0';
-
+       
        return data_len * 2;
 }
 
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        /*
         *      Cache the password by default.
         */
@@ -615,6 +645,8 @@ static const CONF_PARSER module_config[] = {
  */
 static int mschap_detach(void *instance){
 #define inst ((rlm_mschap_t *)instance)
+       free(inst->passwd_file);
+       free(inst->ntlm_auth);
        if (inst->xlat_name) {
                xlat_unregister(inst->xlat_name, mschap_xlat);
                free(inst->xlat_name);
@@ -659,15 +691,13 @@ static int mschap_instantiate(CONF_SECTION *conf, void **instance)
        /*
         *      Create the dynamic translation.
         */
-       if (cf_section_name1(conf))
-               xlat_register(cf_section_name1(conf),mschap_xlat, inst);
-
-       if ((xlat_name = cf_section_name2(conf)) != NULL)
-               xlat_register(xlat_name, mschap_xlat, inst);
+       xlat_name = cf_section_name2(conf);
        if (xlat_name == NULL)
                xlat_name = cf_section_name1(conf);
-       if (xlat_name)
+       if (xlat_name){
                inst->xlat_name = strdup(xlat_name);
+               xlat_register(xlat_name, mschap_xlat, inst);
+       }
 
        /*
         *      For backwards compatibility
@@ -693,8 +723,8 @@ static void add_reply(VALUE_PAIR** vp, unsigned char ident,
                return;
        }
 
-       reply_attr->vp_octets[0] = ident;
-       memcpy(reply_attr->vp_octets + 1, value, len);
+       reply_attr->strvalue[0] = ident;
+       memcpy(reply_attr->strvalue + 1, value, len);
        reply_attr->length = len + 1;
        pairadd(vp, reply_attr);
 }
@@ -712,7 +742,7 @@ static void mppe_add_reply(VALUE_PAIR **vp,
               return;
        }
 
-       memcpy(reply_attr->vp_octets, value, len);
+       memcpy(reply_attr->strvalue, value, len);
        reply_attr->length = len;
        pairadd(vp, reply_attr);
 }
@@ -746,7 +776,7 @@ static int do_mschap(rlm_mschap_t *inst,
         */
        vp = pairfind(request->config_items,
                      PW_MS_CHAP_USE_NTLM_AUTH);
-       if (vp) do_ntlm_auth = vp->vp_integer;
+       if (vp) do_ntlm_auth = vp->lvalue;
 
        /*
         *      No ntlm_auth configured, attribute to tell us to
@@ -769,19 +799,19 @@ static int do_mschap(rlm_mschap_t *inst,
                        DEBUG2("  rlm_mschap: FAILED: No NT/LM-Password.  Cannot perform authentication.");
                        return -1;
                }
-
-               smbdes_mschap(password->vp_strvalue, challenge, calculated);
+               
+               smbdes_mschap(password->strvalue, challenge, calculated);
                if (memcmp(response, calculated, 24) != 0) {
                        return -1;
                }
-
+               
                /*
                 *      If the password exists, and is an NT-Password,
                 *      then calculate the hash of the NT hash.  Doing this
                 *      here minimizes work for later.
                 */
                if (password && (password->attribute == PW_NT_PASSWORD)) {
-                       md4_calc(nthashhash, password->vp_strvalue, 16);
+                       md4_calc(nthashhash, password->strvalue, 16);
                } else {
                        memset(nthashhash, 0, 16);
                }
@@ -792,14 +822,29 @@ static int do_mschap(rlm_mschap_t *inst,
                memset(nthashhash, 0, 16);
 
                /*
-                *      Run the program, and expect that we get 16
+                *      Run the program, and expect that we get 16 
                 */
                result = radius_exec_program(inst->ntlm_auth, request,
                                             TRUE, /* wait */
                                             buffer, sizeof(buffer),
-                                            NULL, NULL, 1);
+                                            NULL, NULL);
                if (result != 0) {
+                       char *p;
+                       
                        DEBUG2("  rlm_mschap: External script failed.");
+
+                       vp = pairmake("Module-Failure-Message", "", T_OP_EQ);
+                       if (!vp) {
+                               radlog(L_ERR, "No memory");
+                               return -1;
+                       }
+
+                       p = strchr(buffer, '\n');
+                       if (p) *p = '\0';
+                       snprintf(vp->strvalue, sizeof(vp->strvalue), 
+                                "rlm_mschap: %s", buffer);
+                       vp->length = strlen(vp->strvalue);
+                       pairadd(&request->packet->vps, vp);
                        return -1;
                }
 
@@ -826,7 +871,7 @@ static int do_mschap(rlm_mschap_t *inst,
                /*
                 *      Update the NT hash hash, from the NT key.
                 */
-               if (lrad_hex2bin(buffer + 8, nthashhash, 16) != 16) {
+               if (hex2bin(buffer + 8, nthashhash, 16) != 16) {
                        DEBUG2("  rlm_mschap: Invalid output from ntlm_auth: NT_KEY has non-hex values");
                        return -1;
                }
@@ -962,7 +1007,8 @@ static void mppe_chap2_gen_keys128(uint8_t *nt_hashhash,uint8_t *response,
 static int mschap_authorize(void * instance, REQUEST *request)
 {
 #define inst ((rlm_mschap_t *)instance)
-       VALUE_PAIR *challenge = NULL, *response = NULL;
+       VALUE_PAIR *challenge = NULL;
+       VALUE_PAIR *response = NULL;
        VALUE_PAIR *vp;
 
        challenge = pairfind(request->packet->vps, PW_MSCHAP_CHALLENGE);
@@ -1007,7 +1053,7 @@ static int mschap_authorize(void * instance, REQUEST *request)
  *
  *     If PW_SMB_ACCOUNT_CTRL is not set to ACB_PWNOTREQ we must have
  *     one of:
- *             PAP:      PW_USER_PASSWORD or
+ *             PAP:      PW_PASSWORD or
  *             MS-CHAP:  PW_MSCHAP_CHALLENGE and PW_MSCHAP_RESPONSE or
  *             MS-CHAP2: PW_MSCHAP_CHALLENGE and PW_MSCHAP2_RESPONSE
  *     In case of password mismatch or locked account we MAY return
@@ -1040,7 +1086,7 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                if (password) {
                        smb_ctrl = pairmake("SMB-Account-CTRL", "0", T_OP_SET);
                        pairadd(&request->config_items, smb_ctrl);
-                       smb_ctrl->vp_integer = pdb_decode_acct_ctrl(password->vp_strvalue);
+                       smb_ctrl->lvalue = pdb_decode_acct_ctrl(password->strvalue);
                }
        }
 
@@ -1052,7 +1098,7 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                /*
                 *      Password is not required.
                 */
-               if ((smb_ctrl->vp_integer & ACB_PWNOTREQ) != 0) {
+               if ((smb_ctrl->lvalue & ACB_PWNOTREQ) != 0) {
                        DEBUG2("  rlm_mschap: SMB-Account-Ctrl says no password is required.");
                        return RLM_MODULE_OK;
                }
@@ -1061,7 +1107,7 @@ static int mschap_authenticate(void * instance, REQUEST *request)
        /*
         *      Decide how to get the passwords.
         */
-       password = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
+       password = pairfind(request->config_items, PW_PASSWORD);
 
        /*
         *      We need an LM-Password.
@@ -1073,8 +1119,8 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                 */
                if ((lm_password->length == 16) ||
                    ((lm_password->length == 32) &&
-                    (lrad_hex2bin(lm_password->vp_strvalue,
-                                  lm_password->vp_strvalue, 16) == 16))) {
+                    (hex2bin(lm_password->strvalue,
+                             lm_password->strvalue, 16) == 16))) {
                        DEBUG2("  rlm_mschap: Found LM-Password");
                        lm_password->length = 16;
 
@@ -1084,15 +1130,15 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                }
 
        } else if (!password) {
-               DEBUG2("  rlm_mschap: No Cleartext-Password configured.  Cannot create LM-Password.");
+               DEBUG2("  rlm_mschap: No User-Password configured.  Cannot create LM-Password.");
 
-       } else {                /* there is a configured Cleartext-Password */
+       } else {                /* there is a configured User-Password */
                lm_password = pairmake("LM-Password", "", T_OP_EQ);
                if (!lm_password) {
                        radlog(L_ERR, "No memory");
                } else {
-                       smbdes_lmpwdhash(password->vp_strvalue,
-                                      lm_password->vp_strvalue);
+                       smbdes_lmpwdhash(password->strvalue,
+                                      lm_password->strvalue);
                        lm_password->length = 16;
                        pairadd(&request->config_items, lm_password);
                }
@@ -1105,8 +1151,8 @@ static int mschap_authenticate(void * instance, REQUEST *request)
        if (nt_password) {
                if ((nt_password->length == 16) ||
                    ((nt_password->length == 32) &&
-                    (lrad_hex2bin(nt_password->vp_strvalue,
-                                  nt_password->vp_strvalue, 16) == 16))) {
+                    (hex2bin(nt_password->strvalue,
+                             nt_password->strvalue, 16) == 16))) {
                        DEBUG2("  rlm_mschap: Found NT-Password");
                        nt_password->length = 16;
 
@@ -1115,16 +1161,15 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                        nt_password = NULL;
                }
        } else if (!password) {
-               DEBUG2("  rlm_mschap: No Cleartext-Password configured.  Cannot create NT-Password.");
+               DEBUG2("  rlm_mschap: No User-Password configured.  Cannot create NT-Password.");
 
-       } else {                /* there is a configured Cleartext-Password */
+       } else {                /* there is a configured User-Password */
                nt_password = pairmake("NT-Password", "", T_OP_EQ);
                if (!nt_password) {
                        radlog(L_ERR, "No memory");
                        return RLM_MODULE_FAIL;
                } else {
-                       ntpwdhash(nt_password->vp_strvalue,
-                                 password->vp_strvalue);
+                       ntpwdhash(nt_password->strvalue, password->strvalue);
                        nt_password->length = 16;
                        pairadd(&request->config_items, nt_password);
                }
@@ -1167,7 +1212,7 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                 *      We are doing MS-CHAP.  Calculate the MS-CHAP
                 *      response
                 */
-               if (response->vp_octets[1] & 0x01) {
+               if (response->strvalue[1] & 0x01) {
                        DEBUG2("  rlm_mschap: Told to do MS-CHAPv1 with NT-Password");
                        password = nt_password;
                        offset = 26;
@@ -1180,10 +1225,10 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                /*
                 *      Do the MS-CHAP authentication.
                 */
-               if (do_mschap(inst, request, password, challenge->vp_octets,
-                             response->vp_octets + offset, nthashhash) < 0) {
+               if (do_mschap(inst, request, password, challenge->strvalue,
+                             response->strvalue + offset, nthashhash) < 0) {
                        DEBUG2("  rlm_mschap: MS-CHAP-Response is incorrect.");
-                       add_reply(&request->reply->vps, *response->vp_octets,
+                       add_reply(&request->reply->vps, *response->strvalue,
                                  "MS-CHAP-Error", "E=691 R=1", 9);
                        return RLM_MODULE_REJECT;
                }
@@ -1222,15 +1267,15 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                /*
                 *      with_ntdomain_hack moved here
                 */
-               if ((username_string = strchr(username->vp_strvalue, '\\')) != NULL) {
+               if ((username_string = strchr(username->strvalue, '\\')) != NULL) {
                        if (inst->with_ntdomain_hack) {
                                username_string++;
                        } else {
                                DEBUG2("  rlm_mschap: NT Domain delimeter found, should we have enabled with_ntdomain_hack?");
-                               username_string = username->vp_strvalue;
+                               username_string = username->strvalue;
                        }
                } else {
-                       username_string = username->vp_strvalue;
+                       username_string = username->strvalue;
                }
 
                /*
@@ -1240,18 +1285,18 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                 *      MS-CHAPv2 takes some additional data to create an
                 *      MS-CHAPv1 challenge, and then does MS-CHAPv1.
                 */
-               challenge_hash(response->vp_octets + 2, /* peer challenge */
-                              challenge->vp_octets, /* our challenge */
+               challenge_hash(response->strvalue + 2, /* peer challenge */
+                              challenge->strvalue, /* our challenge */
                               username_string, /* user name */
                               mschapv1_challenge); /* resulting challenge */
-
+               
                DEBUG2("  rlm_mschap: Told to do MS-CHAPv2 for %s with NT-Password",
                       username_string);
 
                if (do_mschap(inst, request, nt_password, mschapv1_challenge,
-                             response->vp_octets + 26, nthashhash) < 0) {
+                             response->strvalue + 26, nthashhash) < 0) {
                        DEBUG2("  rlm_mschap: FAILED: MS-CHAP2-Response is incorrect");
-                       add_reply(&request->reply->vps, *response->vp_octets,
+                       add_reply(&request->reply->vps, *response->strvalue,
                                  "MS-CHAP-Error", "E=691 R=1", 9);
                        return RLM_MODULE_REJECT;
                }
@@ -1264,11 +1309,11 @@ static int mschap_authenticate(void * instance, REQUEST *request)
 
                auth_response(username_string, /* without the domain */
                              nthashhash, /* nt-hash-hash */
-                             response->vp_octets + 26, /* peer response */
-                             response->vp_octets + 2, /* peer challenge */
-                             challenge->vp_octets, /* our challenge */
+                             response->strvalue + 26, /* peer response */
+                             response->strvalue + 2, /* peer challenge */
+                             challenge->strvalue, /* our challenge */
                              msch2resp); /* calculated MPPE key */
-               add_reply( &request->reply->vps, *response->vp_octets,
+               add_reply( &request->reply->vps, *response->strvalue,
                           "MS-CHAP2-Success", msch2resp, 42);
                chap = 2;
 
@@ -1289,10 +1334,10 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                 *      They're found, but they don't exist, so we
                 *      return 'not found'.
                 */
-               if (((smb_ctrl->vp_integer & ACB_DISABLED) != 0) ||
-                   ((smb_ctrl->vp_integer & ACB_NORMAL) == 0)) {
+               if (((smb_ctrl->lvalue & ACB_DISABLED) != 0) ||
+                   ((smb_ctrl->lvalue & ACB_NORMAL) == 0)) {
                        DEBUG2("  rlm_mschap: SMB-Account-Ctrl says that the account is disabled, or is not a normal account.");
-                       add_reply( &request->reply->vps, *response->vp_octets,
+                       add_reply( &request->reply->vps, *response->strvalue,
                                   "MS-CHAP-Error", "E=691 R=1", 9);
                        return RLM_MODULE_NOTFOUND;
                }
@@ -1300,9 +1345,9 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                /*
                 *      User is locked out.
                 */
-               if ((smb_ctrl->vp_integer & ACB_AUTOLOCK) != 0) {
+               if ((smb_ctrl->lvalue & ACB_AUTOLOCK) != 0) {
                        DEBUG2("  rlm_mschap: SMB-Account-Ctrl says that the account is locked out.");
-                       add_reply( &request->reply->vps, *response->vp_octets,
+                       add_reply( &request->reply->vps, *response->strvalue,
                                   "MS-CHAP-Error", "E=647 R=0", 9);
                        return RLM_MODULE_USERLOCK;
                }
@@ -1317,7 +1362,7 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                        DEBUG2("rlm_mschap: adding MS-CHAPv1 MPPE keys");
                        memset(mppe_sendkey, 0, 32);
                        if (lm_password) {
-                               memcpy(mppe_sendkey, lm_password->vp_octets, 8);
+                               memcpy(mppe_sendkey, lm_password->strvalue, 8);
                        }
 
                        /*
@@ -1340,9 +1385,9 @@ static int mschap_authenticate(void * instance, REQUEST *request)
                } else if (chap == 2) {
                        DEBUG2("rlm_mschap: adding MS-CHAPv2 MPPE keys");
                        mppe_chap2_gen_keys128(nthashhash,
-                                              response->vp_octets + 26,
+                                              response->strvalue + 26,
                                               mppe_sendkey, mppe_recvkey);
-
+                       
                        mppe_add_reply(&request->reply->vps,
                                       "MS-MPPE-Recv-Key",
                                       mppe_recvkey, 16);
@@ -1369,19 +1414,20 @@ static int mschap_authenticate(void * instance, REQUEST *request)
 }
 
 module_t rlm_mschap = {
-       RLM_MODULE_INIT,
-       "MS-CHAP",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       mschap_instantiate,             /* instantiation */
-       mschap_detach,          /* detach */
-       {
-               mschap_authenticate,    /* authenticate */
-               mschap_authorize,       /* authorize */
-               NULL,                   /* pre-accounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "MS-CHAP",
+  RLM_TYPE_THREAD_SAFE,                /* type */
+  NULL,                                /* initialize */
+  mschap_instantiate,          /* instantiation */
+  {
+         mschap_authenticate,  /* authenticate */
+         mschap_authorize,     /* authorize */
+         NULL,                 /* pre-accounting */
+         NULL,                 /* accounting */
+         NULL,                 /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  mschap_detach,               /* detach */
+  NULL,                                /* destroy */
 };
index 7c6692d..1031467 100644 (file)
@@ -19,8 +19,6 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-   Copyright 2006 The FreeRADIUS server project
 */
 
 
    should confirm it for yourself (and maybe let me know if you come
    up with a different answer to the one above)
 */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
+#include "libradius.h"
 #include <string.h>
 #include <ctype.h>
 
index ba1d4bc..63f1adc 100644 (file)
@@ -1,11 +1,6 @@
-/* Copyright 2006 The FreeRADIUS server project */
-
 #ifndef _SMBDES_H
 #define _SMBDES_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(smbdes_h, "$Id$")
-
 void smbdes_lmpwdhash(const unsigned char *password,unsigned char *lmhash);
 void smbdes_mschap(const unsigned char *win_password,
                 const unsigned char *challenge, unsigned char *response);
index dd299a1..601a580 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2002  3APA3A for FreeRADIUS project
-   Copyright 2006  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/libradius.h>
-#include        <freeradius-devel/md4.h>
+#include       "autoconf.h"
+#include        <stdio.h>
+#include        <stdlib.h>
+#include        <string.h>
 #include        <ctype.h>
 
+#include        "md4.h"
 
 #include       "smbdes.h"
 
diff --git a/src/modules/rlm_ns_mta_md5/Makefile b/src/modules/rlm_ns_mta_md5/Makefile
new file mode 100644 (file)
index 0000000..bda32e0
--- /dev/null
@@ -0,0 +1,4 @@
+TARGET = rlm_ns_mta_md5
+SRCS   = rlm_ns_mta_md5.c
+
+include ../rules.mak
diff --git a/src/modules/rlm_ns_mta_md5/rlm_ns_mta_md5.c b/src/modules/rlm_ns_mta_md5/rlm_ns_mta_md5.c
new file mode 100644 (file)
index 0000000..53831b9
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * rlm_ns_mta_md5.c    Functions to authenticate using NS-MTA-MD5 passwords.
+ *             Taken from the hacks for qmail located at nrg4u.com
+ *             by Andre Oppermann.
+ *
+ *             NS-MTA-MD5 passwords are 64 byte strings, the first
+ *             32 bytes being the password hash and the last 32 bytes
+ *             the salt.  The clear text password and the salt are MD5
+ *             hashed[1].  If the resulting hash concatenated with the salt
+ *             are equivalent to the original NS-MTA-MD5 password the
+ *             password is correct.
+ *
+ *             [1] Read the source for details.
+ *
+ *             bob Auth-Type := NS-MTA-MD5, NS-MTA-MD5-Password := "f8b4eac9f051a61eebe266f9c29a193626d8eb25c2598c55c8874260b24eb435"
+ *                 Reply-Message = "NS-MTA-MD5 is working!"
+ *             password = "testpass".
+ *
+ *  Version:   $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright 2000  The FreeRADIUS server project
+ * Copyright 2000  Andre Oppermann
+ */
+
+
+static const char rcsid[] = "$Id$";
+
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "md5.h"
+
+#define HASH_LEN 100
+
+static const char *ns_mta_hextab = "0123456789abcdef";
+
+/*
+ *  Smaller & faster than snprintf("%x");
+ */
+static void ns_mta_hexify(char *buffer, char *str, int len)
+{
+  char *pch = str;
+  char ch;
+  int i;
+
+  for(i = 0;i < len; i ++) {
+    ch = pch[i];
+    buffer[2*i] = ns_mta_hextab[(ch>>4) & 15];
+    buffer[2*i + 1] = ns_mta_hextab[ch & 15];
+  }
+  return;
+}
+
+/*
+ *     Do the hash.
+ */
+static char *ns_mta_hash_alg(char *buffer, const char *salt, const char *passwd)
+{
+  MD5_CTX context;
+  char saltstr[2048];
+  unsigned char digest[16];
+
+  snprintf(saltstr, sizeof(saltstr), "%s%c%s%c%s",salt, 89, passwd, 247, salt);
+
+  MD5Init(&context);
+  MD5Update(&context,(unsigned char *)saltstr,strlen(saltstr));
+  MD5Final(digest,&context);
+  ns_mta_hexify(buffer,(char*)digest,16);
+  buffer[32] = '\0';
+  return(buffer);
+}
+
+/*
+ *  Take the clear
+ */
+static int ns_mta_md5_pass(const char *clear, const char *encrypted)
+{
+  char hashed[HASH_LEN];
+  char salt[33];
+
+  if (!(strlen(encrypted) == 64)) {
+    DEBUG2("NS-MTA-MD5 hash not 64 bytes");
+    return -1;
+  }
+
+  memcpy(salt, &encrypted[32], 32);
+  salt[32] = 0;
+  ns_mta_hash_alg(hashed, salt, clear);
+  memcpy(&hashed[32], salt, 33);
+
+  if (strcasecmp(hashed,encrypted) == 0) {
+    return 0;
+  }
+
+  return -1;
+}
+
+/*
+ *  Validate User-Name / Passwd
+ */
+static int module_auth(void *instance, REQUEST *request)
+{
+       VALUE_PAIR *md5_password;
+
+       /*
+        *      We can only authenticate user requests which HAVE
+        *      a User-Password attribute.
+        */
+       if (!request->password) {
+               radlog(L_AUTH, "rlm_ns_mta_md5: Attribute \"User-Password\" is required for authentication.");
+               return RLM_MODULE_INVALID;
+       }
+
+       /*
+        *  Ensure that we're being passed a plain-text password,
+        *  and not anything else.
+        */
+       if (request->password->attribute != PW_PASSWORD) {
+               radlog(L_AUTH, "rlm_ns_mta_md5: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
+               return RLM_MODULE_INVALID;
+       }
+
+       /*
+        *  Find the MD5 encrypted password
+        */
+       md5_password = pairfind(request->config_items, PW_NS_MTA_MD5_PASSWORD);
+       if (!md5_password) {
+               radlog(L_AUTH, "rlm_ns_mta_md5: Cannot find NS-MTA-MD5-Password attribute.");
+               return RLM_MODULE_INVALID;
+       }
+
+       /*
+        *  Check their password against the encrypted one.
+        */
+       if (ns_mta_md5_pass(request->password->strvalue,
+                           md5_password->strvalue) < 0) {
+               return RLM_MODULE_REJECT;
+       }
+
+       return RLM_MODULE_OK;
+}
+
+module_t rlm_ns_mta_md5 = {
+  "NS-MTA-MD5",
+  0,                           /* type: reserved */
+  NULL,                                /* initialize */
+  NULL,                                /* instantiation */
+  {
+         module_auth,          /* authenticate */
+         NULL,                 /* authorize */
+         NULL,                 /* pre-accounting */
+         NULL,                 /* accounting */
+         NULL,                 /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  NULL,                                /* detach */
+  NULL,                                /* destroy */
+};
index 75e923e..ca728dd 100644 (file)
@@ -23,7 +23,7 @@
 TARGET         = @targetname@
 SRCS           = otp_rlm.c otp_radstate.c otp_pwe.c otp_pw_valid.c
 SRCS          += otp_util.c otp_mppe.c
-HEADERS        = extern.h otp_pw_valid.h otp_mppe.h
+HEADERS        = extern.h otp_pw_valid.h otp_mppe.h ident.h
 RLM_CFLAGS     = @otp_cflags@ $(OPENSSL_INCLUDE)
 RLM_LIBS       = @otp_ldflags@ $(OPENSSL_LIBS)
 
index 50869f8..8515d3e 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.5 .
+# From configure.in Revision: 1.1.2.6 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
index 5fad0cb..4dcd5f6 100644 (file)
 #ifndef EXTERN_H
 #define EXTERN_H
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSIDH(extern_h, "$Id$")
 
-#include <freeradius-devel/autoconf.h>
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <autoconf.h>
+#include <radiusd.h>
+#include <modules.h>
 
 #include <sys/types.h>
 #include <pthread.h>
index 995c063..3240d1a 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef OTP_H
 #define OTP_H
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSIDH(otp_h, "$Id$")
 
 #include <sys/types.h>
@@ -44,7 +44,7 @@ RCSIDH(otp_h, "$Id$")
 #define OTP_RC_AUTH_ERR                3
 #define OTP_RC_MAXTRIES                4
 #define OTP_RC_SERVICE_ERR     5
-#define OTP_RC_NEXTPASSCODE    6
+#define OTP_RC_NEXT_PASSCODE   6
 
 #define OTP_MAX_USERNAME_LEN           31
 /* only needs to be MAX_PIN_LEN (16) + MAX_RESPONSE_LEN (16) */
index f4199f6..112edb4 100644 (file)
  * Copyright 2005,2006 TRI-D Systems, Inc.
  */
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSID("$Id$")
 
 /* avoid inclusion of these FR headers which conflict w/ OpenSSL */
 #define _LRAD_MD4_H
 #define _LRAD_SHA1_H
 
-#include <freeradius-devel/rad_assert.h>
+#include <rad_assert.h>
 
 #include "extern.h"
 #include "otp.h"
@@ -178,7 +178,7 @@ otp_mppe(REQUEST *request, otp_pwe_t pwe, const otp_option_t *opt,
       /*                    0x  (ID) ( ASCII("S="ASCII(auth_md))) */
       char auth_octet_string[2 + 2 + (2 * sizeof(auth_md_string))];
 
-      char *username = request->username->vp_strvalue;
+      char *username = request->username->strvalue;
       int username_len = request->username->length;
 
       /* "Magic server to client signing constant" */
@@ -215,14 +215,14 @@ otp_mppe(REQUEST *request, otp_pwe_t pwe, const otp_option_t *opt,
       /* MD1 */
       SHA1_Init(&ctx);
       SHA1_Update(&ctx, password_md_md, MD4_DIGEST_LENGTH);
-      SHA1_Update(&ctx, rvp->vp_strvalue + 26, 24);
+      SHA1_Update(&ctx, rvp->strvalue + 26, 24);
       SHA1_Update(&ctx, magic1, sizeof(magic1));
       SHA1_Final(md1, &ctx);
 
       /* MD2 */
       SHA1_Init(&ctx);
-      SHA1_Update(&ctx, rvp->vp_strvalue + 2, 16);
-      SHA1_Update(&ctx, cvp->vp_strvalue, 16);
+      SHA1_Update(&ctx, rvp->strvalue + 2, 16);
+      SHA1_Update(&ctx, cvp->strvalue, 16);
       SHA1_Update(&ctx, username, username_len);
       SHA1_Final(md2, &ctx);
 
@@ -242,7 +242,7 @@ otp_mppe(REQUEST *request, otp_pwe_t pwe, const otp_option_t *opt,
       /* And then octet conversion.  Ugh! */
       auth_octet_string[0] = '0';
       auth_octet_string[1] = 'x';
-      (void) sprintf(&auth_octet_string[2], "%02X", rvp->vp_strvalue[0]);
+      (void) sprintf(&auth_octet_string[2], "%02X", rvp->strvalue[0]);
       for (i = 0; i < sizeof(auth_md_string) - 1; ++i)
         (void) sprintf(&auth_octet_string[i * 2 +4], "%02X", auth_md_string[i]);
 
@@ -357,7 +357,7 @@ otp_mppe(REQUEST *request, otp_pwe_t pwe, const otp_option_t *opt,
       /* Generate the master session key. */
       SHA1_Init(&ctx);
       SHA1_Update(&ctx, password_md_md, MD4_DIGEST_LENGTH);
-      SHA1_Update(&ctx, rvp->vp_strvalue + 26, 24);
+      SHA1_Update(&ctx, rvp->strvalue + 26, 24);
       SHA1_Update(&ctx, Magic1, sizeof(Magic1));
       SHA1_Final(sha_md, &ctx);
       (void) memcpy(MasterKey, sha_md, 16);
index e1f8452..2b55535 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef OTP_MPPE_H
 #define OTP_MPPE_H
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSIDH(otp_mppe_h, "$Id$")
 
 /* Some hardcoding here ... because not all types have #defines */
index c76e2c0..574afd4 100644 (file)
  * Copyright 2006,2007 TRI-D Systems, Inc.
  */
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSID("$Id$")
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "autoconf.h"
+#include "radiusd.h"
+#include "modules.h"
 
 #include "extern.h"
 #include "otp.h"
 #include "otp_pw_valid.h"
 
-#ifdef HAVE_PTHREAD_H
+#include <errno.h>
 #include <pthread.h>
-#endif
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <sys/un.h>
+#include <unistd.h>
 
 
 /* transform otpd return codes into rlm return codes */
@@ -76,7 +81,7 @@ otp_pw_valid(REQUEST *request, int pwe, const char *challenge,
   otp_request_t        otp_request;
   otp_reply_t  otp_reply;
   VALUE_PAIR   *cvp, *rvp;
-  char         *username = request->username->vp_strvalue;
+  char         *username = request->username->strvalue;
   int          rc;
 
   if (request->username->length > OTP_MAX_USERNAME_LEN) {
@@ -107,7 +112,7 @@ otp_pw_valid(REQUEST *request, int pwe, const char *challenge,
       (void) radlog(L_AUTH, "rlm_otp: passcode for [%s] too long", username);
       return RLM_MODULE_REJECT;
     }
-    (void) strcpy(otp_request.pwe.u.pap.passcode, rvp->vp_strvalue);
+    (void) strcpy(otp_request.pwe.u.pap.passcode, rvp->strvalue);
     break;
 
   case PWE_CHAP:
@@ -121,10 +126,10 @@ otp_pw_valid(REQUEST *request, int pwe, const char *challenge,
                     username);
       return RLM_MODULE_INVALID;
     }
-    (void) memcpy(otp_request.pwe.u.chap.challenge, cvp->vp_strvalue,
+    (void) memcpy(otp_request.pwe.u.chap.challenge, cvp->strvalue,
                   cvp->length);
     otp_request.pwe.u.chap.clen = cvp->length;
-    (void) memcpy(otp_request.pwe.u.chap.response, rvp->vp_strvalue,
+    (void) memcpy(otp_request.pwe.u.chap.response, rvp->strvalue,
                   rvp->length);
     otp_request.pwe.u.chap.rlen = rvp->length;
     break;
@@ -140,10 +145,10 @@ otp_pw_valid(REQUEST *request, int pwe, const char *challenge,
                     username);
       return RLM_MODULE_INVALID;
     }
-    (void) memcpy(otp_request.pwe.u.chap.challenge, cvp->vp_strvalue,
+    (void) memcpy(otp_request.pwe.u.chap.challenge, cvp->strvalue,
                   cvp->length);
     otp_request.pwe.u.chap.clen = cvp->length;
-    (void) memcpy(otp_request.pwe.u.chap.response, rvp->vp_strvalue,
+    (void) memcpy(otp_request.pwe.u.chap.response, rvp->strvalue,
                   rvp->length);
     otp_request.pwe.u.chap.rlen = rvp->length;
     break;
@@ -159,10 +164,10 @@ otp_pw_valid(REQUEST *request, int pwe, const char *challenge,
                     username);
       return RLM_MODULE_INVALID;
     }
-    (void) memcpy(otp_request.pwe.u.chap.challenge, cvp->vp_strvalue,
+    (void) memcpy(otp_request.pwe.u.chap.challenge, cvp->strvalue,
                   cvp->length);
     otp_request.pwe.u.chap.clen = cvp->length;
-    (void) memcpy(otp_request.pwe.u.chap.response, rvp->vp_strvalue,
+    (void) memcpy(otp_request.pwe.u.chap.response, rvp->strvalue,
                   rvp->length);
     otp_request.pwe.u.chap.rlen = rvp->length;
     break;
index 0d9ba6b..ab8dc63 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef OTP_PW_VALID_H
 #define OTP_PW_VALID_H
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSIDH(otp_pw_valid_h, "$Id$")
 
 #include <pthread.h>
index abad891..c3008f7 100644 (file)
  * is not sufficient for X9.9 use.
  */
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSID("$Id$")
 
 /* avoid inclusion of these FR headers which conflict w/ OpenSSL */
 #define _LRAD_MD4_H
 #define _LRAD_SHA1_H
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
+#include <rad_assert.h>
+#include <autoconf.h>
+#include <radiusd.h>
 
 #include "extern.h"
 
index 6b8f632..ad96bf8 100644 (file)
@@ -19,7 +19,7 @@
  * Copyright 2005,2006 TRI-D Systems, Inc.
  */
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSID("$Id$")
 
 /* avoid inclusion of these FR headers which conflict w/ OpenSSL */
index 5a58f6f..a1c7d07 100644 (file)
  * Copyright 2005-2007 TRI-D Systems, Inc.
  */
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSID("$Id$")
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <autoconf.h>
+#include <radiusd.h>
+#include <modules.h>
 
 #include "extern.h"
 #include "otp.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <netinet/in.h>        /* htonl(), ntohl() */
+
 /* Global data */
 static unsigned char hmac_key[16];     /* to protect State attribute  */
 static int ninstance = 0;              /* #instances, for global init */
@@ -184,7 +192,7 @@ otp_authorize(void *instance, REQUEST *request)
     auth_type_found = 0;
     if ((vp = pairfind(request->config_items, PW_AUTHTYPE)) != NULL) {
       auth_type_found = 1;
-      if (strcmp(vp->vp_strvalue, inst->name))
+      if (strcmp(vp->strvalue, inst->name))
         return RLM_MODULE_NOOP;
     }
   }
@@ -298,7 +306,7 @@ otp_authenticate(void *instance, REQUEST *request)
                   __func__);
     return RLM_MODULE_INVALID;
   }
-  username = request->username->vp_strvalue;
+  username = request->username->strvalue;
 
   if ((pwe = otp_pwe_present(request)) == 0) {
     (void) radlog(L_AUTH, "rlm_otp: %s: Attribute \"User-Password\" "
@@ -335,7 +343,7 @@ otp_authenticate(void *instance, REQUEST *request)
      */
 
     /* ASCII decode; this is why OTP_MAX_RADSTATE_LEN has +1 */
-    (void) memcpy(rad_state, vp->vp_strvalue, vp->length);
+    (void) memcpy(rad_state, vp->strvalue, vp->length);
     rad_state[e_length] = '\0';
     if (otp_a2x(rad_state, raw_state) == -1) {
       (void) radlog(L_AUTH, "rlm_otp: %s: bad radstate for [%s]: not hex",
@@ -356,7 +364,7 @@ otp_authenticate(void *instance, REQUEST *request)
       return RLM_MODULE_FAIL;
     }
     /* compare generated state against returned state to verify hmac */
-    if (memcmp(state, vp->vp_strvalue, vp->length)) {
+    if (memcmp(state, vp->strvalue, vp->length)) {
       (void) radlog(L_AUTH, "rlm_otp: %s: bad radstate for [%s]: hmac",
                     __func__, username);
       return RLM_MODULE_REJECT;
@@ -386,6 +394,10 @@ otp_authenticate(void *instance, REQUEST *request)
 static int
 otp_detach(void *instance)
 {
+  otp_option_t *inst = (otp_option_t *) instance;
+
+  free(inst->otpd_rp);
+  free(inst->chal_prompt);
   free(instance);
   /*
    * Only the main thread instantiates and detaches instances,
@@ -405,11 +417,10 @@ otp_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_otp = {
-  RLM_MODULE_INIT,
   "otp",
   RLM_TYPE_THREAD_SAFE,                /* type */
+  NULL,
   otp_instantiate,             /* instantiation */
-  otp_detach,                  /* detach */
   {
     otp_authenticate,          /* authentication */
     otp_authorize,             /* authorization */
@@ -420,4 +431,6 @@ module_t rlm_otp = {
     NULL,                      /* post-proxy */
     NULL                       /* post-auth */
   },
+  otp_detach,                  /* detach */
+  NULL,
 };
index 4c596fb..45f6c8e 100644 (file)
@@ -19,7 +19,7 @@
  * Copyright 2005,2006 TRI-D Systems, Inc.
  */
 
-#include <freeradius-devel/ident.h>
+#include "ident.h"
 RCSID("$Id$")
 
 #include "extern.h"
index 69ae66b..5500f7e 100644 (file)
@@ -1,52 +1,15 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+*/
 
-/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+
+/* Define if you have the <pam/pam_appl.h> header file.  */
 #undef HAVE_PAM_PAM_APPL_H
 
-/* Define to 1 if you have the <security/pam_appl.h> header file. */
+/* Define if you have the <security/pam_appl.h> header file.  */
 #undef HAVE_SECURITY_PAM_APPL_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
index 454059f..5c9f47d 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.6 .
+# From configure.in Revision: 1.5 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -938,7 +938,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1858,7 +1858,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1916,7 +1917,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2032,7 +2034,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2086,7 +2089,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2131,7 +2135,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2175,7 +2180,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2488,7 +2494,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2558,7 +2565,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2639,7 +2647,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2809,7 +2818,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2880,7 +2890,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3809,6 +3820,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3847,12 +3863,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index d4572f2..3633f17 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_pam.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_pam])
@@ -12,22 +11,22 @@ if test x$with_[]modname != xno; then
                [ pam_ldflags="-ldl" ]
        )
 
-       AC_CHECK_LIB(pam, pam_start,
+       AC_CHECK_LIB(pam, pam_start, 
                [ pam_ldflags="-lpam $pam_ldflags" ],
                [ fail=$fail" libpam" ],
                [ $pam_ldflags ]
        )
 
-dnl #
+dnl #  
 dnl #  Yes, these DO have to be on seperate lines,
 dnl #  otherwise autoheader won't pick them up.
-dnl #
+dnl #  
        AC_CHECK_HEADERS( \
                        security/pam_appl.h \
                        pam/pam_appl.h \
                        )
        pam_cflags="-I."
-
+       
        targetname=modname
 else
        targetname=
@@ -39,7 +38,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index 7f020fb..016622f 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 1997  Jeph Blaize <jblaize@kiva.net>
  * Copyright 1999  miguel a.l. paraz <map@iphil.net>
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
 #include       "config.h"
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
 #ifdef HAVE_SECURITY_PAM_APPL_H
 #include       <security/pam_appl.h>
 #endif
@@ -49,11 +50,14 @@ RCSID("$Id$")
 #include       <syslog.h>
 #endif
 
+#include       "radiusd.h"
+#include       "modules.h"
+
 typedef struct rlm_pam_t {
        const char *pam_auth_name;
 } rlm_pam_t;
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        { "pam_auth",    PW_TYPE_STRING_PTR, offsetof(rlm_pam_t,pam_auth_name),
          NULL, "radiusd" },
        { NULL, -1, 0, NULL, NULL }
@@ -88,6 +92,7 @@ static int pam_detach(void *instance)
 {
        rlm_pam_t *data = (rlm_pam_t *) instance;
 
+       free((char *) data->pam_auth_name);
         free((char *) data);
        return 0;
 }
@@ -257,7 +262,7 @@ static int pam_auth(void *instance, REQUEST *request)
         *  Ensure that we're being passed a plain-text password,
         *  and not anything else.
         */
-       if (request->password->attribute != PW_USER_PASSWORD) {
+       if (request->password->attribute != PW_PASSWORD) {
                radlog(L_AUTH, "rlm_pam: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
                return RLM_MODULE_INVALID;
        }
@@ -267,15 +272,15 @@ static int pam_auth(void *instance, REQUEST *request)
         *      for backwards compatibility.
         */
        pair = pairfind(request->config_items, PAM_AUTH_ATTR);
-       if (pair) pam_auth_string = (char *)pair->vp_strvalue;
+       if (pair) pam_auth_string = (char *)pair->strvalue;
 
-       r = pam_pass((char *)request->username->vp_strvalue,
-                    (char *)request->password->vp_strvalue,
+       r = pam_pass((char *)request->username->strvalue,
+                    (char *)request->password->strvalue,
                     pam_auth_string);
 
 #ifdef HAVE_SYSLOG_H
        if (!strcmp(radlog_dir, "syslog")) {
-               openlog(progname, LOG_PID, mainconfig.syslog_facility);
+               openlog(progname, LOG_PID, syslog_facility);
        }
 #endif
 
@@ -286,20 +291,21 @@ static int pam_auth(void *instance, REQUEST *request)
 }
 
 module_t rlm_pam = {
-       RLM_MODULE_INIT,
-       "pam",
-       RLM_TYPE_THREAD_UNSAFE, /* The PAM libraries are not thread-safe */
-       pam_instantiate,                /* instantiation */
-       pam_detach,                     /* detach */
-       {
-               pam_auth,               /* authenticate */
-               NULL,                   /* authorize */
-               NULL,                   /* pre-accounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "Pam",
+  RLM_TYPE_THREAD_UNSAFE,      /* The PAM libraries are not thread-safe */
+  NULL,                                /* initialize */
+  pam_instantiate,             /* instantiation */
+  {
+         pam_auth,             /* authenticate */
+         NULL,                 /* authorize */
+         NULL,                 /* pre-accounting */
+         NULL,                 /* accounting */
+         NULL,                 /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  pam_detach,                  /* detach */
+  NULL,                                /* destroy */
 };
 
index a1184b6..c485337 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2001  Kostas Kalevras <kkalev@noc.ntua.gr>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 #include "../../include/md5.h"
 #include "../../include/sha1.h"
 
@@ -46,6 +49,8 @@ RCSID("$Id$")
 #define PAP_MAX_ENC            9
 
 
+static const char rcsid[] = "$Id$";
+
 /*
  *      Define a structure for our module configuration.
  *
@@ -59,7 +64,6 @@ typedef struct rlm_pap_t {
        int sch;
        char norm_passwd;
        int auto_header;
-       int auth_type;
 } rlm_pap_t;
 
 /*
@@ -71,10 +75,10 @@ typedef struct rlm_pap_t {
  *      to the strdup'd string into 'config.string'.  This gets around
  *      buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
-       { "encryption_scheme", PW_TYPE_STRING_PTR, offsetof(rlm_pap_t,scheme), NULL, "auto" },
+static CONF_PARSER module_config[] = {
+  { "encryption_scheme", PW_TYPE_STRING_PTR, offsetof(rlm_pap_t,scheme), NULL, "crypt" },
        { "auto_header", PW_TYPE_BOOLEAN, offsetof(rlm_pap_t,auto_header), NULL, "no" },
-       { NULL, -1, 0, NULL, NULL }
+  { NULL, -1, 0, NULL, NULL }
 };
 
 static const LRAD_NAME_NUMBER schemes[] = {
@@ -113,6 +117,7 @@ static int pap_detach(void *instance)
 {
        rlm_pap_t *inst = (rlm_pap_t *) instance;
 
+       free((char *)inst->scheme);
        free(inst);
 
        return 0;
@@ -122,7 +127,6 @@ static int pap_detach(void *instance)
 static int pap_instantiate(CONF_SECTION *conf, void **instance)
 {
         rlm_pap_t *inst;
-       DICT_VALUE *dval;
 
         /*
          *      Set up a storage area for instance data
@@ -138,9 +142,10 @@ static int pap_instantiate(CONF_SECTION *conf, void **instance)
          *      fail.
          */
         if (cf_section_parse(conf, inst, module_config) < 0) {
-               pap_detach(inst);
+                pap_detach(inst);
                 return -1;
         }
+
        if (inst->scheme == NULL || strlen(inst->scheme) == 0){
                radlog(L_ERR, "rlm_pap: No scheme defined");
                pap_detach(inst);
@@ -154,20 +159,12 @@ static int pap_instantiate(CONF_SECTION *conf, void **instance)
                return -1;
        }
 
+        *instance = inst;
        inst->name = cf_section_name2(conf);
        if (!inst->name) {
                inst->name = cf_section_name1(conf);
        }
 
-       dval = dict_valbyname(PW_AUTH_TYPE, inst->name);
-       if (dval) {
-               inst->auth_type = dval->value;
-       } else {
-               inst->auth_type = 0;
-       }
-
-        *instance = inst;
-
         return 0;
 }
 
@@ -185,7 +182,7 @@ static int decode_it(const char *src, uint8_t *dst)
                        x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
                else if (src[i] >= 'a' && src[i] <= 'z')
                         x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
-               else if(src[i] >= '0' && src[i] <= '9')
+               else if(src[i] >= '0' && src[i] <= '9') 
                         x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
                else if(src[i] == '+')
                        x = (x << 6) + 62;
@@ -195,11 +192,11 @@ static int decode_it(const char *src, uint8_t *dst)
                        x = (x << 6);
                else return 0;
        }
-
+       
        dst[2] = (unsigned char)(x & 255); x >>= 8;
        dst[1] = (unsigned char)(x & 255); x >>= 8;
        dst[0] = (unsigned char)(x & 255); x >>= 8;
-
+       
        return 1;
 }
 
@@ -211,7 +208,7 @@ static int base64_decode (const char *src, uint8_t *dst)
 {
        int length, equals;
        int i, num;
-       char last[3];
+       uint8_t last[3];
 
        length = equals = 0;
        while (src[length] && src[length] != '=') length++;
@@ -219,7 +216,7 @@ static int base64_decode (const char *src, uint8_t *dst)
        while (src[length + equals] == '=') equals++;
 
        num = (length + equals) / 4;
-
+       
        for (i = 0; i < num - 1; i++) {
                if (!decode_it(src, dst)) return 0;
                src += 4;
@@ -242,17 +239,17 @@ static void normify(VALUE_PAIR *vp, int min_length)
 {
        int decoded;
        char buffer[64];
-
+       
        if ((size_t) min_length >= sizeof(buffer)) return; /* paranoia */
 
        /*
         *      Hex encoding.
         */
        if (vp->length >= (2 * min_length)) {
-               decoded = lrad_hex2bin(vp->vp_octets, buffer, vp->length >> 1);
+               decoded = lrad_hex2bin(vp->strvalue, buffer, vp->length >> 1);
                if (decoded == (vp->length >> 1)) {
                        DEBUG2("rlm_pap: Normalizing %s from hex encoding", vp->name);
-                       memcpy(vp->vp_octets, buffer, decoded);
+                       memcpy(vp->strvalue, buffer, decoded);
                        vp->length = decoded;
                        return;
                }
@@ -263,10 +260,10 @@ static void normify(VALUE_PAIR *vp, int min_length)
         *      and we want to avoid division...
         */
        if ((vp->length * 3) >= ((min_length * 4))) {
-               decoded = base64_decode(vp->vp_octets, buffer);
+               decoded = base64_decode(vp->strvalue, buffer);
                if (decoded >= min_length) {
                        DEBUG2("rlm_pap: Normalizing %s from base64 encoding", vp->name);
-                       memcpy(vp->vp_octets, buffer, decoded);
+                       memcpy(vp->strvalue, buffer, decoded);
                        vp->length = decoded;
                        return;
                }
@@ -289,20 +286,23 @@ static int pap_authorize(void *instance, REQUEST *request)
        rlm_pap_t *inst = instance;
        int auth_type = FALSE;
        int found_pw = FALSE;
+       int user_pw = FALSE;
        VALUE_PAIR *vp, *next;
+       VALUE_PAIR *cleartext_pw = NULL;
 
        for (vp = request->config_items; vp != NULL; vp = next) {
                next = vp->next;
 
                switch (vp->attribute) {
                case PW_USER_PASSWORD: /* deprecated */
+                       user_pw = TRUE;
                        found_pw = TRUE;
 
                        /*
                         *      Look for '{foo}', and use them
                         */
                        if (!inst->auto_header ||
-                           (vp->vp_strvalue[0] != '{')) {
+                           (vp->strvalue[0] != '{')) {
                                break;
                        }
                        /* FALL-THROUGH */
@@ -313,9 +313,9 @@ static int pap_authorize(void *instance, REQUEST *request)
                        uint8_t *p, *q;
                        char buffer[64];
                        VALUE_PAIR *new_vp;
-
+                       
                        found_pw = TRUE;
-                       q = vp->vp_strvalue;
+                       q = vp->strvalue;
                        p = strchr(q + 1, '}');
                        if (!p) {
                                /*
@@ -326,23 +326,24 @@ static int pap_authorize(void *instance, REQUEST *request)
                                 */
                                break;
                        }
-
+                       
                        if ((size_t) (p - q) > sizeof(buffer)) break;
-
+                       
                        memcpy(buffer, q, p - q + 1);
                        buffer[p - q + 1] = '\0';
-
+                       
                        attr = lrad_str2int(header_names, buffer, 0);
                        if (!attr) {
                                DEBUG2("rlm_pap: Found unknown header {%s}: Not doing anything", buffer);
                                break;
                        }
-
-                       new_vp = radius_paircreate(request,
-                                                  &request->config_items,
-                                                  attr, PW_TYPE_STRING);
-                       strcpy(new_vp->vp_strvalue, p + 1);/* bounds OK */
-                       new_vp->length = strlen(new_vp->vp_strvalue);
+                       
+                       new_vp = paircreate(attr, PW_TYPE_STRING);
+                       if (!new_vp) break; /* OOM */
+                       
+                       strcpy(new_vp->strvalue, p + 1);/* bounds OK */
+                       new_vp->length = strlen(new_vp->strvalue);
+                       pairadd(&request->config_items, new_vp);
 
                        /*
                         *      May be old-style User-Password with header.
@@ -355,6 +356,8 @@ static int pap_authorize(void *instance, REQUEST *request)
                        break;
 
                case PW_CLEARTEXT_PASSWORD:
+                       cleartext_pw = vp;
+
                case PW_CRYPT_PASSWORD:
                case PW_NS_MTA_MD5_PASSWORD:
                        found_pw = TRUE;
@@ -380,8 +383,9 @@ static int pap_authorize(void *instance, REQUEST *request)
                         */
                case PW_PROXY_TO_REALM:
                {
-                       REALM *realm = realm_find(vp->vp_strvalue);
-                       if (realm && !realm->auth_pool) {
+                       REALM *realm = realm_find(vp->strvalue, 0);
+                       if (realm &&
+                           (realm->ipaddr != htonl(INADDR_NONE))) {
                                return RLM_MODULE_NOOP;
                        }
                        break;
@@ -394,15 +398,15 @@ static int pap_authorize(void *instance, REQUEST *request)
                         *      Auth-Type := Accept
                         *      Auth-Type := Reject
                         */
-                       if ((vp->vp_integer == 254) ||
-                           (vp->vp_integer == 4)) {
+                       if ((vp->lvalue == 254) ||
+                           (vp->lvalue == 4)) {
                            found_pw = 1;
                        }
                        break;
 
                default:
                        break;  /* ignore it */
-
+                       
                }
        }
 
@@ -410,37 +414,30 @@ static int pap_authorize(void *instance, REQUEST *request)
         *      Print helpful warnings if there was no password.
         */
        if (!found_pw) {
-               /*
-                *      Likely going to be proxied.  Avoid printing
-                *      warning message.
-                */
-               if (pairfind(request->config_items, PW_REALM) ||
-                   (pairfind(request->config_items, PW_PROXY_TO_REALM))) {
-                       return RLM_MODULE_NOOP;
-               }
-
-               /*
-                *      The TLS types don't need passwords.
-                */
-               vp = pairfind(request->packet->vps, PW_EAP_TYPE);
-               if (vp &&
-                   ((vp->vp_integer == 13) || /* EAP-TLS */
-                    (vp->vp_integer == 21) || /* EAP-TTLS */
-                    (vp->vp_integer == 25))) { /* PEAP */
-                       return RLM_MODULE_NOOP;
-               }
-
                DEBUG("rlm_pap: WARNING! No \"known good\" password found for the user.  Authentication may fail because of this.");
                return RLM_MODULE_NOOP;
        }
 
        /*
+        *      For backwards compatibility with all of the other
+        *      modules, copy Cleartext-Password to User-Password
+        */
+       if (cleartext_pw && !user_pw) {
+               vp = paircreate(PW_USER_PASSWORD, PW_TYPE_STRING);
+               if (!vp) return RLM_MODULE_FAIL;
+
+               memcpy(vp, cleartext_pw, sizeof(*vp));
+               vp->next = NULL;
+               pairadd(&request->config_items, vp);
+       }
+
+       /*
         *      Don't touch existing Auth-Types.
         */
        if (auth_type) {
                DEBUG2("rlm_pap: Found existing Auth-Type, not changing it.");
                return RLM_MODULE_NOOP;
-       }
+       }       
 
        /*
         *      Can't do PAP if there's no password.
@@ -459,11 +456,11 @@ static int pap_authorize(void *instance, REQUEST *request)
                return RLM_MODULE_NOOP;
        }
 
-       if (inst->auth_type) {
-               vp = radius_paircreate(request, &request->config_items,
-                                      PW_AUTH_TYPE, PW_TYPE_INTEGER);
-               vp->vp_integer = inst->auth_type;
-       }
+       vp = paircreate(PW_AUTH_TYPE, PW_TYPE_INTEGER);
+       if (!vp) return RLM_MODULE_FAIL;
+       pairparsevalue(vp, inst->name);
+
+       pairadd(&request->config_items, vp);
 
        return RLM_MODULE_UPDATED;
 }
@@ -509,28 +506,28 @@ static int pap_authenticate(void *instance, REQUEST *request)
        }
 
        DEBUG("rlm_pap: login attempt with password %s",
-             request->password->vp_strvalue);
+             request->password->strvalue);
 
        /*
         *      First, auto-detect passwords, by attribute in the
         *      config items.
         */
-       if (inst->sch == PAP_ENC_AUTO) {
+       if ((inst->sch == PAP_ENC_AUTO) || inst->auto_header) {
                for (vp = request->config_items; vp != NULL; vp = vp->next) {
                        switch (vp->attribute) {
                        case PW_USER_PASSWORD: /* deprecated */
                        case PW_CLEARTEXT_PASSWORD: /* preferred */
                                goto do_clear;
-
+                               
                        case PW_CRYPT_PASSWORD:
                                goto do_crypt;
-
+                               
                        case PW_MD5_PASSWORD:
                                goto do_md5;
-
+                               
                        case PW_SHA_PASSWORD:
                                goto do_sha;
-
+                               
                        case PW_NT_PASSWORD:
                                goto do_nt;
 
@@ -548,7 +545,7 @@ static int pap_authenticate(void *instance, REQUEST *request)
 
                        default:
                                break;  /* ignore it */
-
+                               
                        }
                }
 
@@ -558,7 +555,7 @@ static int pap_authenticate(void *instance, REQUEST *request)
 
        } else {
                vp = NULL;
-
+               
                if (inst->sch == PAP_ENC_CRYPT) {
                        vp = pairfind(request->config_items, PW_CRYPT_PASSWORD);
                }
@@ -570,6 +567,7 @@ static int pap_authenticate(void *instance, REQUEST *request)
                        vp = pairfind(request->config_items, PW_USER_PASSWORD);
                        if (!vp) goto fail;
                }
+               scheme = inst->sch;
        }
 
        /*
@@ -578,9 +576,9 @@ static int pap_authenticate(void *instance, REQUEST *request)
        switch (scheme) {
        case PAP_ENC_CLEAR:
        do_clear:
-               DEBUG("rlm_pap: Using clear text password.");
-               if (strcmp((char *) vp->vp_strvalue,
-                          (char *) request->password->vp_strvalue) != 0){
+               DEBUG("rlm_pap: Using clear text password \"%s\".", vp->strvalue);
+               if (strcmp((char *) vp->strvalue,
+                          (char *) request->password->strvalue) != 0){
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: CLEAR TEXT password check failed");
                        goto make_msg;
                }
@@ -588,18 +586,18 @@ static int pap_authenticate(void *instance, REQUEST *request)
                DEBUG("rlm_pap: User authenticated successfully");
                return RLM_MODULE_OK;
                break;
-
+               
        case PAP_ENC_CRYPT:
        do_crypt:
                DEBUG("rlm_pap: Using CRYPT encryption.");
-               if (lrad_crypt_check((char *) request->password->vp_strvalue,
-                                    (char *) vp->vp_strvalue) != 0) {
+               if (lrad_crypt_check((char *) request->password->strvalue,
+                                    (char *) vp->strvalue) != 0) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: CRYPT password check failed");
                        goto make_msg;
                }
                goto done;
                break;
-
+               
        case PW_MD5_PASSWORD:
        do_md5:
                DEBUG("rlm_pap: Using MD5 encryption.");
@@ -610,18 +608,18 @@ static int pap_authenticate(void *instance, REQUEST *request)
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured MD5 password has incorrect length");
                        goto make_msg;
                }
-
+               
                MD5Init(&md5_context);
-               MD5Update(&md5_context, request->password->vp_strvalue,
+               MD5Update(&md5_context, request->password->strvalue,
                          request->password->length);
                MD5Final(digest, &md5_context);
-               if (memcmp(digest, vp->vp_octets, vp->length) != 0) {
+               if (memcmp(digest, vp->strvalue, vp->length) != 0) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: MD5 password check failed");
                        goto make_msg;
                }
                goto done;
                break;
-
+               
        case PW_SMD5_PASSWORD:
        do_smd5:
                DEBUG("rlm_pap: Using SMD5 encryption.");
@@ -632,49 +630,49 @@ static int pap_authenticate(void *instance, REQUEST *request)
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SMD5 password has incorrect length");
                        goto make_msg;
                }
-
+               
                MD5Init(&md5_context);
-               MD5Update(&md5_context, request->password->vp_strvalue,
+               MD5Update(&md5_context, request->password->strvalue,
                          request->password->length);
-               MD5Update(&md5_context, &vp->vp_octets[16], vp->length - 16);
+               MD5Update(&md5_context, &vp->strvalue[16], vp->length - 16);
                MD5Final(digest, &md5_context);
 
                /*
                 *      Compare only the MD5 hash results, not the salt.
                 */
-               if (memcmp(digest, vp->vp_octets, 16) != 0) {
+               if (memcmp(digest, vp->strvalue, 16) != 0) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SMD5 password check failed");
                        goto make_msg;
                }
                goto done;
                break;
-
+               
        case PW_SHA_PASSWORD:
        do_sha:
                DEBUG("rlm_pap: Using SHA1 encryption.");
-
+               
                normify(vp, 20);
                if (vp->length != 20) {
                        DEBUG("rlm_pap: Configured SHA1 password has incorrect length");
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured SHA1 password has incorrect length");
                        goto make_msg;
                }
-
+               
                SHA1Init(&sha1_context);
-               SHA1Update(&sha1_context, request->password->vp_strvalue,
+               SHA1Update(&sha1_context, request->password->strvalue,
                           request->password->length);
                SHA1Final(digest,&sha1_context);
-               if (memcmp(digest, vp->vp_octets, vp->length) != 0) {
+               if (memcmp(digest, vp->strvalue, vp->length) != 0) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SHA1 password check failed");
                        goto make_msg;
                }
                goto done;
                break;
-
+               
        case PW_SSHA_PASSWORD:
        do_ssha:
                DEBUG("rlm_pap: Using SSHA encryption.");
-
+               
                normify(vp, 20);
                if (vp->length <= 20) {
                        DEBUG("rlm_pap: Configured SSHA password has incorrect length");
@@ -682,19 +680,19 @@ static int pap_authenticate(void *instance, REQUEST *request)
                        goto make_msg;
                }
 
-
+               
                SHA1Init(&sha1_context);
-               SHA1Update(&sha1_context, request->password->vp_strvalue,
+               SHA1Update(&sha1_context, request->password->strvalue,
                           request->password->length);
-               SHA1Update(&sha1_context, &vp->vp_octets[20], vp->length - 20);
+               SHA1Update(&sha1_context, &vp->strvalue[20], vp->length - 20);
                SHA1Final(digest,&sha1_context);
-               if (memcmp(digest, vp->vp_octets, 20) != 0) {
+               if (memcmp(digest, vp->strvalue, 20) != 0) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: SSHA password check failed");
                        goto make_msg;
                }
                goto done;
                break;
-
+               
        case PW_NT_PASSWORD:
        do_nt:
                DEBUG("rlm_pap: Using NT encryption.");
@@ -705,26 +703,26 @@ static int pap_authenticate(void *instance, REQUEST *request)
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NT-Password has incorrect length");
                        goto make_msg;
                }
-
+               
                sprintf(buff2,"%%{mschap:NT-Hash %s}",
-                       request->password->vp_strvalue);
+                       request->password->strvalue);
                if (!radius_xlat(digest,sizeof(digest),buff2,request,NULL)){
                        DEBUG("rlm_pap: mschap xlat failed");
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: mschap xlat failed");
                        goto make_msg;
                }
                if ((lrad_hex2bin(digest, digest, 16) != vp->length) ||
-                   (memcmp(digest, vp->vp_octets, vp->length) != 0)) {
+                   (memcmp(digest, vp->strvalue, vp->length) != 0)) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: NT password check failed");
                        goto make_msg;
                }
                goto done;
                break;
-
+               
        case PW_LM_PASSWORD:
        do_lm:
                DEBUG("rlm_pap: Using LM encryption.");
-
+               
                normify(vp, 16);
                if (vp->length != 16) {
                        DEBUG("rlm_pap: Configured LM-Password has incorrect length");
@@ -732,14 +730,14 @@ static int pap_authenticate(void *instance, REQUEST *request)
                        goto make_msg;
                }
                sprintf(buff2,"%%{mschap:LM-Hash %s}",
-                       request->password->vp_strvalue);
+                       request->password->strvalue);
                if (!radius_xlat(digest,sizeof(digest),buff2,request,NULL)){
                        DEBUG("rlm_pap: mschap xlat failed");
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: mschap xlat failed");
                        goto make_msg;
                }
                if ((lrad_hex2bin(digest, digest, 16) != vp->length) ||
-                   (memcmp(digest, vp->vp_octets, vp->length) != 0)) {
+                   (memcmp(digest, vp->strvalue, vp->length) != 0)) {
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: LM password check failed");
                make_msg:
                        DEBUG("rlm_pap: Passwords don't match");
@@ -764,7 +762,7 @@ static int pap_authenticate(void *instance, REQUEST *request)
                /*
                 *      Sanity check the value of NS-MTA-MD5-Password
                 */
-               if (lrad_hex2bin(vp->vp_octets, buff, 32) != 16) {
+               if (lrad_hex2bin(vp->strvalue, buff, 32) != 16) {
                        DEBUG("rlm_pap: Configured NS-MTA-MD5-Password has invalid value");
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: Configured NS-MTA-MD5-Password has invalid value");
                        goto make_msg;
@@ -775,7 +773,7 @@ static int pap_authenticate(void *instance, REQUEST *request)
                 *
                 *      This really: sizeof(buff) - 2 - 2*32 - strlen(passwd)
                 */
-               if (strlen(request->password->vp_strvalue) >= (sizeof(buff2) - 2 - 2 * 32)) {
+               if (strlen(request->password->strvalue) >= (sizeof(buff2) - 2 - 2 * 32)) {
                        DEBUG("rlm_pap: Configured password is too long");
                        snprintf(module_fmsg,sizeof(module_fmsg),"rlm_pap: password is too long");
                        goto make_msg;
@@ -787,13 +785,13 @@ static int pap_authenticate(void *instance, REQUEST *request)
                {
                        char *p = buff2;
 
-                       memcpy(p, &vp->vp_octets[32], 32);
+                       memcpy(p, &vp->strvalue[32], 32);
                        p += 32;
                        *(p++) = 89;
-                       strcpy(p, request->password->vp_strvalue);
+                       strcpy(p, request->password->strvalue);
                        p += strlen(p);
                        *(p++) = 247;
-                       memcpy(p, &vp->vp_octets[32], 32);
+                       memcpy(p, &vp->strvalue[32], 32);
                        p += 32;
 
                        MD5Init(&md5_context);
@@ -825,14 +823,13 @@ static int pap_authenticate(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_pap = {
-       RLM_MODULE_INIT,
        "PAP",
        0,                              /* type */
+       NULL,                           /* initialization */
        pap_instantiate,                /* instantiation */
-       pap_detach,                     /* detach */
        {
                pap_authenticate,       /* authentication */
-               pap_authorize,          /* authorization */
+               pap_authorize,          /* authorization */
                NULL,                   /* preaccounting */
                NULL,                   /* accounting */
                NULL,                   /* checksimul */
@@ -840,4 +837,6 @@ module_t rlm_pap = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       pap_detach,                     /* detach */
+       NULL,                           /* destroy */
 };
index 5c22a68..6df70c6 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+/*#include "autoconf.h"
+#include "libradius.h"*/
+#include "radiusd.h"
+#include "modules.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
 
 struct mypasswd {
        struct mypasswd *next;
@@ -41,7 +44,7 @@ struct hashtable {
        struct mypasswd *last_found;
        char buffer[1024];
        FILE *fp;
-       char delimiter;
+       char *delimiter;
 };
 
 
@@ -74,11 +77,10 @@ static struct mypasswd * mypasswd_malloc(const char* buffer, int nfields, int* l
 }
 
 static int string_to_entry(const char* string, int nfields, char delimiter,
-       struct mypasswd *passwd, size_t bufferlen)
+       struct mypasswd *passwd, int bufferlen)
 {
        char *str;
-       size_t len, i;
-       int fn=0;
+       int len, i, fn=0;
        char *data_beg;
 
 
@@ -88,8 +90,7 @@ static int string_to_entry(const char* string, int nfields, char delimiter,
        if(!len) return 0;
        if (string[len-1] == '\r') len--;
        if(!len) return 0;
-       if (!len || !passwd ||
-           bufferlen < (len + nfields * sizeof (char*) + nfields * sizeof (char) + sizeof (struct mypasswd) + 1) ) return 0;
+       if (!len || !passwd || bufferlen < (len + nfields * sizeof (char*) + nfields * sizeof (char) + sizeof (struct mypasswd) + 1) ) return 0;
        passwd->next = NULL;
        data_beg=(char *)passwd + sizeof(struct mypasswd);
        str = data_beg + nfields * sizeof (char) + nfields * sizeof (char*);
@@ -154,12 +155,12 @@ static void release_ht(struct hashtable * ht){
 }
 
 static struct hashtable * build_hash_table (const char * file, int nfields,
-       int keyfield, int islist, int tablesize, int ignorenis, char delimiter)
+       int keyfield, int islist, int tablesize, int ignorenis, char delimiter)
 {
 #define passwd ((struct mypasswd *) ht->buffer)
        char buffer[1024];
        struct hashtable* ht;
-       size_t len;
+       int len;
        unsigned int h;
        struct mypasswd *hashentry, *hashentry1;
        char *list;
@@ -181,13 +182,13 @@ static struct hashtable * build_hash_table (const char * file, int nfields,
        ht->keyfield = keyfield;
        ht->islist = islist;
        ht->ignorenis = ignorenis;
-       if (delimiter) ht->delimiter = delimiter;
-       else ht->delimiter = ':';
+       if (delimiter && *delimiter) ht->delimiter = delimiter;
+       else ht->delimiter = ":";
        if(!tablesize) return ht;
        if(!(ht->fp = fopen(file,"r"))) {
                free(ht->filename);
                free(ht);
-                              return NULL;
+               return NULL;
        }
        memset(ht->buffer, 0, 1024);
        ht->table = (struct mypasswd **) rad_malloc (tablesize * sizeof(struct mypasswd *));
@@ -206,7 +207,7 @@ static struct hashtable * build_hash_table (const char * file, int nfields,
                                release_hash_table(ht);
                                return ht;
                        }
-                       len = string_to_entry(buffer, nfields, ht->delimiter, hashentry, len);
+                       len = string_to_entry(buffer, nfields, *ht->delimiter, hashentry, len);
                        if(!hashentry->field[keyfield] || *hashentry->field[keyfield] == '\0') {
                                free(hashentry);
                                continue;
@@ -265,10 +266,10 @@ static struct mypasswd * get_next(char *name, struct hashtable *ht)
                }
                return NULL;
        }
-       /*      printf("try to find in file\n"); */
+       printf("try to find in file\n");
        if (!ht->fp) return NULL;
        while (fgets(buffer, 1024,ht->fp)) {
-               if(*buffer && *buffer!='\n' && (len = string_to_entry(buffer, ht->nfields, ht->delimiter, passwd, sizeof(ht->buffer)-1)) &&
+               if(*buffer && *buffer!='\n' && (len = string_to_entry(buffer, ht->nfields, *ht->delimiter, passwd, sizeof(ht->buffer)-1)) &&
                        (!ht->ignorenis || (*buffer !='-' && *buffer != '+') ) ){
                        if(!ht->islist) {
                                if(!strcmp(passwd->field[ht->keyfield], name))
@@ -348,6 +349,7 @@ struct passwd_instance {
        struct mypasswd *pwdfmt;
        char *filename;
        char *format;
+       char *authtype;
        char * delimiter;
        int allowmultiple;
        int ignorenislike;
@@ -360,11 +362,13 @@ struct passwd_instance {
        int ignoreempty;
 };
 
-static const CONF_PARSER module_config[] = {
-       { "filename",   PW_TYPE_FILENAME,
+static CONF_PARSER module_config[] = {
+       { "filename",   PW_TYPE_STRING_PTR,
           offsetof(struct passwd_instance, filename), NULL,  NULL },
        { "format",   PW_TYPE_STRING_PTR,
           offsetof(struct passwd_instance, format), NULL,  NULL },
+       { "authtype",   PW_TYPE_STRING_PTR,
+          offsetof(struct passwd_instance, authtype), NULL,  NULL },
        { "delimiter",   PW_TYPE_STRING_PTR,
           offsetof(struct passwd_instance, delimiter), NULL,  ":" },
        { "ignorenislike",   PW_TYPE_BOOLEAN,
@@ -437,7 +441,7 @@ static int passwd_instantiate(CONF_SECTION *conf, void **instance)
                free(lf);
                return -1;
        }
-       if (! (inst->ht = build_hash_table (inst->filename, nfields, keyfield, listable, inst->hashsize, inst->ignorenislike, *inst->delimiter)) ){
+       if (! (inst->ht = build_hash_table (inst->filename, nfields, keyfield, listable, inst->hashsize, inst->ignorenislike, inst->delimiter)) ){
                radlog(L_ERR, "rlm_passwd: can't build hashtable from passwd file");
                free(lf);
                return -1;
@@ -456,8 +460,8 @@ static int passwd_instantiate(CONF_SECTION *conf, void **instance)
        }
 
        memcpy(inst->pwdfmt->listflag, lf, nfields);
-
        free(lf);
+
        for (i=0; i<nfields; i++) {
                if (*inst->pwdfmt->field[i] == '*') inst->pwdfmt->field[i]++;
                if (*inst->pwdfmt->field[i] == ',') inst->pwdfmt->field[i]++;
@@ -479,7 +483,7 @@ static int passwd_instantiate(CONF_SECTION *conf, void **instance)
        inst->nfields = nfields;
        inst->keyfield = keyfield;
        inst->listable = listable;
-       DEBUG("rlm_passwd: nfields: %d keyfield %d(%s) listable: %s", nfields, keyfield, inst->pwdfmt->field[keyfield], listable?"yes":"no");
+       radlog(L_INFO, "rlm_passwd: nfields: %d keyfield %d(%s) listable: %s", nfields, keyfield, inst->pwdfmt->field[keyfield], listable?"yes":"no");
        return 0;
 
 #undef inst
@@ -488,6 +492,10 @@ static int passwd_instantiate(CONF_SECTION *conf, void **instance)
 static int passwd_detach (void *instance) {
 #define inst ((struct passwd_instance *)instance)
        if(inst->ht) release_ht(inst->ht);
+        if (inst->filename != NULL)    free(inst->filename);
+        if (inst->format != NULL)      free(inst->format);
+        if (inst->authtype != NULL )   free(inst->authtype);
+        if (inst->delimiter != NULL)   free(inst->delimiter);
        free(instance);
        return 0;
 #undef inst
@@ -529,11 +537,11 @@ static int passwd_authorize(void *instance, REQUEST *request)
          key = key->next ){
                switch (inst->keyattrtype) {
                        case PW_TYPE_INTEGER:
-                               snprintf(buffer, 1024, "%u", key->vp_integer);
+                               snprintf(buffer, 1024, "%u", key->lvalue);
                                name = buffer;
                                break;
                        default:
-                               name = key->vp_strvalue;
+                               name = key->strvalue;
                }
                if (! (pw = get_pw_nam(name, inst->ht)) ) {
                        continue;
@@ -549,17 +557,27 @@ static int passwd_authorize(void *instance, REQUEST *request)
        if(!found) {
                return RLM_MODULE_NOTFOUND;
        }
+       if (inst->authtype &&
+           (key = pairmake ("Auth-Type", inst->authtype, T_OP_EQ))) {
+               radlog(L_INFO, "rlm_passwd: Adding \"Auth-Type = %s\"",
+                      inst->authtype);
+               /*
+                *      Don't call pairadd.  pairmove doesn't
+                *      over-write existing attributes.
+                */
+               pairmove(&request->config_items, &key);
+               pairfree(&key); /* pairmove may have NOT moved it */
+       }
        return RLM_MODULE_OK;
 
 #undef inst
 }
 
 module_t rlm_passwd = {
-       RLM_MODULE_INIT,
        "passwd",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialize */
        passwd_instantiate,             /* instantiation */
-       passwd_detach,                  /* detach */
        {
                NULL,                   /* authentication */
                passwd_authorize,       /* authorization */
@@ -570,5 +588,7 @@ module_t rlm_passwd = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       passwd_detach,                  /* detach */
+       NULL                            /* destroy */
 };
 #endif /* TEST */
index 493d850..ca00d8e 100644 (file)
@@ -1,16 +1,9 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
+*/
 
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
index 84fd96c..857224b 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.2 .
+# From configure.in Revision: 1.1.10.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -901,7 +901,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1821,7 +1821,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1879,7 +1880,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1995,7 +1997,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2049,7 +2052,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2094,7 +2098,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2138,7 +2143,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2453,7 +2459,7 @@ fi
            fail=$fail" perl"
        else
           old_CFLAGS=$CFLAGS
-          CFLAGS="$CFLAGS `perl -MExtUtils::Embed -e ccopts`"
+          CFLAGS="$CFLAGS `perl -MExtUtils::Embed -e ccopts; perl -MConfig -e 'print $Config{cppflags}'`"
 
          smart_try_dir=
 
@@ -2495,7 +2501,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2518,8 +2525,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2548,7 +2555,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2626,7 +2634,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2649,8 +2658,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2665,7 +2674,7 @@ echo "${ECHO_T}no" >&6
 fi
 
          if test "x$ac_cv_header_EXTERN_h" = "xyes"; then
-               perl_cflags='`perl -MExtUtils::Embed -e ccopts`'
+               perl_cflags="`perl -MExtUtils::Embed -e ccopts; perl -MConfig -e 'print $Config{cppflags}'`"
          else
                fail="$fail EXTERN.h"
                targetname=
@@ -2709,7 +2718,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2732,8 +2742,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2762,7 +2772,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2840,7 +2851,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2863,8 +2875,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2879,7 +2891,7 @@ echo "${ECHO_T}no" >&6
 fi
 
          if test "x$ac_cv_header_perl_h" = "xyes"; then
-               perl_cflags='`perl -MExtUtils::Embed -e ccopts`'
+               perl_cflags="`perl -MExtUtils::Embed -e ccopts; perl -MConfig -e 'print $Config{cppflags}'`"
          else
                fail="$fail perl.h"
                targetname=
@@ -3707,6 +3719,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3745,12 +3762,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index dfc9e62..0172a57 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_perl.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_perl])
@@ -8,7 +7,7 @@ if test x$with_[]modname != xno; then
        AC_PROG_CC
        AC_PROG_CPP
 
-       dnl put configuration checks here.
+       dnl put configuration checks here.  
        dnl set $fail to what's missing, on fatal errors.
        dnl use AC_MSG_WARN() on important messages.
 
@@ -17,20 +16,20 @@ if test x$with_[]modname != xno; then
            fail=$fail" perl"
        else
           old_CFLAGS=$CFLAGS
-          CFLAGS="$CFLAGS `perl -MExtUtils::Embed -e ccopts`"
+          CFLAGS="$CFLAGS `perl -MExtUtils::Embed -e ccopts; perl -MConfig -e 'print $Config{cppflags}'`"
 
          smart_try_dir=
-         FR_SMART_CHECK_INCLUDE(EXTERN.h)
+         AC_SMART_CHECK_INCLUDE(EXTERN.h)
          if test "x$ac_cv_header_EXTERN_h" = "xyes"; then
-               perl_cflags='`perl -MExtUtils::Embed -e ccopts`'
+               perl_cflags="`perl -MExtUtils::Embed -e ccopts; perl -MConfig -e 'print $Config{cppflags}'`"
          else
                fail="$fail EXTERN.h"
                targetname=
          fi
 
-         FR_SMART_CHECK_INCLUDE(perl.h, [#include <EXTERN.h>])
+         AC_SMART_CHECK_INCLUDE(perl.h, [#include <EXTERN.h>])
          if test "x$ac_cv_header_perl_h" = "xyes"; then
-               perl_cflags='`perl -MExtUtils::Embed -e ccopts`'
+               perl_cflags="`perl -MExtUtils::Embed -e ccopts; perl -MConfig -e 'print $Config{cppflags}'`"
          else
                fail="$fail perl.h"
                targetname=
@@ -53,7 +52,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
                perl_cflags=""
                perl_ldflags=""
index e5f584b..96d5fd2 100644 (file)
@@ -3,19 +3,19 @@
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation; either version 2 of the License, or
 #  (at your option) any later version.
-#
+# 
 #  This program is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
-#
+# 
 #  You should have received a copy of the GNU General Public License
 #  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
-#
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#  
 #  Copyright 2002  The FreeRADIUS server project
 #  Copyright 2002  Boian Jordanov <bjordanov@orbitel.bg>
-#
+#  
 
 #
 # Example code for use with rlm_perl
@@ -37,7 +37,7 @@ use Data::Dumper;
 #my %RAD_CHECK;
 
 #
-# This the remapping of return values
+# This the remapping of return values 
 #
        use constant    RLM_MODULE_REJECT=>    0;#  /* immediately reject the request */
        use constant    RLM_MODULE_FAIL=>      1;#  /* module failed, don't reply */
@@ -82,7 +82,7 @@ sub authenticate {
 sub preacct {
        # For debugging purposes only
 #      &log_request_attributes;
-
+       
        return RLM_MODULE_OK;
 }
 
@@ -91,9 +91,9 @@ sub accounting {
        # For debugging purposes only
 #      &log_request_attributes;
 
-       # You can call another subroutine from here
+       # You can call another subroutine from here 
        &test_call;
-
+       
        return RLM_MODULE_OK;
 }
 
@@ -162,7 +162,7 @@ sub detach {
 #
 
 sub test_call {
-       # Some code goes here
+       # Some code goes here 
 }
 
 sub log_request_attributes {
index 280e200..17bcd93 100644 (file)
@@ -1,4 +1,4 @@
- /*
+/*
  * rlm_perl.c
  *
  * Version:    $Id$
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Boian Jordanov <bjordanov@orbitel.bg>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 
 #ifdef DEBUG
 #undef DEBUG
@@ -45,6 +50,8 @@ RCSID("$Id$")
 extern char **environ;
 #endif
 
+static const char rcsid[] = "$Id$";
+
 #ifdef USE_ITHREADS
 
 /*
@@ -120,7 +127,7 @@ typedef struct perl_inst {
  *     buffer over-flows.
  */
 static const CONF_PARSER module_config[] = {
-       { "module",  PW_TYPE_FILENAME,
+       { "module",  PW_TYPE_STRING_PTR,
          offsetof(PERL_INST,module), NULL,  "module"},
        { "func_authorize", PW_TYPE_STRING_PTR,
          offsetof(PERL_INST,func_authorize), NULL, "authorize"},
@@ -163,13 +170,13 @@ EXTERN_C void boot_DynaLoader(pTHX_ CV* cv);
  *     We clone it for every instance if we have perl
  *     with -Duseithreads compiled in
  */
-static PerlInterpreter *interp = NULL;
+static PerlInterpreter *interp;
 
 static const CONF_PARSER pool_conf[] = {
        { "max_clones", PW_TYPE_INTEGER, offsetof(PERL_POOL, max_clones), NULL,         "32"},
-       { "start_clones",PW_TYPE_INTEGER, offsetof(PERL_POOL, start_clones), NULL,              "32"},
-       { "min_spare_clones",PW_TYPE_INTEGER, offsetof(PERL_POOL, min_spare_clones),NULL,       "0"},
-       { "max_spare_clones",PW_TYPE_INTEGER, offsetof(PERL_POOL,max_spare_clones),NULL,        "32"},
+       { "start_clones",PW_TYPE_INTEGER, offsetof(PERL_POOL, start_clones), NULL,              "5"},
+       { "min_spare_clones",PW_TYPE_INTEGER, offsetof(PERL_POOL, min_spare_clones),NULL,       "3"},
+       { "max_spare_clones",PW_TYPE_INTEGER, offsetof(PERL_POOL,max_spare_clones),NULL,        "3"},
        { "cleanup_delay",PW_TYPE_INTEGER, offsetof(PERL_POOL,cleanup_delay),NULL,              "5"},
        { "max_request_per_clone",PW_TYPE_INTEGER, offsetof(PERL_POOL,max_request_per_clone),NULL,      "0"},
        { NULL, -1, 0, NULL, NULL }             /* end the list */
@@ -250,7 +257,7 @@ static void rlm_perl_close_handles(void **handles)
 static PerlInterpreter *rlm_perl_clone(PerlInterpreter *perl)
 {
        PerlInterpreter *clone;
-       UV clone_flags = 0;
+       UV      clone_flags = 0;
 
        PERL_SET_CONTEXT(perl);
 
@@ -547,7 +554,6 @@ static int init_pool (CONF_SECTION *conf, PERL_INST *inst) {
        int t;
        PERL_POOL       *pool;
 
-
        pool = rad_malloc(sizeof(PERL_POOL));
        memset(pool,0,sizeof(PERL_POOL));
 
@@ -574,6 +580,20 @@ static int init_pool (CONF_SECTION *conf, PERL_INST *inst) {
        return 1;
 }
 #endif
+/*
+ *     Do any per-module initialization.  e.g. set up connections
+ *     to external databases, read configuration files, set up
+ *     dictionary entries, etc.
+ *
+ *     Try to avoid putting too much stuff in here - it's better to
+ *     do it in instantiate() where it is not global.
+ *     I use one global interpetator to make things more fastest for
+ *     Threading env I clone new perl from this interp.
+ */
+static int perl_init(void)
+{
+       return 0;
+}
 
 static void xs_init(pTHX)
 {
@@ -673,7 +693,7 @@ static int perl_xlat(void *instance, REQUEST *request, char *fmt, char * out,
                POPs ;
        } else if (count > 0) {
                tmp = POPp;
-               strlcpy(out, tmp, freespace);
+               strNcpy(out,tmp,freespace);
                ret = strlen(out);
 
                radlog(L_DBG,"rlm_perl: Len is %d , out is %s freespace is %d",
@@ -710,14 +730,12 @@ static int perl_instantiate(CONF_SECTION *conf, void **instance)
        PERL_INST       *inst = (PERL_INST *) instance;
        HV              *rad_reply_hv;
        HV              *rad_check_hv;
-       HV              *rad_config_hv;
        HV              *rad_request_hv;
        HV              *rad_request_proxy_hv;
        HV              *rad_request_proxy_reply_hv;
        AV              *end_AV;
 
-       char *embed[4];
-       const char *xlat_name;
+       char *embed[4], *xlat_name;
        int exitstatus = 0, argc=0;
 
        /*
@@ -750,7 +768,7 @@ static int perl_instantiate(CONF_SECTION *conf, void **instance)
 
 #ifdef USE_ITHREADS
        inst->perl = interp;
-
+       
        if ((inst->perl = perl_alloc()) == NULL) {
                radlog(L_DBG, "rlm_perl: No memory for allocating new perl !");
                return (-1);
@@ -794,14 +812,12 @@ static int perl_instantiate(CONF_SECTION *conf, void **instance)
 
        rad_reply_hv = newHV();
        rad_check_hv = newHV();
-       rad_config_hv = newHV();
        rad_request_hv = newHV();
        rad_request_proxy_hv = newHV();
        rad_request_proxy_reply_hv = newHV();
 
        rad_reply_hv = get_hv("RAD_REPLY",1);
         rad_check_hv = get_hv("RAD_CHECK",1);
-       rad_config_hv = get_hv("RAD_CONFIG",1);
         rad_request_hv = get_hv("RAD_REQUEST",1);
        rad_request_proxy_hv = get_hv("RAD_REQUEST_PROXY",1);
        rad_request_proxy_reply_hv = get_hv("RAD_REQUEST_PROXY_REPLY",1);
@@ -910,7 +926,6 @@ static int get_hv_content(HV *my_hv, VALUE_PAIR **vp)
        I32             key_len, len, i, j;
        int             ret=0;
 
-       *vp = NULL;
        for (i = hv_iterinit(my_hv); i > 0; i--) {
                res_sv = hv_iternextsv(my_hv,&key,&key_len);
                if (SvROK(res_sv) && (SvTYPE(SvRV(res_sv)) == SVt_PVAV)) {
@@ -941,7 +956,6 @@ static int rlmperl_call(void *instance, REQUEST *request, char *function_name)
 
        HV              *rad_reply_hv;
        HV              *rad_check_hv;
-       HV              *rad_config_hv;
        HV              *rad_request_hv;
        HV              *rad_request_proxy_hv;
        HV              *rad_request_proxy_reply_hv;
@@ -979,7 +993,6 @@ static int rlmperl_call(void *instance, REQUEST *request, char *function_name)
 
        rad_reply_hv = get_hv("RAD_REPLY",1);
        rad_check_hv = get_hv("RAD_CHECK",1);
-       rad_config_hv = get_hv("RAD_CONFIG",1);
        rad_request_hv = get_hv("RAD_REQUEST",1);
        rad_request_proxy_hv = get_hv("RAD_REQUEST_PROXY",1);
        rad_request_proxy_reply_hv = get_hv("RAD_REQUEST_PROXY_REPLY",1);
@@ -988,8 +1001,7 @@ static int rlmperl_call(void *instance, REQUEST *request, char *function_name)
        perl_store_vps(request->reply->vps, rad_reply_hv);
        perl_store_vps(request->config_items, rad_check_hv);
        perl_store_vps(request->packet->vps, rad_request_hv);
-       perl_store_vps(request->config_items, rad_config_hv);
-
+       
        if (request->proxy != NULL) {
                perl_store_vps(request->proxy->vps, rad_request_proxy_hv);
        } else {
@@ -1000,7 +1012,10 @@ static int rlmperl_call(void *instance, REQUEST *request, char *function_name)
                perl_store_vps(request->proxy_reply->vps, rad_request_proxy_reply_hv);
        } else {
                hv_undef(rad_request_proxy_reply_hv);
-       }
+       }       
+       
+       vp = NULL;
+
 
        PUSHMARK(SP);
        /*
@@ -1028,56 +1043,28 @@ static int rlmperl_call(void *instance, REQUEST *request, char *function_name)
                        exitstatus = RLM_MODULE_FAIL;
                }
        }
-
+       
 
        PUTBACK;
        FREETMPS;
        LEAVE;
 
-       vp = NULL;
-       if ((get_hv_content(rad_request_hv, &vp)) > 0 ) {
-               pairfree(&request->packet->vps);
-               request->packet->vps = vp;
-               vp = NULL;
-
-               /*
-                *      Update cached copies
-                */
-               request->username = pairfind(request->packet->vps,
-                                            PW_USER_NAME);
-               request->password = pairfind(request->packet->vps,
-                                            PW_USER_PASSWORD);
-               if (!request->password)
-                       request->password = pairfind(request->packet->vps,
-                                                    PW_CHAP_PASSWORD);
-       }
 
        if ((get_hv_content(rad_reply_hv, &vp)) > 0 ) {
-               pairfree(&request->reply->vps);
-               request->reply->vps = vp;
-               vp = NULL;
+               pairmove(&request->reply->vps, &vp);
+               pairfree(&vp);
        }
 
        if ((get_hv_content(rad_check_hv, &vp)) > 0 ) {
-               pairfree(&request->config_items);
-               request->config_items = vp;
-               vp = NULL;
-       }
-
-       if (request->proxy &&
-           (get_hv_content(rad_request_proxy_hv, &vp) > 0)) {
-               pairfree(&request->proxy->vps);
-               request->proxy->vps = vp;
-               vp = NULL;
+               pairmove(&request->config_items, &vp);
+               pairfree(&vp);
        }
-
-       if (request->proxy_reply &&
-           (get_hv_content(rad_request_proxy_reply_hv, &vp) > 0)) {
+       
+       if ((get_hv_content(rad_request_proxy_reply_hv, &vp)) > 0 && request->proxy_reply != NULL) {
                pairfree(&request->proxy_reply->vps);
-               request->proxy_reply->vps = vp;
-               vp = NULL;
+               pairmove(&request->proxy_reply->vps, &vp);
+               pairfree(&vp);
        }
-
        }
 #ifdef USE_ITHREADS
        pool_release(handle,instance);
@@ -1124,7 +1111,7 @@ static int perl_accounting(void *instance, REQUEST *request)
        int             acctstatustype=0;
 
        if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {
-               acctstatustype = pair->vp_integer;
+                acctstatustype = pair->lvalue;
         } else {
                 radlog(L_ERR, "Invalid Accounting Packet");
                 return RLM_MODULE_INVALID;
@@ -1197,7 +1184,7 @@ static int perl_post_auth(void *instance, REQUEST *request)
 static int perl_detach(void *instance)
 {
        PERL_INST       *inst = (PERL_INST *) instance;
-       int             exitstatus = 0, count = 0;
+       int             exitstatus=0,count=0;
 
 #ifdef USE_ITHREADS
        POOL_HANDLE     *handle, *tmp, *tmp2;
@@ -1283,6 +1270,15 @@ static int perl_detach(void *instance)
        xlat_unregister(inst->xlat_name, perl_xlat);
        free(inst->xlat_name);
 
+       if (inst->func_authorize) free(inst->func_authorize);
+       if (inst->func_authenticate) free(inst->func_authenticate);
+       if (inst->func_accounting) free(inst->func_accounting);
+       if (inst->func_preacct) free(inst->func_preacct);
+       if (inst->func_checksimul) free(inst->func_checksimul);
+       if (inst->func_pre_proxy) free(inst->func_pre_proxy);
+       if (inst->func_post_proxy) free(inst->func_post_proxy);
+       if (inst->func_post_auth) free(inst->func_post_auth);
+       if (inst->func_detach) free(inst->func_detach);
 
 #ifdef USE_ITHREADS
        free(inst->perl_pool->head);
@@ -1308,23 +1304,24 @@ static int perl_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_perl = {
-       RLM_MODULE_INIT,
        "perl",                         /* Name */
 #ifdef USE_ITHREADS
        RLM_TYPE_THREAD_SAFE,           /* type */
 #else
        RLM_TYPE_THREAD_UNSAFE,
 #endif
+       perl_init,                      /* initialization */
        perl_instantiate,               /* instantiation */
-       perl_detach,                    /* detach */
        {
-               perl_authenticate,      /* authenticate */
-               perl_authorize,         /* authorize */
-               perl_preacct,           /* preacct */
-               perl_accounting,        /* accounting */
+               perl_authenticate,
+               perl_authorize,
+               perl_preacct,
+               perl_accounting,
                perl_checksimul,        /* check simul */
-               perl_pre_proxy,         /* pre-proxy */
+               perl_pre_proxy,  /* pre-proxy */
                perl_post_proxy,        /* post-proxy */
-               perl_post_auth          /* post-auth */
+               perl_post_auth    /* post-auth */
        },
+       perl_detach,                    /* detach */
+       NULL,                           /* destroy */
 };
diff --git a/src/modules/rlm_policy/Makefile b/src/modules/rlm_policy/Makefile
deleted file mode 100644 (file)
index 808d84a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile
-#
-# Version:     $Id$
-#
-
-TARGET         = rlm_policy
-SRCS           = rlm_policy.c parse.c evaluate.c
-HEADERS                = rlm_policy.h
-RLM_CFLAGS     =
-RLM_LIBS       =
-
-include ../rules.mak
-
-$(LT_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_policy/evaluate.c b/src/modules/rlm_policy/evaluate.c
deleted file mode 100644 (file)
index d3f9cab..0000000
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * evaluate.c          Evaluate a policy language
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004  Alan DeKok <aland@ox.org>
- * Copyright 2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include "rlm_policy.h"
-
-#ifdef HAVE_REGEX_H
-#include <regex.h>
-#endif
-
-#define debug_evaluate if (0) printf
-
-/*
- *     Print stuff we've parsed
- */
-static void policy_print(const policy_item_t *item, int indent)
-{
-       if (!item) {
-               if (indent) printf("%*s", indent, " ");
-               printf("[NULL]\n");
-               return;
-       }
-
-       while (item) {
-               switch (item->type) {
-               case POLICY_TYPE_BAD:
-                       if (indent) printf("%*s", indent, " ");
-                       printf("[BAD STATEMENT]");
-                       break;
-
-               case POLICY_TYPE_PRINT:
-                       if (indent) printf("%*s", indent, " ");
-                       {
-                               const policy_print_t *this;
-
-                               this = (const policy_print_t *) item;
-
-                               if (this->rhs_type == POLICY_LEX_BARE_WORD) {
-                                       printf("print %s\n", this->rhs);
-                               } else {
-                                       printf("print \"%s\"\n", this->rhs);
-                               }
-                       }
-                       break;
-
-               case POLICY_TYPE_ASSIGNMENT:
-                       {
-                               const policy_assignment_t *assign;
-
-                               assign = (const policy_assignment_t *) item;
-                               if (indent) printf("%*s", indent, " ");
-
-                               printf("\t%s %s ", assign->lhs,
-                                      lrad_int2str(rlm_policy_tokens,
-                                                   assign->assign, "?"));
-                               if (assign->rhs_type == POLICY_LEX_BARE_WORD) {
-                                       printf("%s\n", assign->rhs);
-                               } else {
-                                       /*
-                                        *      FIXME: escape "
-                                        */
-                                       printf("\"%s\"\n", assign->rhs);
-                               }
-                       }
-                       break;
-
-               case POLICY_TYPE_CONDITIONAL: /* no indentation here */
-                       {
-                               const policy_condition_t *condition;
-
-                               condition = (const policy_condition_t *) item;
-
-                               printf("(");
-
-                               /*
-                                *      Nested conditions.
-                                */
-                               if (condition->compare == POLICY_LEX_L_BRACKET) {
-                                       policy_print(condition->child, indent);
-                                       printf(")");
-                                       break;
-                               }
-
-                               if (condition->compare == POLICY_LEX_L_NOT) {
-                                       printf("!");
-                                       policy_print(condition->child, indent);
-                                       printf(")");
-                                       break;
-                               }
-
-                               if (condition->compare == POLICY_LEX_CMP_TRUE) {
-                                       printf("%s)", condition->lhs);
-                                       break;
-                               }
-
-                               if (condition->lhs_type == POLICY_LEX_FUNCTION) {
-                                       printf("%s()", condition->lhs);
-                               } else {
-                                       /*
-                                        *      FIXME: escape ",
-                                        *      and move all of this logic
-                                        *      to a function.
-                                        */
-                                       printf("\"%s\"", condition->lhs);
-                               }
-
-                               /*
-                                *      We always print this condition.
-                                */
-                               printf(" %s ", lrad_int2str(rlm_policy_tokens,
-                                                           condition->compare,
-                                                           "?"));
-                               if (condition->rhs_type == POLICY_LEX_BARE_WORD) {
-                                       printf("%s", condition->rhs);
-                               } else {
-                                       /*
-                                        *      FIXME: escape ",
-                                        *      and move all of this logic
-                                        *      to a function.
-                                        */
-                                       printf("\"%s\"", condition->rhs);
-                               }
-                               printf(")");
-
-                               if ((condition->child_condition != POLICY_LEX_BAD) &&
-                                   (condition->child_condition != POLICY_LEX_BARE_WORD)) {
-                                       printf(" %s ", lrad_int2str(rlm_policy_tokens, condition->child_condition, "?"));
-                                       policy_print(condition->child, indent);
-                               }
-                       }
-                       break;
-
-               case POLICY_TYPE_IF:
-                       {
-                               const policy_if_t *statement;
-
-                               statement = (const policy_if_t *) item;
-
-                               if (indent) printf("%*s", indent, " ");
-                               printf("if ");
-                               policy_print(statement->condition, indent);
-                               printf(" {\n");
-                               policy_print(statement->if_true, indent + 1);
-                               if (indent) printf("%*s", indent, " ");
-                               if (statement->if_false) {
-                                       printf("} else ");
-                                       if (statement->if_false->type == POLICY_TYPE_ASSIGNMENT) {
-                                               printf(" { ");
-                                               policy_print(statement->if_false, indent + 1);
-                                               if (indent) printf("%*s", indent, " ");
-                                               printf(" }");
-                                       } else {
-                                               policy_print(statement->if_false, indent + 1);
-                                       }
-                               } else {
-                                       printf("}\n");
-                               }
-                       }
-                       break;
-
-               case POLICY_TYPE_ATTRIBUTE_LIST:
-                       {
-                               const policy_attributes_t *this;
-
-                               this = (const policy_attributes_t *) item;
-
-                               if (indent) printf("%*s", indent, " ");
-                               printf("%s %s {\n",
-                                      lrad_int2str(policy_reserved_words,
-                                                   this->where, "?"),
-                                      lrad_int2str(rlm_policy_tokens,
-                                                   this->how, "?"));
-                               policy_print(this->attributes, indent + 1);
-                               if (indent) printf("%*s", indent, " ");
-                               printf("}\n");
-                       }
-                       break;
-
-               case POLICY_TYPE_NAMED_POLICY:
-                       {
-                               const policy_named_t *this;
-
-                               this = (const policy_named_t *) item;
-                               if (indent) printf("%*s", indent, " ");
-                               printf("policy %s {\n", this->name);
-                               policy_print(this->policy, indent + 1);
-                               if (indent) printf("%*s", indent, " ");
-                               printf("}\n");
-                       }
-                       break;
-
-               case POLICY_TYPE_CALL:
-                       {
-                               const policy_call_t *this;
-
-                               this = (const policy_call_t *) item;
-                               if (indent) printf("%*s", indent, " ");
-                               printf("call %s\n", this->name);
-                       }
-                       break;
-
-               case POLICY_TYPE_RETURN:
-                       {
-                               const policy_return_t *this;
-
-                               this = (const policy_return_t *) item;
-                               if (indent) printf("%*s", indent, " ");
-                               printf("return %s\n",
-                                      lrad_int2str(policy_return_codes,
-                                                   this->rcode, "???"));
-                       }
-                       break;
-
-               case POLICY_TYPE_MODULE:
-                       {
-                               const policy_module_t *this;
-
-                               this = (const policy_module_t *) item;
-                               if (indent) printf("%*s", indent, " ");
-                               printf("module %s <stuff>\n",
-                                      lrad_int2str(policy_component_names,
-                                                   this->component, "???"));
-                       }
-                       break;
-
-               default:
-                       if (indent) printf("%*s", indent, " ");
-                       printf("[HUH?]\n");
-                       break;
-
-               }
-
-               item = item->next;
-       }
-}
-
-
-void rlm_policy_print(const policy_item_t *item)
-{
-       printf("----------------------------------------------------------\n");
-       policy_print(item, 0);
-       printf("----------------------------------------------------------\n");
-}
-
-/*
- *     Internal stack of things to do.  This lets us have function
- *     calls...
- *
- *     Yes, we should learn lex, yacc, etc.
- */
-#define POLICY_MAX_STACK 16
-typedef struct policy_state_t {
-       rlm_policy_t    *inst;
-       REQUEST         *request; /* so it's not passed on the C stack */
-       int             rcode;  /* for functions, etc. */
-       int             component; /* for calling other modules */
-       int             depth;
-       const policy_item_t *stack[POLICY_MAX_STACK];
-} policy_state_t;
-
-
-static int policy_evaluate_name(policy_state_t *state, const char *name);
-
-/*
- *     Push an item onto the state.
- */
-static int policy_stack_push(policy_state_t *state, const policy_item_t *item)
-{
-       rad_assert(state->depth >= 0);
-
-       /*
-        *      Asked to push nothing.  Don't push it.
-        */
-       if (!item) return 1;
-
-       /*
-        *      State is full.  Die.
-        */
-       if (state->depth >= POLICY_MAX_STACK) {
-               return 0;
-       }
-
-       /*
-        *      Walk back up the stack, looking for previous ocurrances
-        *      of this name.  If found, we have infinite recursion,
-        *      which we stop dead in the water!
-        *
-        *      This isn't strictly necessary right now, as we look up
-        *      policies by name when they're first referenced.  This
-        *      means that ALL references are backwards (to the start
-        *      of the file), which means that there are no circular
-        *      references.
-        */
-       if (item->type == POLICY_TYPE_NAMED_POLICY) {
-               int i;
-
-               for (i = 0; i < state->depth; i++) {
-                       /*
-                        *      Check for circular references, by seeing
-                        *      if the function is already on the stack.
-                        *
-                        *      Hmmm... do we want to do this for any type?
-                        */
-                       if (state->stack[i] == item) {
-                               debug_evaluate("Circular call to policy %s\n",
-                                              ((const policy_named_t *) item)->name);
-                               return 0;
-                       }
-               }
-       }
-
-       debug_evaluate("push %d %p\n", state->depth, item);
-
-       state->stack[state->depth] = item;
-       state->depth++;         /* points to unused entry */
-
-       return 1;
-}
-
-
-/*
- *     Pop an item from the state.
- */
-static int policy_stack_pop(policy_state_t *state, const policy_item_t **pitem)
-{
-       rad_assert(pitem != NULL);
-       rad_assert(state->depth >= 0);
-
- redo:
-       if (state->depth == 0) {
-               *pitem = NULL;
-               return 0;
-       }
-
-       *pitem = state->stack[state->depth - 1];
-
-       /*
-        *      Named policies are on the stack for catching recursion.
-        */
-       if ((*pitem)->type == POLICY_TYPE_NAMED_POLICY) {
-               state->depth--;
-               goto redo;
-       }
-
-       /*
-        *      Process the whole item list.
-        */
-       if ((*pitem)->next) {
-               state->stack[state->depth - 1] = (*pitem)->next;
-               debug_evaluate("pop/push %d %p\n", state->depth - 1, *pitem);
-       } else {
-               state->depth--;         /* points to unused entry */
-               debug_evaluate("pop %d %p\n", state->depth, *pitem);
-       }
-
-       return 1;
-}
-
-
-/*
- *     Evaluate a print statement
- */
-static int evaluate_print(policy_state_t *state, const policy_item_t *item)
-{
-       const policy_print_t *this;
-
-       this = (const policy_print_t *) item;
-
-       if (this->rhs_type == POLICY_LEX_BARE_WORD) {
-               printf("%s\n", this->rhs);
-       } else {
-               char buffer[1024];
-
-               radius_xlat(buffer, sizeof(buffer), this->rhs,
-                           state->request, NULL);
-               printf("%s", buffer);
-       }
-
-       /*
-        *      Doesn't change state->rcode
-        */
-
-       return 1;
-}
-
-/*
- *     Return a VALUE_PAIR, given an attribute name.
- *
- *     FIXME: Have it return the N'th one, too, like
- *     doc/variables.txt?
- *
- *     The amount of duplicated code is getting annoying...
- */
-static VALUE_PAIR *find_vp(REQUEST *request, const char *name)
-{
-       const char *p;
-       const DICT_ATTR *dattr;
-       VALUE_PAIR *vps;
-
-       p = name;
-       vps = request->packet->vps;;
-
-       /*
-        *      FIXME: use names from reserved word list?
-        */
-       if (strncasecmp(name, "request:", 8) == 0) {
-               p += 8;
-       } else if (strncasecmp(name, "reply:", 6) == 0) {
-               p += 6;
-               vps = request->reply->vps;
-       } else if (strncasecmp(name, "proxy-request:", 14) == 0) {
-               p += 14;
-               if (request->proxy) {
-                       vps = request->proxy->vps;
-               }
-       } else if (strncasecmp(name, "proxy-reply:", 12) == 0) {
-               p += 12;
-               if (request->proxy_reply) {
-                       vps = request->proxy_reply->vps;
-               }
-       } else if (strncasecmp(name, "control:", 8) == 0) {
-               p += 8;
-               vps = request->config_items;
-       } /* else it must be a bare attribute name */
-
-       if (!vps) {
-               return NULL;
-       }
-
-       dattr = dict_attrbyname(p);
-       if (!dattr) {
-               fprintf(stderr, "No such attribute %s\n", p);
-               return NULL;    /* no such attribute */
-       }
-
-       return pairfind(vps, dattr->attr);
-}
-
-
-/*
- *     Evaluate an assignment
- *
- *     Not really used much...
- */
-static int evaluate_assignment(policy_state_t *state, const policy_item_t *item)
-{
-       const policy_assignment_t *this;
-#if 0
-       const DICT_ATTR *dattr;
-#endif
-
-       this = (const policy_assignment_t *) item;
-
-       rad_assert(this->lhs != NULL);
-       rad_assert(this->rhs != NULL);
-
-#if 0
-       dattr = dict_attrbyname(this->lhs);
-       if (!dattr) {
-               fprintf(stderr, "HUH?\n");
-               return 0;
-       }
-#endif
-
-       return 1;
-}
-
-
-/*
- *     Evaluate a condition
- */
-static int evaluate_condition(policy_state_t *state, const policy_item_t *item)
-{
-       int rcode;
-       const policy_condition_t *this;
-       VALUE_PAIR *vp = NULL;
-       const char *data = NULL;
-       int compare;
-#ifdef HAVE_REGEX_H
-       regex_t reg;
-#endif
-       char buffer[256];
-       char lhs_buffer[2048];
-
-       this = (const policy_condition_t *) item;
-
- redo:
-       /*
-        *      FIXME: Don't always do this...
-        */
-       if (this->compare != POLICY_LEX_L_BRACKET) {
-               if (this->lhs_type == POLICY_LEX_FUNCTION) {
-                       /*
-                        *      We can't call evaluate_call here,
-                        *      because that just pushes stuff onto
-                        *      the stack, and we want to actually
-                        *      evaluate all of it...
-                        */
-                       rcode = policy_evaluate_name(state, this->lhs);
-                       data = lrad_int2str(policy_return_codes, rcode, "???");
-                       strlcpy(lhs_buffer, data, sizeof(lhs_buffer)); /* FIXME: yuck */
-               } else if (this->lhs_type == POLICY_LEX_DOUBLE_QUOTED_STRING) {
-                       if (radius_xlat(lhs_buffer, sizeof(lhs_buffer), this->lhs,
-                                       state->request, NULL) > 0) {
-                               data = lhs_buffer;
-                       }
-               }
-       }
-
-       switch (this->compare) {
-       case POLICY_LEX_L_BRACKET: /* nested brackets are a special case */
-               rcode = evaluate_condition(state, this->child);
-               break;
-
-       case POLICY_LEX_L_NOT:
-               rcode = evaluate_condition(state, this->child);
-               rcode = (rcode == FALSE); /* reverse sense of test */
-               break;
-
-       case POLICY_LEX_CMP_FALSE: /* non-existence */
-               if (this->lhs_type == POLICY_LEX_BARE_WORD) {
-                       vp = find_vp(state->request, this->lhs);
-                       rcode = (vp == NULL);
-               } else {
-                       rcode = (data == NULL);
-               }
-               break;
-
-       case POLICY_LEX_CMP_TRUE: /* existence */
-               if (this->lhs_type == POLICY_LEX_BARE_WORD) {
-                       vp = find_vp(state->request, this->lhs);
-                       rcode = (vp != NULL);
-               } else {
-                       rcode = (data != NULL);
-               }
-               break;
-
-       default:                /* process other comparisons */
-               if ((this->compare != POLICY_LEX_CMP_EQUALS) &&
-#ifdef HAVE_REGEX_H
-                   (this->compare != POLICY_LEX_RX_EQUALS) &&
-                   (this->compare != POLICY_LEX_RX_NOT_EQUALS) &&
-#endif
-                   (this->compare != POLICY_LEX_LT) &&
-                   (this->compare != POLICY_LEX_GT) &&
-                   (this->compare != POLICY_LEX_LE) &&
-                   (this->compare != POLICY_LEX_GE) &&
-                   (this->compare != POLICY_LEX_CMP_NOT_EQUALS)) {
-                       fprintf(stderr, "%d: bad comparison\n",
-                               this->item.lineno);
-                       return FALSE;
-               }
-
-               if (this->lhs_type == POLICY_LEX_BARE_WORD) {
-                       VALUE_PAIR *myvp;
-
-                       vp = find_vp(state->request, this->lhs);
-
-                       /*
-                        *      A op B always returns FALSE if A doesn't
-                        *      exist.
-                        */
-                       if (!vp) return FALSE; /* not in the request */
-
-                       /*
-                        *      FIXME: Move sanity checks to
-                        *      post-parse code, so we don't do
-                        *      it on every packet.
-                        */
-                       vp_prints_value(buffer, sizeof(buffer), vp, 0);
-                       myvp = pairmake(vp->name, this->rhs, T_OP_EQ);
-                       data = buffer;
-
-                       /*
-                        *      FIXME: What to do about comparisons
-                        *      where vp doesn't exist?  Right now,
-                        *      "simplepaircmp" returns -1, which is
-                        *      probably a bad idea.  it should
-                        *      instead take an operator, a pointer to
-                        *      the comparison result, and return
-                        *      "true/false" for "comparions
-                        *      succeeded/failed", which are different
-                        *      error codes than "comparison is less
-                        *      than, equal to, or greater than zero".
-                        */
-                       compare = radius_callback_compare(state->request,
-                                                         vp, myvp, NULL, NULL);
-                       pairfree(&myvp);
-
-               } else {
-                       /*
-                        *      FIXME: Do something for RHS type?
-                        */
-                       printf("CMP %s %s\n", lhs_buffer, this->rhs);
-                       compare = strcmp(lhs_buffer, this->rhs);
-               }
-
-               debug_evaluate("CONDITION COMPARE %d\n", compare);
-
-               switch (this->compare) {
-               case POLICY_LEX_CMP_EQUALS:
-                       rcode = (compare == 0);
-                       break;
-
-               case POLICY_LEX_CMP_NOT_EQUALS:
-                       rcode = (compare != 0);
-                       break;
-
-               case POLICY_LEX_LT:
-                       rcode = (compare < 0);
-                       break;
-
-               case POLICY_LEX_GT:
-                       rcode = (compare > 0);
-                       break;
-
-               case POLICY_LEX_LE:
-                       rcode =(compare <= 0);
-                       break;
-
-               case POLICY_LEX_GE:
-                       rcode = (compare >= 0);
-                       break;
-
-#ifdef HAVE_REGEX_H
-               case POLICY_LEX_RX_EQUALS:
-               { /* FIXME: copied from src/main/valuepair.c */
-                       int i;
-                       regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];
-
-                       /*
-                        *      Include substring matches.
-                        */
-                       if (regcomp(&reg, this->rhs,
-                                   REG_EXTENDED) != 0) {
-                               return FALSE;
-                       }
-                       rad_assert(data != NULL);
-                       rcode = regexec(&reg, data,
-                                       REQUEST_MAX_REGEX + 1,
-                                       rxmatch, 0);
-                       rcode = (rcode == 0);
-                       regfree(&reg);
-
-                       /*
-                        *      Add %{0}, %{1}, etc.
-                        */
-                       for (i = 0; i <= REQUEST_MAX_REGEX; i++) {
-                               char *p;
-                               char rxbuffer[256];
-
-                               /*
-                                *      Didn't match: delete old
-                                *      match, if it existed.
-                                */
-                               if (!rcode ||
-                                   (rxmatch[i].rm_so == -1)) {
-                                       p = request_data_get(state->request, state->request,
-                                                            REQUEST_DATA_REGEX | i);
-                                       if (p) {
-                                               free(p);
-                                               continue;
-                                       }
-
-                                       /*
-                                        *      No previous match
-                                        *      to delete, stop.
-                                        */
-                                       break;
-                               }
-
-                               /*
-                                *      Copy substring into buffer.
-                                */
-                               memcpy(rxbuffer,
-                                      data + rxmatch[i].rm_so,
-                                      rxmatch[i].rm_eo - rxmatch[i].rm_so);
-                               rxbuffer[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0';
-
-                               /*
-                                *      Copy substring, and add it to
-                                *      the request.
-                                *
-                                *      Note that we don't check
-                                *      for out of memory, which is
-                                *      the only error we can get...
-                                */
-                               p = strdup(rxbuffer);
-                               request_data_add(state->request,
-                                                state->request,
-                                                REQUEST_DATA_REGEX | i,
-                                                p, free);
-                       }
-
-               }
-               break;
-
-               case POLICY_LEX_RX_NOT_EQUALS:
-                       regcomp(&reg, this->rhs, REG_EXTENDED|REG_NOSUB);
-                       rad_assert(data != NULL);
-                       rcode = regexec(&reg, data,
-                                       0, NULL, 0);
-                       rcode = (rcode != 0);
-                       regfree(&reg);
-                               break;
-#endif /* HAVE_REGEX_H */
-               default:
-                       rcode = FALSE;
-                       break;
-               } /* switch over comparison operators */
-               break;          /* default from first switch over compare */
-       }
-
-       /*
-        *      No trailing &&, ||
-        */
-       switch (this->child_condition) {
-       default:
-               return rcode;
-
-       case POLICY_LEX_L_AND:
-               if (!rcode) return rcode; /* FALSE && x == FALSE */
-               break;
-
-       case POLICY_LEX_L_OR:
-               if (rcode) return rcode; /* TRUE && x == TRUE */
-               break;
-       }
-
-       /*
-        *      Tail recursion.
-        */
-       this = (const policy_condition_t *) this->child;
-       goto redo;
-
-       return 1;               /* should never reach here */
-}
-
-
-/*
- *     Evaluate an 'if' statement
- */
-static int evaluate_if(policy_state_t *state, const policy_item_t *item)
-{
-       int rcode;
-       const policy_if_t *this;
-
-       this = (const policy_if_t *) item;
-
-       /*
-        *      evaluate_condition calls itself recursively.
-        *      We should probably allocate a new state, instead.
-        */
-       rcode = evaluate_condition(state, this->condition);
-       debug_evaluate("IF condition returned %s\n",
-              rcode ? "true" : "false");
-       if (rcode) {
-               rcode = policy_stack_push(state, this->if_true);
-               if (!rcode) return rcode;
-       } else if (this->if_false) {
-               rcode = policy_stack_push(state, this->if_false);
-               if (!rcode) return rcode;
-       }
-
-       /*
-        *      'if' can fail, if the block it's processing fails.
-        */
-       return 1;;
-}
-
-
-/*
- *     Make a VALUE_PAIR from a policy_assignment_t*
- *
- *     The assignment operator has to be '='.
- */
-static VALUE_PAIR *assign2vp(REQUEST *request,
-                            const policy_assignment_t *assign)
-{
-       VALUE_PAIR *vp;
-       LRAD_TOKEN operator = T_OP_EQ;
-       const char *value = assign->rhs;
-       char buffer[2048];
-
-       if ((assign->rhs_type == POLICY_LEX_DOUBLE_QUOTED_STRING) &&
-           (strchr(assign->rhs, '%') != NULL)) {
-               radius_xlat(buffer, sizeof(buffer), assign->rhs,
-                           request, NULL);
-               value = buffer;
-       }
-
-       /*
-        *      This is crappy.. fix it.
-        */
-       switch (assign->assign) {
-       case POLICY_LEX_ASSIGN:
-               operator = T_OP_EQ;
-               break;
-
-       case POLICY_LEX_SET_EQUALS:
-               operator = T_OP_SET;
-               break;
-
-       case POLICY_LEX_PLUS_EQUALS:
-               operator = T_OP_ADD;
-               break;
-
-       default:
-               fprintf(stderr, "Expected '=' for operator, not '%s' at line %d\n",
-                       lrad_int2str(rlm_policy_tokens,
-                                    assign->assign, "?"),
-                       assign->item.lineno);
-               return NULL;
-       }
-
-       vp = pairmake(assign->lhs, value, operator);
-       if (!vp) {
-               fprintf(stderr, "SHIT: %s %s\n", value, librad_errstr);
-       }
-
-       return vp;
-}
-
-
-/*
- *     Evaluate a 'packet .= {attrs}' statement
- */
-static int evaluate_attr_list(policy_state_t *state, const policy_item_t *item)
-{
-       const policy_attributes_t *this;
-       VALUE_PAIR **vps = NULL;
-       VALUE_PAIR *vp, *head, **tail;
-       const policy_item_t *attr;
-
-       this = (const policy_attributes_t *) item;
-
-       switch (this->where) {
-       case POLICY_RESERVED_CONTROL:
-               vps = &(state->request->config_items);
-               break;
-
-       case POLICY_RESERVED_REQUEST:
-               vps = &(state->request->packet->vps);
-               break;
-
-       case POLICY_RESERVED_REPLY:
-               vps = &(state->request->reply->vps);
-               break;
-
-       case POLICY_RESERVED_PROXY_REQUEST:
-               if (!state->request->proxy) return 0; /* FIXME: print error */
-               vps = &(state->request->proxy->vps);
-               break;
-
-       case POLICY_RESERVED_PROXY_REPLY:
-               if (!state->request->proxy_reply) return 0; /* FIXME: print error */
-               vps = &(state->request->proxy_reply->vps);
-               break;
-
-       default:
-               return 0;
-       }
-
-       head = NULL;
-       tail = &head;
-
-       for (attr = this->attributes; attr != NULL; attr = attr->next) {
-               if (attr->type != POLICY_TYPE_ASSIGNMENT) {
-                       fprintf(stderr, "bad assignment in attribute list at line %d\n", attr->lineno);
-                       pairfree(&head);
-                       return 0;
-               }
-
-               vp = assign2vp(state->request, (const policy_assignment_t *) attr);
-               if (!vp) {
-                       fprintf(stderr, "Failed to allocate VP\n");
-                       pairfree(&head);
-                       return 0;
-               }
-               *tail = vp;
-               tail = &(vp->next);
-       }
-
-       switch (this->how) {
-       case POLICY_LEX_SET_EQUALS: /* dangerous: removes all previous things! */
-               pairfree(vps);
-               *vps = head;
-               break;
-
-       case POLICY_LEX_ASSIGN: /* 'union' */
-               pairmove(vps, &head);
-               pairfree(&head);
-               break;
-
-       case POLICY_LEX_CONCAT_EQUALS:
-               pairadd(vps, head);
-               break;
-
-       default:
-               fprintf(stderr, "HUH?\n");
-               pairfree(&head);
-               return 0;
-       }
-
-       state->rcode = RLM_MODULE_UPDATED; /* we did stuff */
-
-       return 1;
-}
-
-
-/*
- *     Evaluate a reference call to a module.
- */
-static int evaluate_call(policy_state_t *state, const policy_item_t *item)
-{
-       int rcode;
-       const policy_call_t *this;
-       const policy_named_t *policy;
-
-       this = (const policy_call_t *) item;
-
-       policy = rlm_policy_find(state->inst->policies, this->name);
-       if (!policy) return 0;  /* not found... */
-
-       DEBUG2("rlm_policy: Evaluating policy %s", this->name);
-
-       rad_assert(policy->policy->type != POLICY_TYPE_BAD);
-       rad_assert(policy->policy->type < POLICY_TYPE_NUM_TYPES);
-
-       /*
-        *      Push the name of the function onto the stack,
-        *      so that we can catch recursive calls.
-        *
-        *      The "pop" function will skip over it when it sees it.
-        */
-       rcode = policy_stack_push(state, (const policy_item_t *) policy);
-       if (!rcode) {
-               return rcode;
-       }
-
-       /*
-        *      Push it onto the stack.  Other code will take care of
-        *      calling it.
-        */
-       rcode = policy_stack_push(state, policy->policy);
-       if (!rcode) {
-               return rcode;
-       }
-
-       return 1;
-}
-
-
-/*
- *     Evaluate a return statement
- */
-static int evaluate_return(policy_state_t *state, const policy_item_t *item)
-{
-       const policy_return_t *this;
-
-       this = (const policy_return_t *) item;
-       state->rcode = this->rcode;
-
-       return 1;               /* we succeeded */
-}
-
-
-/*
- *     Evaluate a module statement
- */
-static int evaluate_module(policy_state_t *state, const policy_item_t *item)
-{
-       const policy_module_t *this;
-
-       this = (const policy_module_t *) item;
-
-       /*
-        *      Just to be paranoid.  Maybe we want to loosen this
-        *      restriction in the future?
-        */
-       if (this->component != state->component) {
-               DEBUG2("rlm_policy: Cannot mix & match components");
-               return 0;
-       }
-
-       DEBUG2("rlm_policy: begin nested call");
-       state->rcode = modcall(this->component, this->mc, state->request);
-       DEBUG2("rlm_policy: end nested call");
-
-       return 1;               /* we succeeded */
-}
-
-
-/*
- *     State machine stuff.
- */
-typedef int (*policy_evaluate_type_t)(policy_state_t *, const policy_item_t *);
-
-
-/*
- *     MUST be kept in sync with policy_type_t
- */
-static policy_evaluate_type_t evaluate_functions[POLICY_TYPE_NUM_TYPES] = {
-       NULL,                   /* POLICY_TYPE_BAD */
-       evaluate_if,
-       evaluate_condition,
-       evaluate_assignment,
-       evaluate_attr_list,
-       evaluate_print,
-       NULL,                   /* define a named policy.. */
-       evaluate_call,
-       evaluate_return,
-       evaluate_module
-};
-
-
-/*
- *     Evaluate a policy, keyed by name.
- */
-static int policy_evaluate_name(policy_state_t *state, const char *name)
-{
-       int rcode;
-       const policy_item_t *this;
-       policy_named_t mypolicy, *policy;
-
-       mypolicy.name = name;
-       policy = rbtree_finddata(state->inst->policies, &mypolicy);
-       if (!policy) return RLM_MODULE_FAIL;
-
-       DEBUG2("rlm_policy: Evaluating policy %s", name);
-
-       rad_assert(policy->item.type != POLICY_TYPE_BAD);
-       rad_assert(policy->item.type < POLICY_TYPE_NUM_TYPES);
-
-       rcode = policy_stack_push(state, policy->policy);
-       if (!rcode) {
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      FIXME: Look for magic keywords like "return",
-        *      where the packet gets accepted/rejected/whatever
-        */
-       while (policy_stack_pop(state, &this)) {
-               rad_assert(this != NULL);
-               rad_assert(this->type != POLICY_TYPE_BAD);
-               rad_assert(this->type < POLICY_TYPE_NUM_TYPES);
-
-               debug_evaluate("Evaluating at line %d\n",
-                              this->lineno);
-               rcode = (*evaluate_functions[this->type])(state,
-                                                         this);
-               if (!rcode) {
-                       return RLM_MODULE_FAIL;
-               }
-       } /* loop until the stack is empty */
-
-       return state->rcode;
-}
-
-
-/*
- *     Evaluate, which is pretty close to print, but we look at what
- *     we're printing.
- */
-int rlm_policy_evaluate(rlm_policy_t *inst, REQUEST *request, const char *name)
-{
-       int rcode;
-       policy_state_t *state;
-
-       state = rad_malloc(sizeof(*state));
-       memset(state, 0, sizeof(*state));
-       state->request = request;
-       state->inst = inst;
-       state->rcode = RLM_MODULE_OK;
-       state->component = lrad_str2int(policy_component_names, name,
-                                       RLM_COMPONENT_COUNT);
-
-       rcode = policy_evaluate_name(state, name);
-
-       free(state);
-
-       return rcode;           /* evaluated OK. */
-}
diff --git a/src/modules/rlm_policy/parse.c b/src/modules/rlm_policy/parse.c
deleted file mode 100644 (file)
index 080af37..0000000
+++ /dev/null
@@ -1,1618 +0,0 @@
-/*
- * parse.c             Parse a policy language
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004  Alan DeKok <aland@ox.org>
- * Copyright 2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include "rlm_policy.h"
-
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#endif
-
-#include <freeradius-devel/modules.h>
-
-const LRAD_NAME_NUMBER policy_return_codes[] = {
-       { "reject", RLM_MODULE_REJECT },
-       { "fail", RLM_MODULE_FAIL },
-       { "ok", RLM_MODULE_OK },
-       { "handled", RLM_MODULE_HANDLED },
-       { "invalid", RLM_MODULE_INVALID },
-       { "userlock", RLM_MODULE_USERLOCK },
-       { "notfound", RLM_MODULE_NOTFOUND },
-       { "noop", RLM_MODULE_NOOP },
-       { "updated", RLM_MODULE_UPDATED },
-       { NULL, RLM_MODULE_NUMCODES }
-};
-
-/*
- *     Explanations of what the lexical tokens are.
- */
-static const LRAD_NAME_NUMBER policy_explanations[] = {
-       { "invalid input", POLICY_LEX_BAD },
-       { "end of file", POLICY_LEX_EOF },
-       { "end of line", POLICY_LEX_EOL },
-       { "whitespace", POLICY_LEX_WHITESPACE },
-       { "hash mark", POLICY_LEX_HASH },
-       { "left bracket", POLICY_LEX_L_BRACKET },
-       { "right bracket", POLICY_LEX_R_BRACKET },
-       { "{", POLICY_LEX_LC_BRACKET },
-       { "}", POLICY_LEX_RC_BRACKET },
-       { "comma", POLICY_LEX_COMMA },
-       { "logical AND", POLICY_LEX_L_AND },
-       { "logical OR", POLICY_LEX_L_OR },
-       { "AND", POLICY_LEX_AND },
-       { "OR", POLICY_LEX_OR },
-       { "logical NOT", POLICY_LEX_L_NOT },
-       { "assignment", POLICY_LEX_ASSIGN },
-       { "comparison", POLICY_LEX_CMP_EQUALS },
-       { "comparison", POLICY_LEX_CMP_NOT_EQUALS },
-       { "comparison", POLICY_LEX_LT },
-       { "comparison", POLICY_LEX_GT },
-       { "comparison", POLICY_LEX_LE },
-       { "comparison", POLICY_LEX_GT },
-       { "comparison", POLICY_LEX_RX_EQUALS },
-       { "comparison", POLICY_LEX_RX_NOT_EQUALS },
-       { "double quoted string", POLICY_LEX_DOUBLE_QUOTED_STRING },
-       { "single quoted string", POLICY_LEX_SINGLE_QUOTED_STRING },
-       { "back quoted string", POLICY_LEX_BACK_QUOTED_STRING },
-       { "bare word", POLICY_LEX_BARE_WORD },
-
-       { NULL, -1 }
-};
-
-
-const LRAD_NAME_NUMBER rlm_policy_tokens[] = {
-       { "EOF", POLICY_LEX_EOF },
-       { "#", POLICY_LEX_HASH },
-       { "(", POLICY_LEX_L_BRACKET },
-       { ")", POLICY_LEX_R_BRACKET },
-       { "{", POLICY_LEX_LC_BRACKET },
-       { "}", POLICY_LEX_RC_BRACKET },
-       { ",", POLICY_LEX_COMMA },
-       { "&&", POLICY_LEX_L_AND },
-       { "||", POLICY_LEX_L_OR },
-       { "&", POLICY_LEX_AND },
-       { "|", POLICY_LEX_OR },
-       { "!", POLICY_LEX_L_NOT },
-       { "=", POLICY_LEX_ASSIGN },
-       { "==", POLICY_LEX_CMP_EQUALS },
-       { "!=", POLICY_LEX_CMP_NOT_EQUALS },
-       { "=*", POLICY_LEX_CMP_TRUE },
-       { "!*", POLICY_LEX_CMP_FALSE },
-       { "<", POLICY_LEX_LT },
-       { ">", POLICY_LEX_GT },
-       { "<=", POLICY_LEX_LE },
-       { ">=", POLICY_LEX_GT },
-       { "=~", POLICY_LEX_RX_EQUALS },
-       { "!~", POLICY_LEX_RX_NOT_EQUALS },
-       { ".=", POLICY_LEX_CONCAT_EQUALS },
-       { ":=", POLICY_LEX_SET_EQUALS },
-       { "double quoted string", POLICY_LEX_DOUBLE_QUOTED_STRING },
-       { "single quoted string", POLICY_LEX_SINGLE_QUOTED_STRING },
-       { "back quoted string", POLICY_LEX_BACK_QUOTED_STRING },
-       { "bare word", POLICY_LEX_BARE_WORD },
-
-       { NULL, -1 }
-};
-
-
-/*
- *     Hand-coded lexical analysis of a string.
- *     Handed input string, updates token, possible a decoded
- *     string in buffer, and returns the pointer to the next token.
- *
- *     Lexical tokens cannot cross a string boundary.
- */
-static const char *policy_lex_string(const char *input,
-                                    policy_lex_t *token,
-                                    char *buffer, size_t buflen)
-{
-       rad_assert(input != NULL);
-
-       if (buffer) *buffer = '\0';
-
-       switch (*input) {
-       case '\0':
-               *token = POLICY_LEX_EOL;
-               return NULL;    /* nothing more to do */
-
-       case ' ':
-       case '\t':
-       case '\r':
-       case '\n':
-               /*
-                *      Skip over all of the whitespace in one swell foop.
-                */
-               *token = POLICY_LEX_WHITESPACE;
-               while ((*input == ' ') || (*input == '\t') ||
-                      (*input == '\r') || (*input == '\n')) input++;
-               return input;   /* point to next non-whitespace character */
-
-       case '#':               /* ignore everything to the end of the line */
-               *token = POLICY_LEX_EOL;
-               return NULL;
-
-       case '(':
-               *token = POLICY_LEX_L_BRACKET;
-               return input + 1;
-
-       case ')':
-               *token = POLICY_LEX_R_BRACKET;
-               return input + 1;
-
-       case '{':
-               *token = POLICY_LEX_LC_BRACKET;
-               return input + 1;
-
-       case '}':
-               *token = POLICY_LEX_RC_BRACKET;
-               return input + 1;
-
-       case ',':
-               *token = POLICY_LEX_COMMA;
-               return input + 1;
-
-       case '+':
-               switch (input[1]) {
-               case '=':
-                       *token = POLICY_LEX_PLUS_EQUALS;
-                       input++;
-                       break;
-
-               default:
-                       *token = POLICY_LEX_PLUS;
-                       break;
-               }
-               return input + 1;
-
-       case '-':
-               switch (input[1]) {
-               case '=':
-                       *token = POLICY_LEX_MINUS_EQUALS;
-                       input++;
-                       break;
-
-               default:
-                       *token = POLICY_LEX_MINUS;
-                       break;
-               }
-               return input + 1;
-
-       case '.':
-               if (input[1] == '=') {
-                       *token = POLICY_LEX_CONCAT_EQUALS;
-                       return input + 2;
-               }
-               *token = POLICY_LEX_BAD;
-               return input + 1;
-
-       case ':':
-               if (input[1] == '=') {
-                       *token = POLICY_LEX_SET_EQUALS;
-                       return input + 2;
-               }
-               *token = POLICY_LEX_BAD;
-               return input + 1;
-
-       case '&':
-               switch (input[1]) {
-               case '&':
-                       *token = POLICY_LEX_L_AND;
-                       input++;
-                       break;
-
-               case '=':
-                       *token = POLICY_LEX_AND_EQUALS;
-                       input++;
-                       break;
-
-               default:
-                       *token = POLICY_LEX_AND;
-               }
-               return input + 1;
-
-       case '|':
-               switch (input[1]) {
-               case '|':
-                       *token = POLICY_LEX_L_OR;
-                       input++;
-                       break;
-
-               case '=':
-                       *token = POLICY_LEX_OR_EQUALS;
-                       input++;
-                       break;
-
-               default:
-                       *token = POLICY_LEX_OR;
-               }
-               return input + 1;
-
-       case '!':
-               switch (input[1]) {
-               case '=':
-                       input++;
-                       *token = POLICY_LEX_CMP_NOT_EQUALS;
-                       break;
-
-               case '~':
-                       input++;
-                       *token = POLICY_LEX_RX_NOT_EQUALS;
-                       break;
-
-               case '*':
-                       input++;
-                       *token = POLICY_LEX_CMP_FALSE;
-                       break;
-
-               default:
-                       *token = POLICY_LEX_L_NOT;
-               }
-               return input + 1;
-
-       case '=':
-               switch (input[1]) {
-               case '=':
-                       input++;
-                       *token = POLICY_LEX_CMP_EQUALS;
-                       break;
-
-               case '~':
-                       input++;
-                       *token = POLICY_LEX_RX_EQUALS;
-                       break;
-
-               case '*':
-                       input++;
-                       *token = POLICY_LEX_CMP_TRUE;
-                       break;
-
-               default:
-                       *token = POLICY_LEX_ASSIGN;
-               }
-               return input + 1;
-
-       case '<':
-               if (input[1] == '=') {
-                       input++;
-                       *token = POLICY_LEX_LE;
-               } else {
-                       *token = POLICY_LEX_LT;
-               }
-               return input + 1;
-
-       case '>':
-               if (input[1] == '=') {
-                       input++;
-                       *token = POLICY_LEX_GE;
-               } else {
-                       *token = POLICY_LEX_GT;
-               }
-               return input + 1;
-
-       case '"':
-               if (buflen < 2) {
-                       *token = POLICY_LEX_BAD;
-                       return input + 1;
-               }
-
-               input++;
-               while (*input != '"') {
-                       /*
-                        *      Strings can't pass EOL.
-                        */
-                       if (!*input) {
-                               return POLICY_LEX_BAD;
-                       }
-
-                       /*
-                        *      FIXME: Embedded quotes?
-                        */
-                       *(buffer++) = *(input++);
-                       buflen--;
-
-                       /*
-                        *      FIXME: Print more warnings?
-                        */
-                       if (buflen == 1) {
-                               break;
-                       }
-               }
-               *buffer = '\0';
-
-               *token = POLICY_LEX_DOUBLE_QUOTED_STRING;
-               return input + 1; /* skip trailing '"' */
-
-       default:                /* bare word */
-               break;
-       }
-
-       /*
-        *      It's a bare word, with nowhere to put it.  Die.
-        */
-       if (!buffer) {
-               *token = POLICY_LEX_BAD;
-               return input + 1;
-       }
-
-       /*
-        *      Getting one character is stupid.
-        */
-       if (buflen < 2) {
-               *token = POLICY_LEX_BAD;
-               return input + 1;
-       }
-
-       /*
-        *      Bare words are [-a-zA-Z0-9.]+
-        */
-       while (*input) {
-               if (!(((*input >= '0') && (*input <= '9')) ||
-                     ((*input >= 'a') && (*input <= 'z')) ||
-                     ((*input >= 'A') && (*input <= 'Z')) ||
-                     (*input == '-') || (*input == '.') ||
-                     (*input == ':') || (*input == '_'))) {
-                       break;
-               }
-               *(buffer++) = *(input++);
-               buflen--;
-
-               /*
-                *      FIXME: Print more warnings?
-                */
-               if (buflen == 1) {
-                       break;
-               }
-       }
-       *buffer = '\0';
-
-       *token = POLICY_LEX_BARE_WORD;
-       return input;
-}
-
-
-/*
- *     We want to lexically analyze a file, so we need a wrapper
- *     around the lexical analysis of strings.
- */
-typedef struct policy_lex_file_t {
-       FILE            *fp;
-       const char      *parse;
-       const char      *filename;
-       int             lineno;
-       int             debug;
-       rbtree_t        *policies;
-       policy_lex_t    token;
-       char            buffer[1024];
-} policy_lex_file_t;
-
-
-#define POLICY_LEX_FLAG_RETURN_EOL  (1 << 0)
-#define POLICY_LEX_FLAG_PEEK        (1 << 1)
-#define POLICY_LEX_FLAG_PRINT_TOKEN (1 << 2)
-
-#define debug_tokens if (lexer->debug & POLICY_DEBUG_PRINT_TOKENS) printf
-
-
-/*
- *     Function to return a token saying what it read, and possibly
- *     a buffer of the quoted string or bare word.
- */
-static policy_lex_t policy_lex_file(policy_lex_file_t *lexer,
-                                   int flags,
-                                   char *mystring, size_t mystringlen)
-{
-       policy_lex_t token = POLICY_LEX_BARE_WORD; /* to prime it */
-
-       if (lexer->debug & POLICY_DEBUG_PRINT_TOKENS) {
-               flags |= POLICY_LEX_FLAG_PRINT_TOKEN;
-       }
-
-       if (!lexer->fp) {
-               return POLICY_LEX_EOF;
-       }
-
-       /*
-        *      Starting off, the buffer needs to be primed.
-        */
-       if (!lexer->parse) {
-               lexer->parse = fgets(lexer->buffer,
-                                    sizeof(lexer->buffer),
-                                    lexer->fp);
-
-               if (!lexer->parse) {
-                       return POLICY_LEX_EOF;
-               }
-
-               lexer->lineno = 1;
-       } /* buffer is primed, read stuff */
-
-       if (lexer->token != POLICY_LEX_BAD) {
-               token = lexer->token;
-               lexer->token = POLICY_LEX_BAD;
-               return token;
-       }
-
-       /*
-        *      Ignore whitespace, and keep filling the buffer
-        */
-       while (lexer->parse) {
-               const char *next;
-
-               next = policy_lex_string(lexer->parse, &token,
-                                        mystring, mystringlen);
-               switch (token) {
-               case POLICY_LEX_WHITESPACE: /* skip whitespace */
-                       lexer->parse = next;
-                       continue;
-
-               case POLICY_LEX_EOL: /* read another line */
-                       lexer->parse = fgets(lexer->buffer,
-                                            sizeof(lexer->buffer),
-                                            lexer->fp);
-                       lexer->lineno++;
-                       if (flags & POLICY_LEX_FLAG_RETURN_EOL) {
-                               return POLICY_LEX_EOL;
-                       }
-                       break;  /* read another token */
-
-               default:        /* return the token */
-                       if (!(flags & POLICY_LEX_FLAG_PEEK)) {
-                               lexer->parse = next;
-                       }
-                       if (flags & POLICY_LEX_FLAG_PRINT_TOKEN) {
-                               debug_tokens("[%s token %s] ",
-                                            (flags & POLICY_LEX_FLAG_PEEK) ? "peek " : "",
-                                            lrad_int2str(rlm_policy_tokens,
-                                                         token, "?"));
-                       }
-                       return token;
-                       break;
-               }
-       } /* loop until EOF */
-
-       /*
-        *      Close it for the user.
-        */
-       fclose(lexer->fp);
-       lexer->fp = NULL;
-
-       return POLICY_LEX_EOF;
-}
-
-
-/*
- *     Push a token back onto the input.
- *
- *     FIXME: Push words, too?
- */
-static int policy_lex_push_token(policy_lex_file_t *lexer,
-                                policy_lex_t token)
-{
-       if (lexer->token != POLICY_LEX_BAD) {
-               rad_assert(0 == 1);
-               return 0;
-       }
-
-       lexer->token = token;
-       return 1;
-}
-
-
-/*
- *     Forward declarations.
- */
-static int parse_block(policy_lex_file_t *lexer, policy_item_t **tail);
-
-
-/*
- *     Map reserved words to tokens, and vice versa.
- */
-const LRAD_NAME_NUMBER policy_reserved_words[] = {
-       { "if", POLICY_RESERVED_IF },
-       { "else", POLICY_RESERVED_ELSE },
-       { "debug", POLICY_RESERVED_DEBUG },
-       { "print", POLICY_RESERVED_PRINT },
-       { "policy", POLICY_RESERVED_POLICY },
-       { "control", POLICY_RESERVED_CONTROL },
-       { "request", POLICY_RESERVED_REQUEST },
-       { "reply", POLICY_RESERVED_REPLY },
-       { "proxy-request", POLICY_RESERVED_PROXY_REQUEST },
-       { "proxy-reply", POLICY_RESERVED_PROXY_REPLY },
-       { "include", POLICY_RESERVED_INCLUDE },
-       { "return", POLICY_RESERVED_RETURN },
-       { "module", POLICY_RESERVED_MODULE },
-       { NULL, POLICY_RESERVED_UNKNOWN }
-};
-
-
-/*
- *     Simplifies some later coding
- */
-static int policy_lex_str2int(policy_lex_file_t *lexer,
-                             const LRAD_NAME_NUMBER *table, int default_value)
-{
-       policy_lex_t token;
-       char buffer[256];
-
-       token = policy_lex_file(lexer, 0, buffer, sizeof(buffer));
-       if (token != POLICY_LEX_BARE_WORD) {
-               fprintf(stderr, "%s[%d]: Unexpected token\n",
-                       lexer->filename, lexer->lineno);
-               return default_value;
-       }
-
-       return lrad_str2int(table, buffer, default_value);
-}
-
-
-/*
- *     print foo
- *     print "foo"
- */
-static int parse_print(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       policy_lex_t token;
-       char mystring[1024];
-       policy_print_t *this;
-
-       debug_tokens("[PRINT] ");
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_PRINT;
-       this->item.lineno = lexer->lineno;
-
-       token = policy_lex_file(lexer, 0, mystring, sizeof(mystring));
-       if ((token != POLICY_LEX_BARE_WORD) &&
-           (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) {
-               fprintf(stderr, "%s[%d]: Bad print command\n",
-                       lexer->filename, lexer->lineno);
-               return 0;
-       }
-
-       this->rhs_type = token;
-       this->rhs = strdup(mystring);
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-/*
- * (foo == bar), with nested conditionals.
- */
-static int parse_condition(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       int rcode;
-       policy_lex_t token, compare;
-       char lhs[256], rhs[256];
-       policy_condition_t *this;
-
-       token = policy_lex_file(lexer, 0, lhs, sizeof(lhs));
-       if (token != POLICY_LEX_L_BRACKET) {
-               fprintf(stderr, "%s[%d]: Expected '(', got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, lhs));
-               return 0;
-       }
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_CONDITIONAL;
-       this->item.lineno = lexer->lineno;
-
-       token = policy_lex_file(lexer, 0, lhs, sizeof(lhs));
-       switch (token) {
-       case POLICY_LEX_L_BRACKET:
-               if (!policy_lex_push_token(lexer, token)) {
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return 0;
-               }
-
-               this->compare = POLICY_LEX_L_BRACKET;
-               this->child_condition = POLICY_LEX_L_BRACKET;
-               rcode = parse_condition(lexer, &(this->child));
-               if (!rcode) {
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return rcode;
-               }
-               break;
-
-       case POLICY_LEX_L_NOT:
-               this->compare = POLICY_LEX_L_NOT;
-               debug_tokens("[NOT] ");
-
-               /*
-                *      FIXME: allow !foo, !foo=bar, etc.
-                *
-                *      Maybe we should learn how to use lex && yacc?
-                */
-
-               rcode = parse_condition(lexer, &(this->child));
-               if (!rcode) {
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return rcode;
-               }
-               break;
-
-       case POLICY_LEX_BARE_WORD:
-               this->lhs_type = token;
-               token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
-               if (token == POLICY_LEX_L_BRACKET) {
-                       debug_tokens("[IF-CALL %s] ", lhs);
-
-                       /*
-                        *      Function call.
-                        */
-                       if (rlm_policy_find(lexer->policies, lhs) == NULL) {
-                               fprintf(stderr, "%s[%d]: Undefined function \"%s\"\n",
-                                       lexer->filename, lexer->lineno,
-                                       lhs);
-                               rlm_policy_free_item((policy_item_t *) this);
-                               return 0;
-
-                       }
-
-                       /*
-                        *      this->lhs set up below, after "check"
-                        */
-                       this->lhs_type = POLICY_LEX_FUNCTION;
-
-                       /*
-                        *      Copied from parse_call
-                        */
-                       token = policy_lex_file(lexer, 0, NULL, 0);
-                       if (token != POLICY_LEX_L_BRACKET) {
-                               fprintf(stderr, "%s[%d]: Expected left bracket, got \"%s\"\n",
-                                       lexer->filename, lexer->lineno,
-                                       lrad_int2str(rlm_policy_tokens, token, "?"));
-                               return 0;
-                       }
-
-                       token = policy_lex_file(lexer, 0, NULL, 0);
-                       if (token != POLICY_LEX_R_BRACKET) {
-                               fprintf(stderr, "%s[%d]: Expected right bracket, got \"%s\"\n",
-                                       lexer->filename, lexer->lineno,
-                                       lrad_int2str(rlm_policy_tokens, token, "?"));
-                               return 0;
-                       }
-               } /* else it's a comparison? */
-               goto check;
-
-       case POLICY_LEX_DOUBLE_QUOTED_STRING:
-               this->lhs_type = token;
-
-               /*
-                *      Got word.  May just be test for existence.
-                */
-       check:
-               token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
-               if (token == POLICY_LEX_R_BRACKET) {
-                       debug_tokens("[TEST %s] ", lhs);
-                       this->lhs = strdup(lhs);
-                       this->compare = POLICY_LEX_CMP_TRUE;
-                       break;
-               }
-
-               compare = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
-               switch (compare) {
-               case POLICY_LEX_CMP_EQUALS:
-               case POLICY_LEX_CMP_NOT_EQUALS:
-               case POLICY_LEX_RX_EQUALS:
-               case POLICY_LEX_RX_NOT_EQUALS:
-               case POLICY_LEX_CMP_TRUE:
-               case POLICY_LEX_CMP_FALSE:
-               case POLICY_LEX_LT:
-               case POLICY_LEX_GT:
-               case POLICY_LEX_LE:
-               case POLICY_LEX_GE:
-                       break;
-
-               default:
-                       fprintf(stderr, "%s[%d]: Invalid operator \"%s\"\n",
-                               lexer->filename, lexer->lineno,
-                               lrad_int2str(rlm_policy_tokens, compare, rhs));
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return 0;
-               }
-
-               token = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
-               if ((token != POLICY_LEX_BARE_WORD) &&
-                   (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) {
-                       fprintf(stderr, "%s[%d]: Unexpected rhs token\n",
-                               lexer->filename, lexer->lineno);
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return 0;
-               }
-               debug_tokens("[COMPARE (%s %s %s)] ",
-                      lhs, lrad_int2str(rlm_policy_tokens, compare, "?"), rhs);
-               this->lhs = strdup(lhs);
-               this->compare = compare;
-               this->rhs_type = token;
-               this->rhs = strdup(rhs);
-               break;
-
-       default:
-               fprintf(stderr, "%s[%d]: Unexpected lhs token\n",
-                       lexer->filename, lexer->lineno);
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-
-       token = policy_lex_file(lexer, 0, NULL, 0);
-       if (token != POLICY_LEX_R_BRACKET) {
-               fprintf(stderr, "%s[%d]: Expected ')', got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-
-       /*
-        *      After the end of condition, we MAY have && or ||
-        */
-       token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0);
-       if ((token == POLICY_LEX_L_AND) || (token == POLICY_LEX_L_OR)) {
-               token = policy_lex_file(lexer, 0, NULL, 0); /* skip over it */
-               debug_tokens("[%s] ",
-                      lrad_int2str(rlm_policy_tokens, token, "?"));
-               this->child_condition = token;
-               rcode = parse_condition(lexer, &(this->child));
-               if (!rcode) {
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return 0;
-               }
-       }
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-/*
- *     if (...) {...}
- *     if (...) {...} else {...}
- *     if (...) {...} else if ...
- */
-static int parse_if(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       int rcode;
-       policy_lex_t token;
-       char mystring[256];
-       policy_if_t *this;
-
-       debug_tokens("[IF] ");
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_IF;
-       this->item.lineno = lexer->lineno;
-
-       rcode = parse_condition(lexer, &(this->condition));
-       if (!rcode) {
-               rlm_policy_free_item((policy_item_t *) this);
-               return rcode;
-       }
-
-       rcode = parse_block(lexer, &(this->if_true));
-       if (!rcode) {
-               rlm_policy_free_item((policy_item_t *) this);
-               return rcode;
-       }
-
-       token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK,
-                               mystring, sizeof(mystring));
-       if ((token == POLICY_LEX_BARE_WORD) &&
-           (lrad_str2int(policy_reserved_words, mystring,
-                         POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_ELSE)) {
-               debug_tokens("[ELSE] ");
-               token = policy_lex_file(lexer, 0, mystring, sizeof(mystring));
-
-               token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK,
-                                       mystring, sizeof(mystring));
-               if ((token == POLICY_LEX_BARE_WORD) &&
-                   (lrad_str2int(policy_reserved_words, mystring,
-                                 POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_IF)) {
-                       token = policy_lex_file(lexer, 0,
-                                               mystring, sizeof(mystring));
-                       rcode = parse_if(lexer, &(this->if_false));
-               } else {
-                       rcode = parse_block(lexer, &(this->if_false));
-               }
-               if (!rcode) {
-                       rlm_policy_free_item((policy_item_t *) this);
-                       return rcode;
-               }
-       }
-
-       debug_tokens("\n");
-
-       /*
-        *      Empty "if" condition, don't even bother remembering
-        *      it.
-        */
-       if (!this->if_true && !this->if_false) {
-               debug_tokens("Discarding empty \"if\" statement at line %d\n",
-                            this->item.lineno);
-               rlm_policy_free_item((policy_item_t *) this);
-               return 1;
-       }
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-/*
- *     Parse a reference to a named policy "foo()"
- */
-static int parse_call(policy_lex_file_t *lexer, policy_item_t **tail,
-                     const char *name)
-{
-       policy_lex_t token;
-       policy_call_t *this;
-
-       debug_tokens("[CALL] ");
-
-       token = policy_lex_file(lexer, 0, NULL, 0);
-       if (token != POLICY_LEX_L_BRACKET) {
-               fprintf(stderr, "%s[%d]: Expected left bracket, got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               return 0;
-       }
-
-       token = policy_lex_file(lexer, 0, NULL, 0);
-       if (token != POLICY_LEX_R_BRACKET) {
-               fprintf(stderr, "%s[%d]: Expected right bracket, got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               return 0;
-       }
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_CALL;
-       this->item.lineno = lexer->lineno;
-
-       this->name = strdup(name);
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-/*
- *     Edit/update/replace an attribute list
- */
-static int parse_attribute_block(policy_lex_file_t *lexer,
-                                policy_item_t **tail,
-                                policy_reserved_word_t where)
-{
-       policy_lex_t token;
-       policy_attributes_t *this;
-       char buffer[32];
-
-       token = policy_lex_file(lexer, 0, buffer, sizeof(buffer));
-       switch (token) {
-       case POLICY_LEX_ASSIGN:
-       case POLICY_LEX_SET_EQUALS:
-       case POLICY_LEX_CONCAT_EQUALS:
-               break;
-
-       default:
-               fprintf(stderr, "%s[%d]: Unexpected token %s\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               return 0;       /* unknown */
-       }
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_ATTRIBUTE_LIST;
-       this->item.lineno = lexer->lineno;
-       this->where = where;
-       this->how = token;
-
-       if (!parse_block(lexer, &(this->attributes))) {
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-
-       *tail = (policy_item_t *) this;
-       return 1;
-}
-
-
-/*
- *     Parse a return statement.
- */
-static int parse_return(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       int rcode;
-       policy_lex_t token;
-       policy_return_t *this;
-
-       rcode = policy_lex_str2int(lexer, policy_return_codes,
-                                  RLM_MODULE_NUMCODES);
-       if (rcode == RLM_MODULE_NUMCODES) {
-               fprintf(stderr, "%s[%d]: Invalid return code\n",
-                       lexer->filename, lexer->lineno);
-               return 0;
-       }
-
-       /*
-        *      Look for more sutff
-        */
-       token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK,
-                               NULL, sizeof(0));
-       if (token != POLICY_LEX_RC_BRACKET) {
-               fprintf(stderr, "%s[%d]: return statement must be the last statement in a policy.\n",
-                       lexer->filename, lexer->lineno);
-               return 0;
-       }
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_RETURN;
-       this->item.lineno = lexer->lineno;
-       this->rcode = rcode;
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-const LRAD_NAME_NUMBER policy_component_names[] = {
-       { "authenticate", RLM_COMPONENT_AUTH },
-       { "authorize", RLM_COMPONENT_AUTZ },
-       { "preacct", RLM_COMPONENT_PREACCT },
-       { "accounting", RLM_COMPONENT_ACCT },
-       { "session", RLM_COMPONENT_SESS },
-       { "pre-proxy", RLM_COMPONENT_PRE_PROXY },
-       { "post-proxy", RLM_COMPONENT_POST_PROXY },
-       { "post-auth", RLM_COMPONENT_POST_AUTH },
-       { NULL, RLM_COMPONENT_COUNT }
-};
-
-/*
- *     Parse a module statement.
- */
-static int parse_module(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       int component;
-       policy_lex_t token;
-       policy_module_t *this;
-       char *p;
-       const char *section_name;
-       char filename[1024];
-       char buffer[2048];
-       CONF_SECTION *cs, *subcs;
-       modcallable *mc;
-
-       /*
-        *      And the filename
-        */
-       token = policy_lex_file(lexer, 0, filename, sizeof(filename));
-       if (token != POLICY_LEX_DOUBLE_QUOTED_STRING) {
-               fprintf(stderr, "%s[%d]: Expected filename, got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               return 0;
-       }
-
-       /*
-        *      See if we're including all of the files in a subdirectory.
-        */
-       strlcpy(buffer, lexer->filename, sizeof(buffer));
-       p = strrchr(buffer, '/');
-       if (p) {
-               strlcpy(p + 1, filename, sizeof(buffer) - 1 - (p - buffer));
-       } else {
-               snprintf(buffer, sizeof(buffer), "%s/%s",
-                        radius_dir, filename);
-       }
-
-       /*
-        *      Include section calling a module.
-        */
-       debug_tokens("including module section from file %s\n", buffer);
-       cs = cf_file_read(buffer);
-       if (!cs) {
-               return 0;       /* it prints out error messages */
-       }
-
-       /*
-        *      The outer section is called "main", and can be ignored.
-        *      It should be a section, so there should be a subsection.
-        */
-       subcs = cf_subsection_find_next(cs, NULL, NULL);
-       if (!subcs) {
-               fprintf(stderr, "%s[%d]: Expected section containing modules\n",
-                       lexer->filename, lexer->lineno);
-               cf_section_free(&cs);
-               return 0;
-       }
-
-       section_name = cf_section_name1(subcs);
-       rad_assert(section_name != NULL);
-       component = lrad_str2int(policy_component_names, section_name,
-                                RLM_COMPONENT_COUNT);
-       if (component == RLM_COMPONENT_COUNT) {
-               fprintf(stderr, "%s[%d]: Invalid section name \"%s\"\n",
-                       lexer->filename, lexer->lineno, section_name);
-               cf_section_free(&cs);
-               return 0;
-       }
-
-       /*
-        *      Compile the module entry.
-        */
-       mc = compile_modgroup(component, subcs, buffer);
-       if (!mc) {
-               cf_section_free(&cs);
-               return 0;       /* more often results in calling exit... */
-       }
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_MODULE;
-       this->item.lineno = lexer->lineno;
-       this->component = component;
-       this->cs = cs;
-       this->mc = mc;
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-/*
- *     Parse one statement.  'foo = bar', or 'if (...) {...}', or '{...}',
- *     and so on.
- */
-static int parse_statement(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       int rcode;
-       policy_reserved_word_t reserved;
-       policy_lex_t token, assign;
-       char lhs[256], rhs[256];
-       policy_assignment_t *this;
-
-       /*
-        *      See what kind of token we have.
-        */
-       token = policy_lex_file(lexer, 0, lhs, sizeof(lhs));
-       switch (token) {
-       case POLICY_LEX_LC_BRACKET:
-               rcode = parse_block(lexer, tail);
-               if (!rcode) {
-                       return 0;
-               }
-               break;
-
-       case POLICY_LEX_BARE_WORD:
-               reserved = lrad_str2int(policy_reserved_words,
-                                       lhs,
-                                       POLICY_RESERVED_UNKNOWN);
-               switch (reserved) {
-               case POLICY_RESERVED_IF:
-                       if (parse_if(lexer, tail)) {
-                               return 1;
-                       }
-                       return 0;
-                       break;
-
-               case POLICY_RESERVED_CONTROL:
-               case POLICY_RESERVED_REQUEST:
-               case POLICY_RESERVED_REPLY:
-               case POLICY_RESERVED_PROXY_REQUEST:
-               case POLICY_RESERVED_PROXY_REPLY:
-                       if (parse_attribute_block(lexer, tail,
-                                                 reserved))
-                               return 1;
-                       return 0;
-                       break;
-
-               case POLICY_RESERVED_PRINT:
-                       if (parse_print(lexer, tail)) {
-                               return 1;
-                       }
-                       return 0;
-                       break;
-
-               case POLICY_RESERVED_RETURN:
-                       if (parse_return(lexer, tail)) {
-                               return 1;
-                       }
-                       return 0;
-                       break;
-
-               case POLICY_RESERVED_MODULE:
-                       if (parse_module(lexer, tail)) {
-                               return 1;
-                       }
-                       return 0;
-                       break;
-
-               case POLICY_RESERVED_UNKNOWN: /* wasn't a reserved word */
-                       /*
-                        *      Is a named policy, parse the reference to it.
-                        */
-                       if (rlm_policy_find(lexer->policies, lhs) != NULL) {
-                               if (!parse_call(lexer, tail, lhs)) {
-                                       return 0;
-                               }
-                               return 1;
-                       }
-
-                       {
-                               const DICT_ATTR *dattr;
-
-                               /*
-                                *      Bare words MUST be dictionary attributes
-                                */
-
-                               dattr = dict_attrbyname(lhs);
-                               if (!dattr) {
-                                       fprintf(stderr, "%s[%d]: Expected attribute name, got \"%s\"\n",
-                                               lexer->filename, lexer->lineno, lhs);
-                                       return 0;
-                               }
-                               debug_tokens("%s[%d]: Got attribute %s\n",
-                                            lexer->filename, lexer->lineno,
-                                            lhs);
-                       }
-                       break;
-
-               default:
-                       fprintf(stderr, "%s[%d]: Unexpected reserved word \"%s\"\n",
-                               lexer->filename, lexer->lineno, lhs);
-                       return 0;
-               } /* switch over reserved words */
-               break;
-
-               /*
-                *      Return from nested blocks.
-                */
-       case POLICY_LEX_RC_BRACKET:
-               policy_lex_push_token(lexer, token);
-               return 2;       /* magic */
-
-       case POLICY_LEX_EOF:    /* nothing more to do */
-               return 3;
-
-       default:
-               fprintf(stderr, "%s[%d]: Unexpected %s\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(policy_explanations,
-                                    token, "string"));
-               break;
-       }
-
-       /*
-        *      Parse a bare statement.
-        */
-       assign = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
-       switch (assign) {
-       case POLICY_LEX_ASSIGN:
-       case POLICY_LEX_SET_EQUALS:
-       case POLICY_LEX_AND_EQUALS:
-       case POLICY_LEX_OR_EQUALS:
-       case POLICY_LEX_PLUS_EQUALS:
-               break;
-
-       default:
-               fprintf(stderr, "%s[%d]: Unexpected assign %s\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(policy_explanations,
-                                    assign, "string"));
-               return 0;
-       }
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_ASSIGNMENT;
-       this->item.lineno = lexer->lineno;
-
-       token = policy_lex_file(lexer, 0, rhs, sizeof(rhs));
-       if ((token != POLICY_LEX_BARE_WORD) &&
-           (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) {
-               fprintf(stderr, "%s[%d]: Unexpected rhs %s\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(policy_explanations,
-                                    token, "string"));
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-       this->rhs_type = token;
-       this->rhs = strdup(rhs);
-
-       token = policy_lex_file(lexer, POLICY_LEX_FLAG_RETURN_EOL,
-                               rhs, sizeof(rhs));
-       if (token != POLICY_LEX_EOL) {
-               fprintf(stderr, "%s[%d]: Expected EOL\n",
-                       lexer->filename, lexer->lineno);
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-       debug_tokens("[ASSIGN %s %s %s]\n",
-              lhs, lrad_int2str(rlm_policy_tokens, assign, "?"), rhs);
-
-       /*
-        *      Fill in the assignment struct
-        */
-       this->lhs = strdup(lhs);
-       this->assign = assign;
-
-       *tail = (policy_item_t *) this;
-
-       return 1;
-}
-
-
-/*
- *     Parse block of statements.  The block has already been checked
- *     to begin with a '{'.
- */
-static int parse_block(policy_lex_file_t *lexer, policy_item_t **tail)
-{
-       int rcode;
-       policy_lex_t token;
-
-       debug_tokens("[BLOCK] ");
-
-       token = policy_lex_file(lexer, 0, NULL, 0);
-       if (token != POLICY_LEX_LC_BRACKET) {
-               fprintf(stderr, "%s[%d]: Expected '{'\n",
-                       lexer->filename, lexer->lineno);
-               return 0;
-       }
-
-       rcode = 0;
-       while ((rcode = parse_statement(lexer, tail)) != 0) {
-               if (rcode == 2) {
-                       token = policy_lex_file(lexer, 0, NULL, 0);
-                       if (token != POLICY_LEX_RC_BRACKET) {
-                               fprintf(stderr, "%s[%d]: Expected '}'\n",
-                                       lexer->filename, lexer->lineno);
-                               return 0;
-                       }
-                       return 1;
-               }
-               rad_assert(*tail != NULL);
-               /* parse_statement must fill this in */
-               while (*tail) tail = &((*tail)->next);
-       }
-       debug_tokens("\n");
-
-       /*
-        *      Parse statement failed.
-        */
-       return 0;
-}
-
-
-/*
- *     Parse debugging statements
- */
-static int parse_debug(policy_lex_file_t *lexer)
-{
-       int rcode = 0;
-       policy_lex_t token;
-       char buffer[32];
-
-       token = policy_lex_file(lexer, 0, buffer, sizeof(buffer));
-       if (token != POLICY_LEX_BARE_WORD) {
-               fprintf(stderr, "%s[%d]: Bad debug command\n",
-                       lexer->filename, lexer->lineno);
-               return 0;
-       }
-
-       if (strcasecmp(buffer, "none") == 0) {
-               lexer->debug = POLICY_DEBUG_NONE;
-               rcode = 1;
-
-       } else if (strcasecmp(buffer, "peek") == 0) {
-               lexer->debug |= POLICY_DEBUG_PEEK;
-               rcode = 1;
-
-       } else if (strcasecmp(buffer, "print_tokens") == 0) {
-               lexer->debug |= POLICY_DEBUG_PRINT_TOKENS;
-               rcode = 1;
-
-       } else if (strcasecmp(buffer, "print_policy") == 0) {
-               lexer->debug |= POLICY_DEBUG_PRINT_POLICY;
-               rcode = 1;
-
-       } else if (strcasecmp(buffer, "evaluate") == 0) {
-               lexer->debug |= POLICY_DEBUG_EVALUATE;
-               rcode = 1;
-       }
-
-       if (rcode) {
-               token = policy_lex_file(lexer, POLICY_LEX_FLAG_RETURN_EOL,
-                                       NULL, 0);
-               if (token != POLICY_LEX_EOL) {
-                       fprintf(stderr, "%s[%d]: Expected EOL\n",
-                               lexer->filename, lexer->lineno);
-                       return 0;
-               }
-       } else {
-               fprintf(stderr, "%s[%d]: Bad debug command \"%s\"\n",
-                       lexer->filename, lexer->lineno, buffer);
-               return 0;
-       }
-
-       return 1;
-}
-
-
-/*
- *     Parse a named policy "policy foo {...}"
- */
-static int parse_named_policy(policy_lex_file_t *lexer)
-{
-       int rcode;
-       policy_lex_t token;
-       char mystring[256];
-       policy_named_t *this;
-       DICT_ATTR *dattr;
-
-       debug_tokens("[POLICY] ");
-
-       this = rad_malloc(sizeof(*this));
-       memset(this, 0, sizeof(*this));
-
-       this->item.type = POLICY_TYPE_NAMED_POLICY;
-       this->item.lineno = lexer->lineno;
-
-       token = policy_lex_file(lexer, 0, mystring, sizeof(mystring));
-       if (token != POLICY_LEX_BARE_WORD) {
-               fprintf(stderr, "%s[%d]: Expected policy name, got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-
-       dattr = dict_attrbyname(mystring);
-       if (dattr) {
-               fprintf(stderr, "%s[%d]: Invalid policy name \"%s\": it is already defined as a dictionary attribute\n",
-                       lexer->filename, lexer->lineno, mystring);
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-
-       this->name = strdup(mystring);
-       rcode = parse_block(lexer, &(this->policy));
-       if (!rcode) {
-               rlm_policy_free_item((policy_item_t *) this);
-               return rcode;
-       }
-
-       /*
-        *      And insert it into the tree of policies.
-        *
-        *      For now, policy names aren't scoped, they're global.
-        */
-       if (!rlm_policy_insert(lexer->policies, this)) {
-               fprintf(stderr, "Failed to insert policy \"%s\"\n", this->name);
-               rlm_policy_free_item((policy_item_t *) this);
-               return 0;
-       }
-
-       /*
-        *      Do NOT add it into the list of parsed expressions!
-        *      The above insertion will take care of freeing it if
-        *      anything goes wrong...
-        */
-       return 1;
-}
-
-
-/*
- *     Parse an "include filename" statement
- *
- *     FIXME: Tie this file into the CONF_SECTION for HUP handling!
- */
-static int parse_include(policy_lex_file_t *lexer)
-{
-       char *p;
-       policy_lex_t token;
-       char filename[1024];
-       char buffer[2048];
-
-       token = policy_lex_file(lexer, 0, filename, sizeof(filename));
-       if (token != POLICY_LEX_DOUBLE_QUOTED_STRING) {
-               fprintf(stderr, "%s[%d]: Expected filename, got \"%s\"\n",
-                       lexer->filename, lexer->lineno,
-                       lrad_int2str(rlm_policy_tokens, token, "?"));
-               return 0;
-       }
-
-       /*
-        *      See if we're including all of the files in a subdirectory.
-        */
-       strlcpy(buffer, lexer->filename, sizeof(buffer));
-       p = strrchr(buffer, '/');
-       if (p) {
-               strlcpy(p + 1, filename, sizeof(buffer) - 1 - (p - buffer));
-
-#ifdef HAVE_DIRENT_H
-               p = strrchr(p + 1, '/');
-               if (p && !p[1]) {
-                       DIR             *dir;
-                       struct dirent   *dp;
-
-                       p++;
-
-                       dir = opendir(buffer);
-                       if (!dir) {
-                               fprintf(stderr, "%s[%d]: Error opening %s:%s\n",
-                                       lexer->filename, lexer->lineno,
-                                       buffer, strerror(errno));
-                               return 0;
-                       }
-
-                       /*
-                        *      Read the directory, ignoring "." files.
-                        */
-                       while ((dp = readdir(dir)) != NULL) {
-                               struct stat buf;
-
-                               if (dp->d_name[0] == '.') continue;
-                               if (strchr(dp->d_name, '~') != NULL) continue;
-
-                               strlcpy(p, dp->d_name,
-                                       sizeof(buffer) - (p - buffer));
-
-                               if ((stat(buffer, &buf) != 0) ||
-                                   S_ISDIR(buf.st_mode)) continue;
-
-                               debug_tokens("\nincluding file %s\n", buffer);
-                               if (!rlm_policy_parse(lexer->policies, buffer)) {
-                                       closedir(dir);
-                                       return 0;
-                               }
-                       }
-                       closedir(dir);
-                       return 1;
-               } /* else it must have been a normalx file */
-#endif
-       } else {
-               snprintf(buffer, sizeof(buffer), "%s/%s",
-                        radius_dir, filename);
-       }
-
-       /*
-        *      Handle one include file.
-        */
-       debug_tokens("\nincluding file %s\n", buffer);
-       if (!rlm_policy_parse(lexer->policies, buffer)) {
-               return 0;
-       }
-
-       return 1;
-}
-
-
-/*
- *     Parse data from a file into a policy language.
- */
-int rlm_policy_parse(rbtree_t *policies, const char *filename)
-{
-       FILE *fp;
-       policy_lex_t token;
-       policy_lex_file_t mylexer, *lexer = NULL;
-       char buffer[32];
-
-       fp = fopen(filename, "r");
-       if (!fp) {
-               fprintf(stderr, "Failed to open %s: %s\n",
-                       filename, strerror(errno));
-               return 0;
-       }
-
-       lexer = &mylexer;
-       memset(lexer, 0, sizeof(*lexer));
-       lexer->filename = filename;
-       lexer->fp = fp;
-       lexer->token = POLICY_LEX_BAD;
-       lexer->parse = NULL;    /* initial input */
-       lexer->policies = policies;
-
-       do {
-               int reserved;
-
-               token = policy_lex_file(lexer, 0, buffer, sizeof(buffer));
-               switch (token) {
-               case POLICY_LEX_BARE_WORD:
-                       reserved = lrad_str2int(policy_reserved_words,
-                                               buffer,
-                                               POLICY_RESERVED_UNKNOWN);
-                       switch (reserved) {
-                       case POLICY_RESERVED_POLICY:
-                               if (!parse_named_policy(lexer)) {
-                                       return 0;
-                               }
-                               break;
-
-                       case POLICY_RESERVED_INCLUDE:
-                               if (!parse_include(lexer)) {
-                                       return 0;
-                               }
-                               break;
-
-                       case POLICY_RESERVED_DEBUG:
-                               if (!parse_debug(lexer)) {
-                                       return 0;
-                               }
-                               break;
-
-                       default:
-                               fprintf(stderr, "%s[%d]: Unexpected word \"%s\"\n",
-                                       lexer->filename, lexer->lineno,
-                                       buffer);
-                               return 0;
-                               break;
-                       } /* switch over reserved words */
-
-               case POLICY_LEX_EOF:
-                       break;
-
-               default:
-                       fprintf(stderr, "%s[%d]: Illegal input\n",
-                               lexer->filename, lexer->lineno);
-                       return 0;
-               }
-
-               fflush(stdout);
-       } while (token != POLICY_LEX_EOF);
-
-
-       debug_tokens("--------------------------------------------------\n");
-
-       return 1;
-}
-
diff --git a/src/modules/rlm_policy/rlm_policy.c b/src/modules/rlm_policy/rlm_policy.c
deleted file mode 100644 (file)
index f527116..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * rlm_policy.c                Implements a policy language
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004  Alan DeKok <aland@ox.org>
- * Copyright 2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-#include "rlm_policy.h"
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-  { "filename",  PW_TYPE_FILENAME,
-    offsetof(rlm_policy_t,filename), NULL,  NULL},
-
-  { NULL, -1, 0, NULL, NULL }          /* end the list */
-};
-
-
-/*
- *     Callbacks for red-black trees.
- */
-static int policyname_cmp(const void *a, const void *b)
-{
-       return strcmp(((const policy_named_t *)a)->name,
-                     ((const policy_named_t *)b)->name);
-}
-
-
-/*
- *     Detach a policy.
- */
-static int policy_detach(void *instance)
-{
-       rlm_policy_t *inst = instance;
-
-       if (inst->policies) rbtree_free(inst->policies);
-       free(instance);
-       return 0;
-}
-
-/*
- *     Do any per-module initialization that is separate to each
- *     configured instance of the module.  e.g. set up connections
- *     to external databases, read configuration files, set up
- *     dictionary entries, etc.
- *
- *     If configuration information is given in the config section
- *     that must be referenced in later calls, store a handle to it
- *     in *instance otherwise put a null pointer there.
- */
-static int policy_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_policy_t *inst;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       inst = rad_malloc(sizeof(*inst));
-       if (!inst) {
-               return -1;
-       }
-       memset(inst, 0, sizeof(*inst));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, inst, module_config) < 0) {
-               policy_detach(inst);
-               return -1;
-       }
-
-       inst->policies = rbtree_create(policyname_cmp, rlm_policy_free_item, 0);
-       if (!inst->policies) {
-               policy_detach(inst);
-               return -1;
-       }
-
-       /*
-        *      Parse the policy from the file.
-        */
-       if (!rlm_policy_parse(inst->policies, inst->filename)) {
-               policy_detach(inst);
-               return -1;
-       }
-
-       *instance = inst;
-
-       return 0;
-}
-
-
-/*
- *     Insert a named policy into a list.
- */
-int rlm_policy_insert(rbtree_t *head, policy_named_t *policy)
-{
-       if (!rbtree_insert(head, policy)) {
-               rlm_policy_free_item((policy_item_t *) policy);
-               return 0;
-       }
-
-       return 1;
-}
-
-
-/*
- *     Find a named policy
- */
-policy_named_t *rlm_policy_find(rbtree_t *head, const char *name)
-{
-       policy_named_t mypolicy;
-
-       mypolicy.name = name;
-
-       return rbtree_finddata(head, &mypolicy);
-}
-
-
-/*
- *     Find the named user in this modules database.  Create the set
- *     of attribute-value pairs to check and reply with for this user
- *     from the database. The authentication code only needs to check
- *     the password, the rest is done here.
- */
-static int policy_authorize(void *instance, REQUEST *request)
-{
-       return rlm_policy_evaluate((rlm_policy_t *) instance, request,
-                                  "authorize");
-}
-
-
-static int policy_preacct(void *instance, REQUEST *request)
-{
-       return rlm_policy_evaluate((rlm_policy_t *) instance, request,
-                                  "preacct");
-}
-
-static int policy_accounting(void *instance, REQUEST *request)
-{
-       return rlm_policy_evaluate((rlm_policy_t *) instance, request,
-                                  "accounting");
-}
-
-static int policy_post_auth(void *instance, REQUEST *request)
-{
-       return rlm_policy_evaluate((rlm_policy_t *) instance, request,
-                                  "post-auth");
-}
-
-static int policy_pre_proxy(void *instance, REQUEST *request)
-{
-       return rlm_policy_evaluate((rlm_policy_t *) instance, request,
-                                  "pre-proxy");
-}
-
-static int policy_post_proxy(void *instance, REQUEST *request)
-{
-       return rlm_policy_evaluate((rlm_policy_t *) instance, request,
-                                  "post-proxy");
-}
-
-/*
- *     The "free" functions are here, for no particular reason.
- */
-void rlm_policy_free_item(policy_item_t *item)
-{
-       while (item) {
-               policy_item_t *next = item->next;
-
-               switch (item->type) {
-               default:
-               case POLICY_TYPE_BAD:
-                       break;
-
-               case POLICY_TYPE_ASSIGNMENT:
-                       {
-                               policy_assignment_t *this;
-
-                               this = (policy_assignment_t *) item;
-                               if (this->lhs) free(this->lhs);
-                               if (this->rhs) free(this->rhs);
-                       }
-                       break;
-
-               case POLICY_TYPE_CONDITIONAL:
-                       {
-                               policy_condition_t *this;
-
-                               this = (policy_condition_t *) item;
-                               if (this->lhs) free(this->lhs);
-                               if (this->rhs) free(this->rhs);
-
-                               if (this->child) {
-                                       rlm_policy_free_item(this->child);
-                                       this->child = NULL;
-                               }
-                       }
-                       break;
-
-               case POLICY_TYPE_IF:
-                       {
-                               policy_if_t *this;
-
-                               this = (policy_if_t *) item;
-                               if (this->condition) {
-                                       rlm_policy_free_item(this->condition);
-                                       this->condition = NULL;
-                               }
-                               if (this->if_true) {
-                                       rlm_policy_free_item(this->if_true);
-                                       this->if_true = NULL;
-                               }
-                               if (this->if_false) {
-                                       rlm_policy_free_item(this->if_false);
-                                       this->if_false = NULL;
-                               }
-                       }
-                       break;
-
-               case POLICY_TYPE_ATTRIBUTE_LIST:
-                       {
-                               policy_attributes_t *this;
-
-                               this = (policy_attributes_t *) item;
-                               rlm_policy_free_item(this->attributes);
-                       }
-                       break;
-
-               case POLICY_TYPE_NAMED_POLICY:
-                       {
-                               policy_named_t *this;
-
-                               this = (policy_named_t *) item;
-                               rad_assert(this->name != NULL);
-                               free(this->name);
-                               rlm_policy_free_item(this->policy);
-                       }
-                       break;
-
-               case POLICY_TYPE_CALL:
-                       {
-                               policy_call_t *this;
-
-                               this = (policy_call_t *) item;
-                               if (this->name) free(this->name);
-                       }
-                       break;
-
-               case POLICY_TYPE_RETURN:
-                       break;  /* do nothing */
-
-               case POLICY_TYPE_MODULE:
-                       {
-                               policy_module_t *this;
-
-                               this = (policy_module_t *) item;
-                               if (this->cs) cf_section_free(&this->cs);
-                               if (this->mc) modcallable_free(&this->mc);
-                       }
-                       break;
-               } /* switch over type */
-               item->next = NULL; /* for debugging & sanity checks */
-               item->type = POLICY_TYPE_BAD;
-               free(item);
-
-               item = next;
-       }
-}
-
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- *
- *     If the module needs to temporarily modify it's instantiation
- *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
- *     The server will then take care of ensuring that the module
- *     is single-threaded.
- */
-module_t rlm_policy = {
-       RLM_MODULE_INIT,
-       "policy",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       policy_instantiate,             /* instantiation */
-       policy_detach,                  /* detach */
-       {
-               NULL,                   /* authentication */
-               policy_authorize,       /* authorization */
-               policy_preacct,         /* preaccounting */
-               policy_accounting,      /* accounting */
-               NULL,                   /* checksimul */
-               policy_pre_proxy,       /* pre-proxy */
-               policy_post_proxy,      /* post-proxy */
-               policy_post_auth        /* post-auth */
-       },
-};
diff --git a/src/modules/rlm_policy/rlm_policy.h b/src/modules/rlm_policy/rlm_policy.h
deleted file mode 100644 (file)
index 79b27ec..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * rlm_policy.h    Header file for policy module
- *
- * Version:     $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004  Alan DeKok <aland@freeradius.org>
- * Copyright 2006  The FreeRADIUS server project
- */
-#ifndef _RLM_POLICY_H
-#define _RLM_POLICY_H
-
-#include <freeradius-devel/ident.h>
-RCSIDH(rlm_policy_h, "$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/modcall.h>
-#include <freeradius-devel/rad_assert.h>
-
-/*
- *     Internal lexer.
- */
-typedef enum policy_lex_t {
-       POLICY_LEX_BAD = 0,
-       POLICY_LEX_EOF,         /* end of the file/input */
-       POLICY_LEX_EOL,         /* end of the line */
-       POLICY_LEX_WHITESPACE,
-       POLICY_LEX_HASH,
-       POLICY_LEX_L_BRACKET,
-       POLICY_LEX_R_BRACKET,
-       POLICY_LEX_LC_BRACKET,  /* left curly bracket */
-       POLICY_LEX_RC_BRACKET,  /* right curly bracket */
-       POLICY_LEX_COMMA,
-       POLICY_LEX_L_AND,       /* logical AND */
-       POLICY_LEX_L_OR,        /* logical OR */
-       POLICY_LEX_AND,         /* bit-wise AND */
-       POLICY_LEX_OR,          /* bit-wise OR */
-       POLICY_LEX_L_NOT,
-       POLICY_LEX_PLUS,        /* + */
-       POLICY_LEX_MINUS,       /* - */
-       POLICY_LEX_ASSIGN,      /* = */
-       POLICY_LEX_CMP_EQUALS,
-       POLICY_LEX_CMP_NOT_EQUALS,
-       POLICY_LEX_CMP_TRUE,
-       POLICY_LEX_CMP_FALSE,
-       POLICY_LEX_LT,
-       POLICY_LEX_GT,
-       POLICY_LEX_LE,
-       POLICY_LEX_GE,
-       POLICY_LEX_RX_EQUALS,
-       POLICY_LEX_RX_NOT_EQUALS,
-       POLICY_LEX_SET_EQUALS,  /* := */
-       POLICY_LEX_AND_EQUALS,  /* &= */
-       POLICY_LEX_OR_EQUALS,   /* |= */
-       POLICY_LEX_PLUS_EQUALS, /* += */
-       POLICY_LEX_MINUS_EQUALS, /* -= */
-       POLICY_LEX_CONCAT_EQUALS, /* .= */
-       POLICY_LEX_VARIABLE,    /* %{foo} */
-       POLICY_LEX_FUNCTION,    /* Hmmm... */
-       POLICY_LEX_DOUBLE_QUOTED_STRING,
-       POLICY_LEX_SINGLE_QUOTED_STRING,
-       POLICY_LEX_BACK_QUOTED_STRING,
-       POLICY_LEX_BARE_WORD
-} policy_lex_t;
-
-typedef enum policy_type_t {
-       POLICY_TYPE_BAD = 0,
-       POLICY_TYPE_IF,
-       POLICY_TYPE_CONDITIONAL,
-       POLICY_TYPE_ASSIGNMENT,
-       POLICY_TYPE_ATTRIBUTE_LIST,
-       POLICY_TYPE_PRINT,
-       POLICY_TYPE_NAMED_POLICY,
-       POLICY_TYPE_CALL,
-       POLICY_TYPE_RETURN,
-       POLICY_TYPE_MODULE,
-       POLICY_TYPE_NUM_TYPES
-} policy_type_t;
-
-
-/*
- *     For our policy language, we want to have some reserved words.
- */
-typedef enum policy_reserved_word_t {
-       POLICY_RESERVED_UNKNOWN = 0,
-       POLICY_RESERVED_CONTROL,
-       POLICY_RESERVED_REQUEST,
-       POLICY_RESERVED_REPLY,
-       POLICY_RESERVED_PROXY_REQUEST,
-       POLICY_RESERVED_PROXY_REPLY,
-       POLICY_RESERVED_IF,
-       POLICY_RESERVED_ELSE,
-       POLICY_RESERVED_DEBUG,
-       POLICY_RESERVED_PRINT,
-       POLICY_RESERVED_POLICY,
-       POLICY_RESERVED_INCLUDE,
-       POLICY_RESERVED_RETURN,
-       POLICY_RESERVED_MODULE,
-       POLICY_RESERVED_NUM_WORDS
-} policy_reserved_word_t;
-
-
-#define POLICY_DEBUG_NONE           0
-#define POLICY_DEBUG_PEEK           (1 << 0)
-#define        POLICY_DEBUG_PRINT_TOKENS   (1 << 1)
-#define        POLICY_DEBUG_PRINT_POLICY   (1 << 2)
-#define        POLICY_DEBUG_EVALUATE       (1 << 3)
-
-/*
- *     A policy item
- */
-typedef struct policy_item_t {
-       struct policy_item_t    *next;
-       policy_type_t           type;
-       int                     lineno;
-} policy_item_t;
-
-
-/*
- *     A list of attributes to add/replace/whatever in a packet.
- */
-typedef struct policy_print_t {
-       policy_item_t           item;
-       policy_lex_t            rhs_type;
-       const char              *rhs;
-} policy_print_t;
-
-
-/*
- *     A list of attributes to add/replace/whatever in a packet.
- */
-typedef struct policy_attributes_t {
-       policy_item_t           item;
-       policy_reserved_word_t  where; /* where to do it */
-       policy_lex_t            how; /* how to do */
-       policy_item_t           *attributes; /* things to do */
-       /* FIXME: VALUE_PAIR *vps; */
-} policy_attributes_t;
-
-
-/*
- *     Holds a named policy
- */
-typedef struct policy_named_t {
-       policy_item_t   item;
-       const char      *name;
-       policy_item_t   *policy;
-} policy_named_t;
-
-
-/*
- *     Reference to a named policy
- */
-typedef struct policy_call_t {
-       policy_item_t   item;
-       const char      *name;
-} policy_call_t;
-
-
-/*
- *     Hold a return code
- */
-typedef struct policy_return_t {
-       policy_item_t   item;
-       int             rcode;
-} policy_return_t;
-
-
-/*
- *     Holds an assignment.
- */
-typedef struct policy_assignment_t {
-       policy_item_t   item;
-       char            *lhs;
-       policy_lex_t    assign; /* operator for the assignment */
-       policy_lex_t    rhs_type;
-       char            *rhs;
-} policy_assignment_t;
-
-
-/*
- *     Condition
- */
-typedef struct policy_condition_t {
-       policy_item_t   item;
-
-       policy_lex_t    lhs_type;
-       char            *lhs;
-       policy_lex_t    compare;
-       policy_lex_t    rhs_type; /* bare word, quoted string, etc. */
-       char            *rhs;
-
-       policy_lex_t    child_condition;
-       policy_item_t   *child;
-} policy_condition_t;
-
-
-/*
- *     Holds an "if" statement.  The "else" may be a block, or another "if"
- */
-typedef struct policy_if_t {
-       policy_item_t           item;
-       policy_item_t           *condition;
-       policy_item_t           *if_true;
-       policy_item_t           *if_false;      /* assignment, or other 'if' */
-} policy_if_t;
-
-
-/*
- *     Holds a reference to calling other modules... wild.
- */
-typedef struct policy_module_t {
-       policy_item_t   item;
-       int             component; /* authorize, authenticate, etc. */
-       CONF_SECTION    *cs;
-       modcallable     *mc;
-} policy_module_t;
-
-
-/*
- *     Define a structure for our module configuration.
- *
- *     These variables do not need to be in a structure, but it's
- *     a lot cleaner to do so, and a pointer to the structure can
- *     be used as the instance handle.
- */
-typedef struct rlm_policy_t {
-       char            *filename;
-       rbtree_t        *policies;
-} rlm_policy_t;
-
-
-/*
- *     Functions.
- */
-extern const LRAD_NAME_NUMBER rlm_policy_tokens[];
-extern const LRAD_NAME_NUMBER policy_reserved_words[];
-extern const LRAD_NAME_NUMBER policy_return_codes[];
-extern const LRAD_NAME_NUMBER policy_component_names[];
-
-extern int rlm_policy_insert(rbtree_t *head, policy_named_t *policy);
-extern policy_named_t *rlm_policy_find(rbtree_t *head, const char *name);
-
-extern int rlm_policy_parse(rbtree_t *policies, const char *filename);
-extern void rlm_policy_free_item(policy_item_t *item);
-extern void rlm_policy_print(const policy_item_t *item);
-extern int rlm_policy_evaluate(rlm_policy_t *inst, REQUEST *request,
-                              const char *name);
-
-#endif /* _RLM_POLICY_H */
index 39fd012..5668215 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
+#include       <sys/stat.h>
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
 #include       <ctype.h>
 
+#include       "radiusd.h"
+#include       "modules.h"
+
 typedef struct rlm_preprocess_t {
        char            *huntgroup_file;
        char            *hints_file;
@@ -45,11 +51,11 @@ typedef struct rlm_preprocess_t {
        int             with_alvarion_vsa_hack;
 } rlm_preprocess_t;
 
-static const CONF_PARSER module_config[] = {
-       { "huntgroups",                 PW_TYPE_FILENAME,
+static CONF_PARSER module_config[] = {
+       { "huntgroups",                 PW_TYPE_STRING_PTR,
          offsetof(rlm_preprocess_t,huntgroup_file), NULL,
          "${raddbdir}/huntgroups" },
-       { "hints",                      PW_TYPE_FILENAME,
+       { "hints",                      PW_TYPE_STRING_PTR,
          offsetof(rlm_preprocess_t,hints_file), NULL,
          "${raddbdir}/hints" },
        { "with_ascend_hack",           PW_TYPE_BOOLEAN,
@@ -87,11 +93,11 @@ static void ascend_nasport_hack(VALUE_PAIR *nas_port, int channels_per_line)
                return;
        }
 
-       if (nas_port->vp_integer > 9999) {
-               service = nas_port->vp_integer/10000; /* 1=digital 2=analog */
-               line = (nas_port->vp_integer - (10000 * service)) / 100;
-               channel = nas_port->vp_integer-((10000 * service)+(100 * line));
-               nas_port->vp_integer =
+       if (nas_port->lvalue > 9999) {
+               service = nas_port->lvalue/10000; /* 1=digital 2=analog */
+               line = (nas_port->lvalue - (10000 * service)) / 100;
+               channel = nas_port->lvalue-((10000 * service)+(100 * line));
+               nas_port->lvalue =
                        (channel - 1) + (line - 1) * channels_per_line;
        }
 }
@@ -120,7 +126,7 @@ static void cisco_vsa_hack(VALUE_PAIR *vp)
                /*
                 *  No weird packing.  Ignore it.
                 */
-               ptr = strchr(vp->vp_strvalue, '='); /* find an '=' */
+               ptr = strchr(vp->strvalue, '='); /* find an '=' */
                if (!ptr) continue;
 
                /*
@@ -138,7 +144,7 @@ static void cisco_vsa_hack(VALUE_PAIR *vp)
                        char *p;
                        DICT_ATTR       *dattr;
 
-                       p = vp->vp_strvalue;
+                       p = vp->strvalue;
                        gettoken(&p, newattr, sizeof(newattr));
 
                        if (((dattr = dict_attrbyname(newattr)) != NULL) &&
@@ -159,10 +165,10 @@ static void cisco_vsa_hack(VALUE_PAIR *vp)
                         *      value field, we use only the value on
                         *      the right side of the '=' character.
                         */
-                       strlcpy(newattr, ptr + 1, sizeof(newattr));
-                       strlcpy((char *)vp->vp_strvalue, newattr,
-                               sizeof(vp->vp_strvalue));
-                       vp->length = strlen((char *)vp->vp_strvalue);
+                       strNcpy(newattr, ptr + 1, sizeof(newattr));
+                       strNcpy((char *)vp->strvalue, newattr,
+                               sizeof(vp->strvalue));
+                       vp->length = strlen((char *)vp->strvalue);
                }
        }
 }
@@ -217,10 +223,10 @@ static void rad_mangle(rlm_preprocess_t *data, REQUEST *request)
                 *
                 *      FIXME: should we handle this as a REALM ?
                 */
-               if ((ptr = strchr(namepair->vp_strvalue, '\\')) != NULL) {
-                       strlcpy(newname, ptr + 1, sizeof(newname));
+               if ((ptr = strchr(namepair->strvalue, '\\')) != NULL) {
+                       strNcpy(newname, ptr + 1, sizeof(newname));
                        /* Same size */
-                       strcpy(namepair->vp_strvalue, newname);
+                       strcpy(namepair->strvalue, newname);
                        namepair->length = strlen(newname);
                }
        }
@@ -236,12 +242,12 @@ static void rad_mangle(rlm_preprocess_t *data, REQUEST *request)
                 *
                 *      Reported by Lucas Heise <root@laonet.net>
                 */
-               if ((strlen((char *)namepair->vp_strvalue) > 10) &&
-                   (namepair->vp_strvalue[10] == '/')) {
-                       for (ptr = (char *)namepair->vp_strvalue + 11; *ptr; ptr++)
+               if ((strlen((char *)namepair->strvalue) > 10) &&
+                   (namepair->strvalue[10] == '/')) {
+                       for (ptr = (char *)namepair->strvalue + 11; *ptr; ptr++)
                                *(ptr - 1) = *ptr;
                        *(ptr - 1) = 0;
-                       namepair->length = strlen((char *)namepair->vp_strvalue);
+                       namepair->length = strlen((char *)namepair->strvalue);
                }
        }
 
@@ -251,9 +257,11 @@ static void rad_mangle(rlm_preprocess_t *data, REQUEST *request)
         */
        if (pairfind(request_pairs, PW_FRAMED_PROTOCOL) != NULL &&
            pairfind(request_pairs, PW_SERVICE_TYPE) == NULL) {
-               tmp = radius_paircreate(request, &request->packet->vps,
-                                       PW_SERVICE_TYPE, PW_TYPE_INTEGER);
-               tmp->vp_integer = PW_FRAMED_USER;
+               tmp = paircreate(PW_SERVICE_TYPE, PW_TYPE_INTEGER);
+               if (tmp) {
+                       tmp->lvalue = PW_FRAMED_USER;
+                       pairmove(&request_pairs, &tmp);
+               }
        }
 }
 
@@ -275,7 +283,7 @@ static int hunt_paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check)
                tmp = check_item->next;
                check_item->next = NULL;
 
-               result = paircompare(req, request, check_item, NULL);
+               result = paircmp(req, request, check_item, NULL);
 
                check_item->next = tmp;
                check_item = check_item->next;
@@ -308,7 +316,7 @@ static int hints_setup(PAIR_LIST *hints, REQUEST *request)
        if ((tmp = pairfind(request_pairs, PW_USER_NAME)) == NULL)
                name = NULL;
        else
-               name = (char *)tmp->vp_strvalue;
+               name = (char *)tmp->strvalue;
 
        if (name == NULL || name[0] == 0)
                /*
@@ -318,9 +326,9 @@ static int hints_setup(PAIR_LIST *hints, REQUEST *request)
 
        for (i = hints; i; i = i->next) {
                /*
-                *      Use "paircompare", which is a little more general...
+                *      Use "paircmp", which is a little more general...
                 */
-               if (paircompare(request, request_pairs, i->check, NULL) == 0) {
+               if (paircmp(request, request_pairs, i->check, NULL) == 0) {
                        DEBUG2("  hints: Matched %s at %d",
                               i->name, i->lineno);
                        break;
@@ -346,11 +354,11 @@ static int hints_setup(PAIR_LIST *hints, REQUEST *request)
 /*
  *     See if we have access to the huntgroup.
  */
-static int huntgroup_access(REQUEST *request, PAIR_LIST *huntgroups)
+static int huntgroup_access(REQUEST *request,
+                           PAIR_LIST *huntgroups, VALUE_PAIR *request_pairs)
 {
        PAIR_LIST       *i;
        int             r = RLM_MODULE_OK;
-       VALUE_PAIR      *request_pairs = request->packet->vps;
 
        /*
         *      We're not controlling access by huntgroups:
@@ -363,7 +371,7 @@ static int huntgroup_access(REQUEST *request, PAIR_LIST *huntgroups)
                /*
                 *      See if this entry matches.
                 */
-               if (paircompare(request, request_pairs, i->check, NULL) != 0)
+               if (paircmp(request, request_pairs, i->check, NULL) != 0)
                        continue;
 
                /*
@@ -379,13 +387,19 @@ static int huntgroup_access(REQUEST *request, PAIR_LIST *huntgroups)
                         */
                        vp = pairfind(request_pairs, PW_HUNTGROUP_NAME);
                        if (!vp) {
-                               vp = radius_paircreate(request,
-                                                      &request->packet->vps,
-                                                      PW_HUNTGROUP_NAME,
-                                                      PW_TYPE_STRING);
-                               strlcpy(vp->vp_strvalue, i->name,
-                                       sizeof(vp->vp_strvalue));
-                               vp->length = strlen(vp->vp_strvalue);
+                               vp = paircreate(PW_HUNTGROUP_NAME,
+                                               PW_TYPE_STRING);
+                               if (!vp) {
+                                       radlog(L_ERR, "No memory");
+                                       r = RLM_MODULE_FAIL;
+                                       break;
+                               }
+
+                               strNcpy(vp->strvalue, i->name,
+                                       sizeof(vp->strvalue));
+                               vp->length = strlen(vp->strvalue);
+
+                               pairadd(&request_pairs, vp);
                        }
                        r = RLM_MODULE_OK;
                }
@@ -403,34 +417,37 @@ static int add_nas_attr(REQUEST *request)
 {
        VALUE_PAIR *nas;
 
-       switch (request->packet->src_ipaddr.af) {
-       case AF_INET:
-               nas = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS);
+       nas = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS);
+       if (!nas) {
+               nas = paircreate(PW_NAS_IP_ADDRESS, PW_TYPE_IPADDR);
                if (!nas) {
-                       nas = radius_paircreate(request, &request->packet->vps,
-                                               PW_NAS_IP_ADDRESS,
-                                               PW_TYPE_IPADDR);
-                       nas->vp_ipaddr = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
+                       radlog(L_ERR, "No memory");
+                       return -1;
                }
-               break;
-
-       case AF_INET6:
-               nas = pairfind(request->packet->vps, PW_NAS_IPV6_ADDRESS);
-               if (!nas) {
-                       nas = radius_paircreate(request, &request->packet->vps,
-                                               PW_NAS_IPV6_ADDRESS,
-                                               PW_TYPE_IPV6ADDR);
-                       memcpy(nas->vp_strvalue,
-                              &request->packet->src_ipaddr.ipaddr,
-                              sizeof(request->packet->src_ipaddr.ipaddr));
-               }
-               break;
-
-       default:
-               radlog(L_ERR, "Unknown address family for packet");
-               return -1;
+               nas->lvalue = request->packet->src_ipaddr;
+               ip_hostname(nas->strvalue, sizeof(nas->strvalue), nas->lvalue);
+               pairadd(&request->packet->vps, nas);
        }
 
+       /*
+        *      Add in a Client-IP-Address, to tell the user
+        *      the source IP of the request.  That is, the client,
+        *
+        *      Note that this MAY BE different from the NAS-IP-Address,
+        *      especially if the request is being proxied.
+        *
+        *      Note also that this is a server configuration item,
+        *      and will NOT make it to any packets being sent from
+        *      the server.
+        */
+       nas = paircreate(PW_CLIENT_IP_ADDRESS, PW_TYPE_IPADDR);
+       if (!nas) {
+         radlog(L_ERR, "No memory");
+         return -1;
+       }
+       nas->lvalue = request->packet->src_ipaddr;
+       ip_hostname(nas->strvalue, sizeof(nas->strvalue), nas->lvalue);
+       pairadd(&request->packet->vps, nas);
        return 0;
 }
 
@@ -493,6 +510,7 @@ static int preprocess_instantiate(CONF_SECTION *conf, void **instance)
  */
 static int preprocess_authorize(void *instance, REQUEST *request)
 {
+       char buf[1024];
        int r;
        rlm_preprocess_t *data = (rlm_preprocess_t *) instance;
 
@@ -549,18 +567,20 @@ static int preprocess_authorize(void *instance, REQUEST *request)
        if (pairfind(request->packet->vps, PW_CHAP_PASSWORD) &&
            pairfind(request->packet->vps, PW_CHAP_CHALLENGE) == NULL) {
                VALUE_PAIR *vp;
-
-               vp = radius_paircreate(request, &request->packet->vps,
-                                      PW_CHAP_CHALLENGE, PW_TYPE_OCTETS);
+               vp = paircreate(PW_CHAP_CHALLENGE, PW_TYPE_OCTETS);
+               if (!vp) {
+                       radlog(L_ERR|L_CONS, "no memory");
+                       return RLM_MODULE_FAIL;
+               }
                vp->length = AUTH_VECTOR_LEN;
-               memcpy(vp->vp_strvalue, request->packet->vector, AUTH_VECTOR_LEN);
+               memcpy(vp->strvalue, request->packet->vector, AUTH_VECTOR_LEN);
+               pairadd(&request->packet->vps, vp);
        }
 
-       if ((r = huntgroup_access(request,
-                                 data->huntgroups)) != RLM_MODULE_OK) {
-               char buf[1024];
+       if ((r = huntgroup_access(request, data->huntgroups,
+                            request->packet->vps)) != RLM_MODULE_OK) {
                radlog(L_AUTH, "No huntgroup access: [%s] (%s)",
-                      request->username ? request->username->vp_strvalue : "<NO User-Name>",
+                      request->username ? request->username->strvalue : "<No User-Name>",
                       auth_name(buf, sizeof(buf), request, 1));
                return r;
        }
@@ -607,15 +627,6 @@ static int preprocess_preaccounting(void *instance, REQUEST *request)
 
        r = hints_setup(data->hints, request);
 
-       if ((r = huntgroup_access(request,
-                                 data->huntgroups)) != RLM_MODULE_OK) {
-               char buf[1024];
-               radlog(L_INFO, "No huntgroup access: [%s] (%s)",
-                      request->username ? request->username->vp_strvalue : "<NO User-Name>",
-                      auth_name(buf, sizeof(buf), request, 1));
-               return r;
-       }
-
        return r;
 }
 
@@ -629,6 +640,8 @@ static int preprocess_detach(void *instance)
        pairlist_free(&(data->huntgroups));
        pairlist_free(&(data->hints));
 
+       free(data->huntgroup_file);
+       free(data->hints_file);
        free(data);
 
        return 0;
@@ -636,11 +649,10 @@ static int preprocess_detach(void *instance)
 
 /* globally exported name */
 module_t rlm_preprocess = {
-       RLM_MODULE_INIT,
        "preprocess",
        0,                      /* type: reserved */
+       NULL,                   /* initialization */
        preprocess_instantiate, /* instantiation */
-       preprocess_detach,      /* detach */
        {
                NULL,                   /* authentication */
                preprocess_authorize,   /* authorization */
@@ -651,5 +663,7 @@ module_t rlm_preprocess = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       preprocess_detach,      /* detach */
+       NULL,                   /* destroy */
 };
 
diff --git a/src/modules/rlm_protocol_filter/Makefile b/src/modules/rlm_protocol_filter/Makefile
deleted file mode 100755 (executable)
index 9d08409..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile
-#
-# Version:     $Id$
-#
-
-TARGET         = rlm_protocol_filter
-SRCS           = rlm_protocol_filter.c
-
-include ../rules.mak
diff --git a/src/modules/rlm_protocol_filter/rlm_protocol_filter.c b/src/modules/rlm_protocol_filter/rlm_protocol_filter.c
deleted file mode 100755 (executable)
index b8b8790..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * rlm_protocol_filter.c
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2004  Cladju Consulting, Inc. <aland@cladju.com>
- * Copyright 2006  The FreeRADIUS server project
- */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-
-/*
- *     Define a structure for our module configuration.
- *
- */
-typedef struct rlm_protocol_filter_t {
-       char            *filename;
-       char            *key;
-       CONF_SECTION    *cs;
-} rlm_protocol_filter_t;
-
-/*
- *     A mapping of configuration file names to internal variables.
- *
- *     Note that the string is dynamically allocated, so it MUST
- *     be freed.  When the configuration file parse re-reads the string,
- *     it free's the old one, and strdup's the new one, placing the pointer
- *     to the strdup'd string into 'config.string'.  This gets around
- *     buffer over-flows.
- */
-static const CONF_PARSER module_config[] = {
-       { "filename",  PW_TYPE_FILENAME,
-         offsetof(rlm_protocol_filter_t,filename), NULL,
-         "${raddbdir}/protocol_filter.conf"},
-
-       { "key",  PW_TYPE_STRING_PTR,
-         offsetof(rlm_protocol_filter_t,key), NULL, "%{Realm:-DEFAULT}"},
-
-       { NULL, -1, 0, NULL, NULL }             /* end the list */
-};
-
-static int filter_detach(void *instance)
-{
-       rlm_protocol_filter_t *inst = instance;
-
-       if (inst->cs) cf_section_free(&(inst->cs));
-
-       free(instance);
-       return 0;
-}
-
-
-/*
- *     Do any per-module initialization that is separate to each
- *     configured instance of the module.  e.g. set up connections
- *     to external databases, read configuration files, set up
- *     dictionary entries, etc.
- *
- *     If configuration information is given in the config section
- *     that must be referenced in later calls, store a handle to it
- *     in *instance otherwise put a null pointer there.
- */
-static int filter_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_protocol_filter_t *inst;
-
-       /*
-        *      Set up a storage area for instance data
-        */
-       inst = rad_malloc(sizeof(*inst));
-       if (!inst) {
-               return -1;
-       }
-       memset(inst, 0, sizeof(*inst));
-
-       /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-       if (cf_section_parse(conf, inst, module_config) < 0) {
-               filter_detach(inst);
-               return -1;
-       }
-
-       inst->cs = conf_read("rlm_protocol_filter", 0,
-                            inst->filename, NULL);
-       if (!inst->cs) {
-               filter_detach(inst);
-               return -1;
-       }
-
-       *instance = inst;
-
-       return 0;
-}
-
-
-/*
- *     Return permission.
- */
-static int str2sense(const char *str)
-{
-       if (strcasecmp(str, "permit") == 0) return 1;
-       if (strcasecmp(str, "deny") == 0) return 0;
-
-       return -1;
-}
-
-/*
- *     Apply a subsection to a request.
- *     Returns permit/deny/error.
- */
-static int apply_subsection(rlm_protocol_filter_t *inst, REQUEST *request,
-                           CONF_SECTION *cs, const char *name)
-{
-       int sense;
-       CONF_PAIR *cp;
-       const char *value;
-       char keybuf[256];
-
-       DEBUG2("  rlm_protocol_filter: Found subsection %s", name);
-
-       cp = cf_pair_find(cs, "key");
-       if (!cp) {
-               radlog(L_ERR, "rlm_protocol_filter: %s[%d]: No key defined in subsection %s",
-                      inst->filename, cf_section_lineno(cs), name);
-               return RLM_MODULE_FAIL;
-       }
-
-       radius_xlat(keybuf, sizeof(keybuf),
-                   cf_pair_value(cp), request, NULL);
-       if (!*keybuf) {
-               DEBUG2("  rlm_protocol_filter: %s[%d]: subsection %s, key is empty, doing nothing.",
-                      inst->filename, cf_section_lineno(cs), name);
-               return RLM_MODULE_NOOP;
-       }
-
-       DEBUG2("  rlm_protocol_filter: %s[%d]: subsection %s, using key %s",
-              inst->filename, cf_section_lineno(cs), name, keybuf);
-
-       /*
-        *      And repeat some of the above code.
-        */
-       cp = cf_pair_find(cs, keybuf);
-       if (!cp) {
-               CONF_SECTION *subcs;
-
-               /*
-                *      Maybe it has a subsection, too.
-                */
-               subcs = cf_section_sub_find(cs, keybuf);
-               if (subcs) {
-                       return apply_subsection(inst, request, subcs, keybuf);
-               } /* it was a subsection */
-
-
-
-               DEBUG2("  rlm_protocol_filter: %s[%d]: subsection %s, rule not found, doing nothing.",
-                      inst->filename, cf_section_lineno(cs), name);
-               return RLM_MODULE_NOOP;
-       }
-
-       value = cf_pair_value(cp);
-       sense = str2sense(value);
-       if (sense < 0) {
-               radlog(L_ERR, "rlm_protocol_filter: %s[%d]: Unknwn directive %s",
-                      inst->filename, cf_pair_lineno(cp), value);
-               return RLM_MODULE_FAIL;
-       }
-
-       if (!sense) return RLM_MODULE_REJECT;
-
-       return RLM_MODULE_OK;
-}
-
-
-/*
- *     Authorize the user.
- */
-static int filter_authorize(void *instance, REQUEST *request)
-{
-       int sense;
-       VALUE_PAIR *vp;
-       CONF_SECTION *cs;
-       CONF_PAIR *cp;
-       char keybuf[1024];
-       rlm_protocol_filter_t *inst = instance;
-
-       radius_xlat(keybuf, sizeof(keybuf), inst->key, request, NULL);
-       if (!*keybuf) {
-               DEBUG2("  rlm_protocol_filter: key is empty");
-               return RLM_MODULE_NOOP;
-       }
-       DEBUG2("  rlm_protocol_filter: Using key %s", keybuf);
-
-       cs = cf_section_sub_find(inst->cs, keybuf);
-       if (!cs) {
-               DEBUG2("  rlm_protocol_filter: No such key in %s", inst->filename);
-               return RLM_MODULE_NOTFOUND;
-       }
-
-       /*
-        *      Walk through the list of attributes, seeing if they're
-        *      permitted/denied.
-        */
-       for (vp = request->packet->vps; vp != NULL; vp = vp->next) {
-               const char *value;
-               CONF_SECTION *subcs;
-
-               cp = cf_pair_find(cs, vp->name);
-               if (cp) {
-                       value = cf_pair_value(cp);
-
-                       sense = str2sense(value);
-                       if (sense < 0) {
-                               radlog(L_ERR, "rlm_protocol_filter %s[%d]: Unknown directive %s",
-                                      inst->filename,
-                                      cf_pair_lineno(cp),
-                                      value);
-                               return RLM_MODULE_FAIL;
-                       }
-
-                       if (!sense) return RLM_MODULE_REJECT;
-                       continue; /* was permitted */
-               } /* else no pair was found */
-
-               /*
-                *      Maybe it has a subsection
-                */
-               subcs = cf_section_sub_find(cs, vp->name);
-               if (subcs) {
-                       sense = apply_subsection(inst, request, subcs, vp->name);
-                       if ((sense == RLM_MODULE_OK) ||
-                           (sense == RLM_MODULE_NOOP)) {
-                               continue;
-                       }
-
-                       return sense;
-               } /* it was a subsection */
-
-               /*
-                *      Not found, must be "permit"
-                */
-       }
-
-       return RLM_MODULE_OK;
-}
-
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- *
- *     If the module needs to temporarily modify it's instantiation
- *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
- *     The server will then take care of ensuring that the module
- *     is single-threaded.
- */
-module_t rlm_protocol_filter = {
-       RLM_MODULE_INIT,
-       "protocol_filter",
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       filter_instantiate,             /* instantiation */
-       filter_detach,                  /* detach */
-       {
-               NULL,                   /* authentication */
-               filter_authorize,       /* authorization */
-               NULL,                   /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
-};
index eb0df8f..aa96770 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.8 .
+# From configure.in Revision: 1.7 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -907,7 +907,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1827,7 +1827,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1885,7 +1886,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2001,7 +2003,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2055,7 +2058,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2100,7 +2104,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2144,7 +2149,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2565,7 +2571,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2588,8 +2595,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2618,7 +2625,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2696,7 +2704,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2719,8 +2728,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2784,7 +2793,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2807,8 +2817,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2837,7 +2847,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2942,7 +2953,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2965,8 +2977,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -3825,6 +3837,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3863,12 +3880,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index ea34e0d..1e688e8 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_python.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_python])
@@ -69,7 +68,7 @@ if test x$with_[]modname != xno; then
                old_CFLAGS=$CFLAGS
                CFLAGS="$CFLAGS $PY_CFLAGS"
                smart_try_dir=$PY_INC_DIR
-               FR_SMART_CHECK_INCLUDE(Python.h)
+               AC_SMART_CHECK_INCLUDE(Python.h)
                CFLAGS=$old_CFLAGS
 
                if test "x$ac_cv_header_Python_h" = "xyes"; then
@@ -82,7 +81,7 @@ if test x$with_[]modname != xno; then
                old_LIBS=$LIBS
                LIBS="$LIBS $PY_LIB_LOC $PY_EXTRA_LIBS -lm"
                smart_try_dir=$PY_LIB_DIR
-               FR_SMART_CHECK_LIB(python${PY_VERSION}, Py_Initialize)
+               AC_SMART_CHECK_LIB(python${PY_VERSION}, Py_Initialize)
                LIBS=$old_LIBS
 
                eval t=\${ac_cv_lib_${sm_lib_safe}_${sm_func_safe}}
@@ -105,7 +104,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index aae1c83..51567b6 100644 (file)
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
 #
 # Example Python module for prepaid usage using MySQL
 
 # GNU General Public License for more details.
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 # Copyright 2002 Miguel A.L. Paraz <mparaz@mparaz.com>
 # Copyright 2002 Imperium Technology, Inc.
-#
-# $Id$
 
 import radiusd
 import MySQLdb
index 08a1aa0..08fe100 100644 (file)
@@ -1,4 +1,3 @@
-#! /usr/bin/env python
 #
 # Definitions for RADIUS programs
 #
@@ -7,8 +6,6 @@
 # This should only be used when testing modules.
 # Inside freeradius, the 'radiusd' Python module is created by the C module
 # and the definitions are automatically created.
-#
-# $Id$
 
 # from modules.h
 
index 3db91f0..2e24af5 100644 (file)
@@ -1,9 +1,6 @@
-#! /usr/bin/env python
 #
 # Python module test
 # Miguel A.L. Paraz <mparaz@mparaz.com>
-#
-# $Id$
 
 import radiusd
 
index 2669500..2a74554 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2002  Miguel A.L. Paraz <mparaz@mparaz.com>
  * Copyright 2002  Imperium Technology, Inc.
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include <Python.h>
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <Python.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+#define Pyx_BLOCK_THREADS       {PyGILState_STATE __gstate = PyGILState_Ensure();
+#define Pyx_UNBLOCK_THREADS     PyGILState_Release(__gstate);}
+
+
+
+static const char rcsid[] = "$Id$";
 
 /*
  *     Define a structure for our module configuration.
@@ -36,55 +47,43 @@ RCSID("$Id$")
  *     a lot cleaner to do so, and a pointer to the structure can
  *     be used as the instance handle.
  */
-typedef struct rlm_python_t {
-    /* Config section */
-
-    /* Names of modules */
-    char
-        *mod_instantiate,
-        *mod_authorize,
-       *mod_authenticate,
-       *mod_preacct,
-       *mod_accounting,
-       *mod_checksimul,
-       *mod_detach,
-
-    /* Names of functions */
-        *func_instantiate,
-        *func_authorize,
-       *func_authenticate,
-       *func_preacct,
-       *func_accounting,
-       *func_checksimul,
-       *func_detach;
-
-
-    /* End Config section */
-
-
-    /* Python objects for modules */
-    PyObject
-        *pModule_builtin,
-        *pModule_instantiate,
-        *pModule_authorize,
-       *pModule_authenticate,
-       *pModule_preacct,
-       *pModule_accounting,
-       *pModule_checksimul,
-       *pModule_detach,
-
-
-       /* Functions */
-
-       *pFunc_instantiate,
-       *pFunc_authorize,
-       *pFunc_authenticate,
-       *pFunc_preacct,
-       *pFunc_accounting,
-       *pFunc_checksimul,
-       *pFunc_detach;
-
-} rlm_python_t;
+
+struct rlm_python_t {
+        char    *mod_instantiate;
+        char    *mod_authorize;
+        char    *mod_authenticate;
+        char    *mod_preacct;
+        char    *mod_accounting;
+        char    *mod_checksimul;
+        char    *mod_detach;
+
+        /* Names of functions */
+        char    *func_instantiate;
+        char    *func_authorize;
+        char    *func_authenticate;
+        char    *func_preacct;
+        char    *func_accounting;
+        char    *func_checksimul;
+        char    *func_detach;
+
+        PyObject *pModule_instantiate;
+        PyObject *pModule_authorize;
+        PyObject *pModule_authenticate;
+        PyObject *pModule_preacct;
+        PyObject *pModule_accounting;
+        PyObject *pModule_checksimul;
+        PyObject *pModule_detach;
+
+        /* Functions */
+        PyObject *pFunc_instantiate;
+        PyObject *pFunc_authorize;
+        PyObject *pFunc_authenticate;
+        PyObject *pFunc_preacct;
+        PyObject *pFunc_accounting;
+        PyObject *pFunc_checksimul;
+        PyObject *pFunc_detach;
+};
+
 
 /*
  *     A mapping of configuration file names to internal variables.
@@ -95,52 +94,80 @@ typedef struct rlm_python_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "mod_instantiate",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_instantiate), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_instantiate), NULL,  NULL},
   { "func_instantiate",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_instantiate), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_instantiate), NULL,  NULL},
 
   { "mod_authorize",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_authorize), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_authorize), NULL,  NULL},
   { "func_authorize",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_authorize), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_authorize), NULL,  NULL},
 
   { "mod_authenticate",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_authenticate), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_authenticate), NULL,  NULL},
   { "func_authenticate",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_authenticate), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_authenticate), NULL,  NULL},
 
   { "mod_preacct",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_preacct), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_preacct), NULL,  NULL},
   { "func_preacct",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_preacct), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_preacct), NULL,  NULL},
 
   { "mod_accounting",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_accounting), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_accounting), NULL,  NULL},
   { "func_accounting",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_accounting), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_accounting), NULL,  NULL},
 
   { "mod_checksimul",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_checksimul), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_checksimul), NULL,  NULL},
   { "func_checksimul",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_checksimul), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_checksimul), NULL,  NULL},
 
   { "mod_detach",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, mod_detach), NULL,  NULL},
+    offsetof(struct rlm_python_t, mod_detach), NULL,  NULL},
   { "func_detach",  PW_TYPE_STRING_PTR,
-    offsetof(rlm_python_t, func_detach), NULL,  NULL},
+    offsetof(struct rlm_python_t, func_detach), NULL,  NULL},
 
 
   { NULL, -1, 0, NULL, NULL }          /* end the list */
 };
 
+static struct {
+        const char*     name;
+        int             value;
+} radiusd_constants[] = {
+        { "L_DBG",              L_DBG                   },
+        { "L_AUTH",             L_AUTH                  },
+        { "L_INFO",             L_INFO                  },
+        { "L_ERR",              L_ERR                   },
+        { "L_PROXY",            L_PROXY                 },
+        { "L_CONS",             L_CONS                  },
+        { "RLM_MODULE_REJECT",  RLM_MODULE_REJECT       },
+        { "RLM_MODULE_FAIL",    RLM_MODULE_FAIL         },
+        { "RLM_MODULE_OK",      RLM_MODULE_OK           },
+        { "RLM_MODULE_HANDLED", RLM_MODULE_HANDLED      },
+        { "RLM_MODULE_INVALID", RLM_MODULE_INVALID      },
+        { "RLM_MODULE_USERLOCK",RLM_MODULE_USERLOCK     },
+        { "RLM_MODULE_NOTFOUND",RLM_MODULE_NOTFOUND     },
+        { "RLM_MODULE_NOOP",    RLM_MODULE_NOOP         },
+        { "RLM_MODULE_UPDATED", RLM_MODULE_UPDATED      },
+        { "RLM_MODULE_NUMCODES",RLM_MODULE_NUMCODES     },
+        { NULL, 0 },
+};
+
+
+/* Let assume that radiusd module is only one since we have only one intepreter */
+
+static PyObject *radiusd_module = NULL;
+
 /*
  * radiusd Python functions
  */
 
 /* radlog wrapper */
-static PyObject *radlog_py(const PyObject *self, PyObject *args) {
+static PyObject *python_radlog(const PyObject *module, PyObject *args) {
     int status;
     char *msg;
 
@@ -148,389 +175,332 @@ static PyObject *radlog_py(const PyObject *self, PyObject *args) {
        return NULL;
     }
 
-    radlog(status, msg);
+    radlog(status, "%s", msg);
+    Py_INCREF(Py_None);
+
     return Py_None;
 }
 
 static PyMethodDef radiusd_methods[] = {
-    {"radlog", (PyCFunction)radlog_py, METH_VARARGS, "freeradius radlog()."},
+    {"radlog", (PyCFunction) &python_radlog, METH_VARARGS, "freeradius radlog()."},
     {NULL, NULL, 0, NULL}
 };
 
+static void python_error() {
+    PyObject        *pType = NULL;
+    PyObject        *pValue = NULL;
+    PyObject        *pTraceback = NULL;
+    PyObject        *pStr1 = NULL;
+    PyObject        *pStr2 = NULL;
 
-/* Extract string representation of Python error. */
-static void python_error(void) {
-    PyObject *pType, *pValue, *pTraceback, *pStr1, *pStr2;
+    Pyx_BLOCK_THREADS
 
     PyErr_Fetch(&pType, &pValue, &pTraceback);
-    pStr1 = PyObject_Str(pType);
-    pStr2 = PyObject_Str(pValue);
-
-    radlog(L_ERR, "%s: %s\n",
-          PyString_AsString(pStr1), PyString_AsString(pStr2));
+    if (pType == NULL || pValue == NULL)
+        goto failed;
+    if ((pStr1 = PyObject_Str(pType)) == NULL || (pStr2 = PyObject_Str(pValue)) == NULL)
+        goto failed;
+    radlog(L_ERR, "rlm_python:EXCEPT:%s: %s", PyString_AsString(pStr1), PyString_AsString(pStr2));
+
+failed:
+    Py_XDECREF(pStr1);
+    Py_XDECREF(pStr2);
+    Py_XDECREF(pType);
+    Py_XDECREF(pValue);
+    Py_XDECREF(pTraceback);
+
+    Pyx_UNBLOCK_THREADS
 }
 
-/* Tuple to value pair conversion */
-static void add_vp_tuple(VALUE_PAIR **vpp, PyObject *pValue,
-                        const char *function_name) {
-    int i, outertuplesize;
-    VALUE_PAIR *vp;
-
-    /* If the Python function gave us None for the tuple, then just return. */
-    if (pValue == Py_None) {
-       return;
-    }
-
-    if (!PyTuple_Check(pValue)) {
-       radlog(L_ERR, "%s: non-tuple passed", function_name);
-    }
-
-    /* Get the tuple size. */
-    outertuplesize = PyTuple_Size(pValue);
-
-    for (i = 0; i < outertuplesize; i++) {
-       PyObject *pTupleElement = PyTuple_GetItem(pValue, i);
-
-       if ((pTupleElement != NULL) &&
-           (PyTuple_Check(pTupleElement))) {
-
-           /* Check if it's a pair */
-           int tuplesize;
-
-           if ((tuplesize = PyTuple_Size(pTupleElement)) != 2) {
-               radlog(L_ERR, "%s: tuple element %d is a tuple "
-                      " of size %d. must be 2\n", function_name,
-                      i, tuplesize);
-           }
-           else {
-               PyObject *pString1, *pString2;
-
-               pString1 = PyTuple_GetItem(pTupleElement, 0);
-               pString2 = PyTuple_GetItem(pTupleElement, 1);
-
-               /* xxx PyString_Check does not compile here */
-               if  ((pString1 != NULL) &&
-                    (pString2 != NULL) &&
-                    PyObject_TypeCheck(pString1,&PyString_Type) &&
-                    PyObject_TypeCheck(pString2,&PyString_Type)) {
-
-
-                   const char *s1, *s2;
-
-                   /* pairmake() will convert and find any
-                    * errors in the pair.
-                    */
-
-                   s1 = PyString_AsString(pString1);
-                   s2 = PyString_AsString(pString2);
-
-                   if ((s1 != NULL) && (s2 != NULL)) {
-                       radlog(L_DBG, "%s: %s = %s ",
-                              function_name, s1, s2);
-
-                       /* xxx Might need to support other T_OP */
-                       vp = pairmake(s1, s2, T_OP_EQ);
-                       if (vp != NULL) {
-                           pairadd(vpp, vp);
-                           radlog(L_DBG, "%s: s1, s2 OK\n",
-                                  function_name);
-                       }
-                       else {
-                           radlog(L_DBG, "%s: s1, s2 FAILED\n",
-                                  function_name);
-                       }
-                   }
-                   else {
-                       radlog(L_ERR, "%s: string conv failed\n",
-                              function_name);
-                   }
-
-               }
-               else {
-                   radlog(L_ERR, "%s: tuple element %d must be "
-                          "(string, string)", function_name, i);
-               }
-           }
-       }
-       else {
-           radlog(L_ERR, "%s: tuple element %d is not a tuple\n",
-                  function_name, i);
-       }
-    }
-
-}
-
-/* This is the core Python function that the others wrap around.
- * Pass the value-pair print strings in a tuple.
- * xxx We're not checking the errors. If we have errors, what do we do?
- */
-
-static int python_function(REQUEST *request,
-                          PyObject *pFunc, const char *function_name)
+static int python_init()
 {
-#define BUF_SIZE 1024
-
-    char buf[BUF_SIZE];                /* same size as vp_print buffer */
-
-    VALUE_PAIR *vp;
-
-    PyObject *pValue, *pValuePairContainer, **pValueHolder, **pValueHolderPtr;
-    int i, n_tuple, return_value;
-
-    /* Return with "OK, continue" if the function is not defined. */
-    if (pFunc == NULL) {
-       return RLM_MODULE_OK;
-    }
-
-    /* Default return value is "OK, continue" */
-    return_value = RLM_MODULE_OK;
-
-    /* We will pass a tuple containing (name, value) tuples
-     * We can safely use the Python function to build up a tuple,
-     * since the tuple is not used elsewhere.
-     *
-     * Determine the size of our tuple by walking through the packet.
-     * If request is NULL, pass None.
-     */
-    n_tuple = 0;
-
-    if (request != NULL) {
-       for (vp = request->packet->vps; vp; vp = vp->next) {
-           n_tuple++;
-       }
-    }
-
-    /* Create the tuple and a holder for the pointers, so that we can
-     * decref more efficiently later without the overhead of reading
-     * the tuple.
-     *
-     * We use malloc() instead of the Python memory allocator since we
-     * are not embedded.
-     */
-
-    if (NULL == (pValueHolder = pValueHolderPtr =
-                malloc(sizeof(PyObject *) * n_tuple))) {
+    int i;
 
-       radlog(L_ERR, "%s: malloc of %d bytes failed\n",
-              function_name, sizeof(PyObject *) * n_tuple);
+    Py_SetProgramName("radiusd");
 
-       return -1;
-    }
-
-    if (n_tuple == 0) {
-       pValuePairContainer = Py_None;
-    }
-    else {
-       pValuePairContainer = PyTuple_New(n_tuple);
-
-       i = 0;
-       for (vp = request->packet->vps; vp; vp = vp->next) {
-           PyObject *pValuePair, *pString1, *pString2;
-
-           /* The inside tuple has two only: */
-           pValuePair = PyTuple_New(2);
+    Py_Initialize();
 
-           /* The name. logic from vp_prints, lib/print.c */
-           if (vp->flags.has_tag) {
-               snprintf(buf, BUF_SIZE, "%s:%d", vp->name, vp->flags.tag);
-           }
-           else {
-               strcpy(buf, vp->name);
-           }
+    PyEval_InitThreads(); // This also grabs a lock
 
-           pString1 = PyString_FromString(buf);
-           PyTuple_SetItem(pValuePair, 0, pString1);
+    if ((radiusd_module = Py_InitModule3("radiusd", radiusd_methods, "FreeRADIUS Module.")) == NULL)
+        goto failed;
 
+    for (i = 0; radiusd_constants[i].name; i++)
+        if ((PyModule_AddIntConstant(radiusd_module, radiusd_constants[i].name, radiusd_constants[i].value)) < 0)
+            goto failed;
 
-           /* The value. Use delimiter - don't know what that means */
-           vp_prints_value(buf, sizeof(buf), vp, 1);
-           pString2 = PyString_FromString(buf);
-           PyTuple_SetItem(pValuePair, 1, pString2);
+    PyEval_ReleaseLock(); // Drop lock grabbed by InitThreads
 
-           /* Put the tuple inside the container */
-           PyTuple_SetItem(pValuePairContainer, i++, pValuePair);
-
-           /* Store the pointer in our malloc() storage */
-           *pValueHolderPtr++ = pValuePair;
-       }
-    }
+    radlog(L_DBG, "python_init done");
 
+    return 0;
 
-    /* Call Python function.
-     */
-
-    if (pFunc && PyCallable_Check(pFunc)) {
-       PyObject *pArgs;
-
-       /* call the function with a singleton tuple containing the
-        * container tuple.
-        */
-
-       if ((pArgs = PyTuple_New(1)) == NULL) {
-           radlog(L_ERR, "%s: could not create tuple", function_name);
-           return -1;
-       }
-       if ((PyTuple_SetItem(pArgs, 0, pValuePairContainer)) != 0) {
-           radlog(L_ERR, "%s: could not set tuple item", function_name);
-           return -1;
-       }
-
-       if ((pValue = PyObject_CallObject(pFunc, pArgs)) == NULL) {
-           radlog(L_ERR, "%s: function call failed", function_name);
-           python_error();
-           return -1;
-       }
-
-       /* The function returns either:
-        *  1. tuple containing the integer return value,
-        *  then the integer reply code (or None to not set),
-        *  then the string tuples to build the reply with.
-        *     (returnvalue, (p1, s1), (p2, s2))
-        *
-        *  2. the function return value alone
-        *
-        *  3. None - default return value is set
-        *
-        * xxx This code is messy!
-        */
-
-       if (PyTuple_Check(pValue)) {
-           PyObject *pTupleInt;
-
-           if (PyTuple_Size(pValue) != 3) {
-               radlog(L_ERR, "%s: tuple must be " \
-                      "(return, replyTuple, configTuple)",
-                      function_name);
-
-           }
-           else {
-               pTupleInt = PyTuple_GetItem(pValue, 0);
-
-               if ((pTupleInt == NULL) || !PyInt_Check(pTupleInt)) {
-                   radlog(L_ERR, "%s: first tuple element not an integer",
-                          function_name);
-               }
-               else {
-                   /* Now have the return value */
-                   return_value = PyInt_AsLong(pTupleInt);
-
-                   /* Reply item tuple */
-                   add_vp_tuple(&request->reply->vps,
-                                PyTuple_GetItem(pValue, 1), function_name);
-
-                   /* Config item tuple */
-                   add_vp_tuple(&request->config_items,
-                                PyTuple_GetItem(pValue, 2), function_name);
-               }
-           }
-       }
-       else if (PyInt_Check(pValue)) {
-           /* Just an integer */
-           return_value = PyInt_AsLong(pValue);
-       }
-       else if (pValue == Py_None) {
-           /* returned 'None', return value defaults to "OK, continue." */
-           return_value = RLM_MODULE_OK;
-       }
-       else {
-           /* Not tuple or None */
-           radlog(L_ERR, "%s function did not return a tuple or None\n",
-                  function_name);
-       }
-
-
-       /* Decrease reference counts for the argument and return tuple */
-       Py_DECREF(pArgs);
-       Py_DECREF(pValue);
-    }
+failed:
+    python_error();
+    Py_Finalize();
+    return -1;
+}
 
-    /* Decrease reference count for the tuples passed, the
-     * container tuple, and the return value.
-     */
+static int python_destroy() {
+    Pyx_BLOCK_THREADS
+    Py_XDECREF(radiusd_module);
+    Py_Finalize();
+    Pyx_UNBLOCK_THREADS
 
-    pValueHolderPtr = pValueHolder;
-    i = n_tuple;
-    while (i--) {
-       /* Can't write as pValueHolderPtr since Py_DECREF is a macro */
-       Py_DECREF(*pValueHolderPtr);
-       pValueHolderPtr++;
-    }
-    free(pValueHolder);
-    Py_DECREF(pValuePairContainer);
+    return 0;
+}
 
-    /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
+static void python_vptuple(VALUE_PAIR **vpp, PyObject *pValue, const char *funcname) {
+        int             i;
+        int             tuplesize;
+        VALUE_PAIR      *vp;
+
+        /* If the Python function gave us None for the tuple, then just return. */
+        if (pValue == Py_None)
+                return;
+
+        if (!PyTuple_CheckExact(pValue)) {
+                radlog(L_ERR, "rlm_python:%s: non-tuple passed", funcname);
+                return;
+        }
+        /* Get the tuple tuplesize. */
+        tuplesize = PyTuple_GET_SIZE(pValue);
+        for (i = 0; i < tuplesize; i++) {
+                PyObject *pTupleElement = PyTuple_GET_ITEM(pValue, i);
+                PyObject *pStr1;
+                PyObject *pStr2;
+                int pairsize;
+                const char *s1;
+                const char *s2;
+
+                if (!PyTuple_CheckExact(pTupleElement)) {
+                        radlog(L_ERR, "rlm_python:%s: tuple element %d is not a tuple", funcname, i);
+                        continue;
+                }
+                /* Check if it's a pair */
+                if ((pairsize = PyTuple_GET_SIZE(pTupleElement)) != 2) {
+                        radlog(L_ERR, "rlm_python:%s: tuple element %d is a tuple of size %d. Must be 2", funcname, i, pairsize);
+                        continue;
+                }
+                pStr1 = PyTuple_GET_ITEM(pTupleElement, 0);
+                pStr2 = PyTuple_GET_ITEM(pTupleElement, 1);
+                if ((!PyString_CheckExact(pStr1)) || (!PyString_CheckExact(pStr2))) {
+                        radlog(L_ERR, "rlm_python:%s: tuple element %d must be as (str, str)", funcname, i);
+                        continue;
+                }
+                s1 = PyString_AsString(pStr1);
+                s2 = PyString_AsString(pStr2);
+                /* xxx Might need to support other T_OP */
+                vp = pairmake(s1, s2, T_OP_EQ);
+                if (vp != NULL) {
+                        pairadd(vpp, vp);
+                        radlog(L_DBG, "rlm_python:%s: '%s' = '%s'", funcname, s1, s2);
+                } else {
+                        radlog(L_DBG, "rlm_python:%s: Failed: '%s' = '%s'", funcname, s1, s2);
+                }
+        }
+}
 
-    /* Free pairs if we are rejecting.
-     * xxx Shouldn't the core do that?
-     */
 
-    if ((return_value == RLM_MODULE_REJECT) && (request != NULL)) {
-       pairfree(&(request->reply->vps));
-    }
+/* This is the core Python function that the others wrap around.
+ * Pass the value-pair print strings in a tuple.
+ * xxx We're not checking the errors. If we have errors, what do we do?
+ */
 
-    /* Return the specified by the Python module */
-    return return_value;
+static int python_function(REQUEST *request, PyObject *pFunc, const char *funcname) {
+        char            buf[1024];
+        VALUE_PAIR      *vp;
+        PyObject        *pRet = NULL;
+        PyObject        *pArgs = NULL;
+        int             tuplelen;
+        int             ret;
+
+       PyGILState_STATE gstate;
+
+        /* Return with "OK, continue" if the function is not defined. */
+        if (pFunc == NULL)
+                return RLM_MODULE_OK;
+
+        /* Default return value is "OK, continue" */
+        ret = RLM_MODULE_OK;
+
+        /* We will pass a tuple containing (name, value) tuples
+         * We can safely use the Python function to build up a tuple,
+         * since the tuple is not used elsewhere.
+         *
+         * Determine the size of our tuple by walking through the packet.
+         * If request is NULL, pass None.
+         */
+        tuplelen = 0;
+        if (request != NULL) {
+                for (vp = request->packet->vps; vp; vp = vp->next)
+                        tuplelen++;
+        }
+
+        gstate = PyGILState_Ensure();
+
+        if (tuplelen == 0) {
+                Py_INCREF(Py_None);
+                pArgs = Py_None;
+        } else {
+                int     i = 0;
+                if ((pArgs = PyTuple_New(tuplelen)) == NULL)
+                        goto failed;
+                for (vp = request->packet->vps; vp != NULL; vp = vp->next, i++) {
+                        PyObject *pPair;
+                        PyObject *pStr;
+                        /* The inside tuple has two only: */
+                        if ((pPair = PyTuple_New(2)) == NULL)
+                                goto failed;
+                        /* Put the tuple inside the container */
+                        PyTuple_SET_ITEM(pArgs, i, pPair);
+                        /* The name. logic from vp_prints, lib/print.c */
+                        if (vp->flags.has_tag)
+                                snprintf(buf, sizeof(buf), "%s:%d", vp->name, vp->flags.tag);
+                        else
+                                strcpy(buf, vp->name);
+                        if ((pStr = PyString_FromString(buf)) == NULL)
+                                goto failed;
+                        PyTuple_SET_ITEM(pPair, 0, pStr);
+                        vp_prints_value(buf, sizeof(buf), vp, 1);
+                        if ((pStr = PyString_FromString(buf)) == NULL)
+                                goto failed;
+                        PyTuple_SET_ITEM(pPair, 1, pStr);
+                }
+        }
+
+        /* Call Python function. */
+        pRet = PyObject_CallFunctionObjArgs(pFunc, pArgs, NULL);
+
+       if (pRet == NULL)
+                goto failed;
+
+        if (request == NULL)
+                goto okay;
+        /* The function returns either:
+         *  1. tuple containing the integer return value,
+         *  then the integer reply code (or None to not set),
+         *  then the string tuples to build the reply with.
+         *  (returnvalue, (p1, s1), (p2, s2))
+         *
+         *  2. the function return value alone
+         *
+         *  3. None - default return value is set
+         *
+         * xxx This code is messy!
+         */
+        if (PyTuple_CheckExact(pRet)) {
+                PyObject *pTupleInt;
+
+                if (PyTuple_GET_SIZE(pRet) != 3) {
+                        radlog(L_ERR, "rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname);
+                        goto failed;
+                }
+                pTupleInt = PyTuple_GET_ITEM(pRet, 0);
+                if (!PyInt_CheckExact(pTupleInt)) {
+                        radlog(L_ERR, "rlm_python:%s: first tuple element not an integer", funcname);
+                        goto failed;
+                }
+                /* Now have the return value */
+                ret = PyInt_AsLong(pTupleInt);
+                /* Reply item tuple */
+                python_vptuple(&request->reply->vps, PyTuple_GET_ITEM(pRet, 1), funcname);
+                /* Config item tuple */
+                python_vptuple(&request->config_items, PyTuple_GET_ITEM(pRet, 2), funcname);
+        } else
+        if (PyInt_CheckExact(pRet)) {
+                /* Just an integer */
+                ret = PyInt_AsLong(pRet);
+        } else
+        if (pRet == Py_None) {
+                /* returned 'None', return value defaults to "OK, continue." */
+                ret = RLM_MODULE_OK;
+        } else {
+                /* Not tuple or None */
+                radlog(L_ERR, "rlm_python:%s: function did not return a tuple or None", funcname);
+                goto failed;
+        }
+        if (ret == RLM_MODULE_REJECT && request != NULL)
+                pairfree(&request->reply->vps);
+okay:
+        Py_DECREF(pArgs);
+        Py_DECREF(pRet);
+       PyGILState_Release(gstate);
+        return ret;
+failed:
+        python_error();
+        Py_XDECREF(pArgs);
+        Py_XDECREF(pRet);
+        PyGILState_Release(gstate);
+
+        return -1;
 }
 
-
-static struct varlookup {
-       const char*     name;
-       int             value;
-} constants[] = {
-       { "L_DBG",              L_DBG                   },
-       { "L_AUTH",             L_AUTH                  },
-       { "L_INFO",             L_INFO                  },
-       { "L_ERR",              L_ERR                   },
-       { "L_PROXY",            L_PROXY                 },
-       { "L_CONS",             L_CONS                  },
-       { "RLM_MODULE_REJECT",  RLM_MODULE_REJECT       },
-       { "RLM_MODULE_FAIL",    RLM_MODULE_FAIL         },
-       { "RLM_MODULE_OK",      RLM_MODULE_OK           },
-       { "RLM_MODULE_HANDLED", RLM_MODULE_HANDLED      },
-       { "RLM_MODULE_INVALID", RLM_MODULE_INVALID      },
-       { "RLM_MODULE_USERLOCK",RLM_MODULE_USERLOCK     },
-       { "RLM_MODULE_NOTFOUND",RLM_MODULE_NOTFOUND     },
-       { "RLM_MODULE_NOOP",    RLM_MODULE_NOOP         },
-       { "RLM_MODULE_UPDATED", RLM_MODULE_UPDATED      },
-       { "RLM_MODULE_NUMCODES",RLM_MODULE_NUMCODES     },
-       { NULL, 0 },
-};
-
 /*
  * Import a user module and load a function from it
  */
-static int load_python_function(const char* module, const char* func,
-                               PyObject** pyModule, PyObject** pyFunc) {
-
-    if ((module==NULL) || (func==NULL)) {
-       *pyFunc=NULL;
-       *pyModule=NULL;
-    } else {
-       PyObject *pName;
-
-       pName = PyString_FromString(module);
-       Py_INCREF(pName);
-       *pyModule = PyImport_Import(pName);
-       Py_DECREF(pName);
-       if (*pyModule != NULL) {
-           PyObject *pDict;
-
-           pDict = PyModule_GetDict(*pyModule);
-           /* pDict: borrowed reference */
-
-           *pyFunc = PyDict_GetItemString(pDict, func);
-           /* pFunc: Borrowed reference */
-       } else {
-           python_error();
-
-           radlog(L_ERR, "Failed to import python module \"%s\"\n", module);
-           return -1;
-       }
-    }
 
-    return 0;
+static int python_load_function(char *module, const char *func, PyObject **pModule, PyObject **pFunc) {
+        const char      funcname[] = "python_load_function";
+        PyGILState_STATE gstate;
+
+        *pFunc = NULL;
+        *pModule = NULL;
+        gstate = PyGILState_Ensure();
+
+        if (module != NULL && func != NULL) {
+                if ((*pModule = PyImport_ImportModule(module)) == NULL) {
+                        radlog(L_ERR, "rlm_python:%s: module '%s' is not found", funcname, module);
+                        goto failed;
+                }
+                if ((*pFunc = PyObject_GetAttrString(*pModule, func)) == NULL) {
+                        radlog(L_ERR, "rlm_python:%s: function '%s.%s' is not found", funcname, module, func);
+                        goto failed;
+                }
+                if (!PyCallable_Check(*pFunc)) {
+                        radlog(L_ERR, "rlm_python:%s: function '%s.%s' is not callable", funcname, module, func);
+                        goto failed;
+                }
+        }
+       PyGILState_Release(gstate);
+        return 0;
+failed:
+        python_error();
+        radlog(L_ERR, "rlm_python:%s: failed to import python function '%s.%s'", funcname, module, func);
+        Py_XDECREF(*pFunc);
+        *pFunc = NULL;
+        Py_XDECREF(*pModule);
+        PyGILState_Release(gstate);
+        *pModule = NULL;
+        return -1;
 }
 
+static void python_objclear(PyObject **ob) {
+        if (*ob != NULL) {
+               Pyx_BLOCK_THREADS
+                Py_DECREF(*ob);
+                Pyx_UNBLOCK_THREADS
+                *ob = NULL;
+        }
+}
+
+static void python_instance_clear(struct rlm_python_t *data) {
+        python_objclear(&data->pFunc_instantiate);
+        python_objclear(&data->pFunc_authorize);
+        python_objclear(&data->pFunc_authenticate);
+        python_objclear(&data->pFunc_preacct);
+        python_objclear(&data->pFunc_accounting);
+        python_objclear(&data->pFunc_checksimul);
+        python_objclear(&data->pFunc_detach);
+
+        python_objclear(&data->pModule_instantiate);
+        python_objclear(&data->pModule_authorize);
+        python_objclear(&data->pModule_authenticate);
+        python_objclear(&data->pModule_preacct);
+        python_objclear(&data->pModule_accounting);
+        python_objclear(&data->pModule_checksimul);
+        python_objclear(&data->pModule_detach);
+}
 
 /*
  *     Do any per-module initialization that is separate to each
@@ -543,112 +513,94 @@ static int load_python_function(const char* module, const char* func,
  *     in *instance otherwise put a null pointer there.
  *
  */
-static int python_instantiate(CONF_SECTION *conf, void **instance)
-{
-    rlm_python_t *data;
-    PyObject *module;
-    int idx;
-
-    /*
-     * Initialize Python interpreter. Fatal error if this fails.
-     */
-    Py_Initialize();
-
-    /*
-     * Set up a storage area for instance data
-     */
-    data = rad_malloc(sizeof(*data));
-    if (!data) {
-      return -1;
-    }
-    memset(data, 0, sizeof(*data));
-
-    /*
-        *      If the configuration parameters can't be parsed, then
-        *      fail.
-        */
-    if (cf_section_parse(conf, data, module_config) < 0) {
-       free(data);
-       return -1;
-    }
-
-
-    /*
-     * Setup our 'radiusd' module.
-     */
-
-    /* Code */
-    if ((module = data->pModule_builtin =
-        Py_InitModule3("radiusd", radiusd_methods,
-                       "FreeRADIUS Module.")) == NULL) {
-
-       radlog(L_ERR, "Python Py_InitModule3 failed");
-       free(data);
-       return -1;
-    }
-
-    /*
-     * Load constants into module
-     */
-    for (idx=0; constants[idx].name; idx++)
-       if ((PyModule_AddIntConstant(module, constants[idx].name, constants[idx].value)) == -1) {
 
-           radlog(L_ERR, "Python AddIntConstant failed");
-       }
-
-
-    /*
-     * Import user modules.
-     */
-
-    if (load_python_function(data->mod_instantiate, data->func_instantiate,
-               &data->pModule_instantiate, &data->pFunc_instantiate)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
-
-    if (load_python_function(data->mod_authenticate, data->func_authenticate,
-               &data->pModule_authenticate, &data->pFunc_authenticate)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
-
-    if (load_python_function(data->mod_authorize, data->func_authorize,
-               &data->pModule_authorize, &data->pFunc_authorize)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
-
-    if (load_python_function(data->mod_preacct, data->func_preacct,
-               &data->pModule_preacct, &data->pFunc_preacct)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
-
-    if (load_python_function(data->mod_accounting, data->func_accounting,
-               &data->pModule_accounting, &data->pFunc_accounting)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
+static int python_instantiate(CONF_SECTION *conf, void **instance) {
+        struct rlm_python_t    *data = NULL;
+
+        /*
+         *      Set up a storage area for instance data
+         */
+        if ((data = malloc(sizeof(*data))) == NULL)
+                return -1;
+        bzero(data, sizeof(*data));
+
+        /*
+         *      If the configuration parameters can't be parsed, then
+         *      fail.
+         */
+        if (cf_section_parse(conf, data, module_config) < 0) {
+                free(data);
+                return -1;
+        }
+
+        /*
+         * Import user modules.
+         */
+        if (python_load_function(data->mod_instantiate,
+                                data->func_instantiate,
+                                &data->pModule_instantiate,
+                                &data->pFunc_instantiate) < 0)
+                goto failed;
+
+        if (python_load_function(data->mod_authenticate,
+                                data->func_authenticate,
+                                &data->pModule_authenticate,
+                                &data->pFunc_authenticate) < 0)
+                goto failed;
+
+        if (python_load_function(data->mod_authorize,
+                                data->func_authorize,
+                                &data->pModule_authorize,
+                                &data->pFunc_authorize) < 0)
+                goto failed;
+
+        if (python_load_function(data->mod_preacct,
+                                data->func_preacct,
+                                &data->pModule_preacct,
+                                &data->pFunc_preacct) < 0)
+                goto failed;
+
+        if (python_load_function(data->mod_accounting,
+                                data->func_accounting,
+                                &data->pModule_accounting,
+                                &data->pFunc_accounting) < 0)
+                goto failed;
+
+        if (python_load_function(data->mod_checksimul,
+                                data->func_checksimul,
+                                &data->pModule_checksimul,
+                                &data->pFunc_checksimul) < 0)
+                goto failed;
+
+        if (python_load_function(data->mod_detach,
+                                data->func_detach,
+                                &data->pModule_detach,
+                                &data->pFunc_detach) < 0)
+                goto failed;
+
+        *instance = data;
+        /* Call the instantiate function.  No request.  Use the return value. */
+
+        return python_function(NULL, data->pFunc_instantiate, "instantiate");
+failed:
+        python_error();
+        python_instance_clear(data);
+        return -1;
+}
 
-    if (load_python_function(data->mod_checksimul, data->func_checksimul,
-               &data->pModule_checksimul, &data->pFunc_checksimul)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
+static int python_detach(void *instance) {
+        struct rlm_python_t    *data = (struct rlm_python_t *) instance;
+        int             ret;
 
-    if (load_python_function(data->mod_detach, data->func_detach,
-               &data->pModule_detach, &data->pFunc_detach)==-1) {
-       /* TODO: check if we need to cleanup data */
-       return -1;
-    }
+        ret = python_function(NULL, data->pFunc_detach, "detach");
 
-    *instance=data;
+        python_instance_clear(data);
 
-    /* Call the instantiate function.  No request.  Use the return value. */
-    return python_function(NULL, data->pFunc_instantiate, "instantiate");
+        free(data);
+        return ret;
 }
 
+
 /* Wrapper functions */
 static int python_authorize(void *instance, REQUEST *request)
 {
@@ -690,57 +642,6 @@ static int python_checksimul(void *instance, REQUEST *request)
 }
 
 
-static int python_detach(void *instance)
-{
-    int return_value;
-
-    /* Default return value is failure */
-    return_value = -1;
-
-    if (((rlm_python_t *)instance)->pFunc_detach &&
-       PyCallable_Check(((rlm_python_t *)instance)->pFunc_detach)) {
-
-       PyObject *pArgs, *pValue;
-
-       /* call the function with an empty tuple */
-
-       pArgs = PyTuple_New(0);
-       pValue = PyObject_CallObject(((rlm_python_t *)instance)->pFunc_detach,
-                                    pArgs);
-
-       if (pValue == NULL) {
-           python_error();
-           return -1;
-       }
-       else {
-           if (!PyInt_Check(pValue)) {
-               radlog(L_ERR, "detach: return value not an integer");
-           }
-           else {
-               return_value = PyInt_AsLong(pValue);
-           }
-       }
-
-       /* Decrease reference counts for the argument and return tuple */
-       Py_DECREF(pArgs);
-       Py_DECREF(pValue);
-    }
-
-    free(instance);
-
-#if 0
-    /* xxx test delete module object so it will be reloaded later.
-     * xxx useless since we can't SIGHUP reliably, anyway.
-     */
-    PyObject_Del(((struct rlm_python_t *)instance)->pModule_accounting);
-#endif
-
-    radlog(L_DBG, "python_detach done");
-
-    /* Return the specified by the Python module */
-    return return_value;
-}
-
 /*
  *     The module name should be the only globally exported symbol.
  *     That is, everything else should be 'static'.
@@ -751,11 +652,10 @@ static int python_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_python = {
-       RLM_MODULE_INIT,
        "python",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       python_init,                    /* initialization */
        python_instantiate,             /* instantiation */
-       python_detach,                  /* detach */
        {
                python_authenticate,    /* authentication */
                python_authorize,       /* authorization */
@@ -766,4 +666,6 @@ module_t rlm_python = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       python_detach,                  /* detach */
+       python_destroy,                         /* destroy */
 };
index c66094f..ff080a0 100644 (file)
@@ -1,49 +1,12 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+*/
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
 
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/mman.h> header file. */
+/* Define if you have the <sys/mman.h> header file.  */
 #undef HAVE_SYS_MMAN_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
index f4c519d..6d17f9a 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.2 .
+# From configure.in Revision: 1.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -938,7 +938,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1858,7 +1858,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1916,7 +1917,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2032,7 +2034,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2086,7 +2089,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2131,7 +2135,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2175,7 +2180,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2498,7 +2504,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2668,7 +2675,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2735,7 +2743,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3649,6 +3658,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3687,12 +3701,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 52d0084..0ef48ab 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_radutmp.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_radutmp])
index 861f0c3..c0a44a9 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * FIXME add copyrights
  */
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/radutmp.h>
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
+#include       "autoconf.h"
 
+#include       <sys/types.h>
+#include       <stdio.h>
+#include       <string.h>
+#include       <stdlib.h>
+#include       <unistd.h>
 #include       <fcntl.h>
+#include       <time.h>
+#include       <errno.h>
 #include        <limits.h>
 
 #include "config.h"
 
+#include       "radiusd.h"
+#include       "radutmp.h"
+#include       "modules.h"
+
 #define LOCK_LEN sizeof(struct radutmp)
 
 static const char porttypes[] = "ASITX";
@@ -59,7 +64,7 @@ typedef struct rlm_radutmp_t {
        int             callerid_ok;
 } rlm_radutmp_t;
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        { "filename", PW_TYPE_STRING_PTR,
          offsetof(rlm_radutmp_t,filename), NULL,  RADUTMP },
        { "username", PW_TYPE_STRING_PTR,
@@ -108,6 +113,8 @@ static int radutmp_detach(void *instance)
                next = p->next;
                free(p);
        }
+       if (inst->filename) free(inst->filename);
+       if (inst->username) free(inst->username);
        free(inst);
        return 0;
 }
@@ -200,11 +207,6 @@ static int radutmp_accounting(void *instance, REQUEST *request)
        NAS_PORT        *cache;
        int             r;
 
-       if (request->packet->src_ipaddr.af != AF_INET) {
-               DEBUG("rlm_radutmp: IPv6 not supported!");
-               return RLM_MODULE_NOOP;
-       }
-
        /*
         *      Which type is this.
         */
@@ -212,7 +214,7 @@ static int radutmp_accounting(void *instance, REQUEST *request)
                radlog(L_ERR, "rlm_radutmp: No Accounting-Status-Type record.");
                return RLM_MODULE_NOOP;
        }
-       status = vp->vp_integer;
+       status = vp->lvalue;
 
        /*
         *      Look for weird reboot packets.
@@ -232,11 +234,11 @@ static int radutmp_accounting(void *instance, REQUEST *request)
                int check2 = 0;
 
                if ((vp = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME))
-                    == NULL || vp->vp_date == 0)
+                    == NULL || vp->lvalue == 0)
                        check1 = 1;
                if ((vp = pairfind(request->packet->vps, PW_ACCT_SESSION_ID))
                     != NULL && vp->length == 8 &&
-                    memcmp(vp->vp_strvalue, "00000000", 8) == 0)
+                    memcmp(vp->strvalue, "00000000", 8) == 0)
                        check2 = 1;
                if (check1 == 0 || check2 == 0) {
 #if 0 /* Cisco sometimes sends START records without username. */
@@ -264,22 +266,22 @@ static int radutmp_accounting(void *instance, REQUEST *request)
                switch (vp->attribute) {
                        case PW_LOGIN_IP_HOST:
                        case PW_FRAMED_IP_ADDRESS:
-                               framed_address = vp->vp_ipaddr;
-                               ut.framed_address = vp->vp_ipaddr;
+                               framed_address = vp->lvalue;
+                               ut.framed_address = vp->lvalue;
                                break;
                        case PW_FRAMED_PROTOCOL:
-                               protocol = vp->vp_integer;
+                               protocol = vp->lvalue;
                                break;
                        case PW_NAS_IP_ADDRESS:
-                               nas_address = vp->vp_ipaddr;
-                               ut.nas_address = vp->vp_ipaddr;
+                               nas_address = vp->lvalue;
+                               ut.nas_address = vp->lvalue;
                                break;
                        case PW_NAS_PORT:
-                               ut.nas_port = vp->vp_integer;
+                               ut.nas_port = vp->lvalue;
                                port_seen = 1;
                                break;
                        case PW_ACCT_DELAY_TIME:
-                               ut.delay = vp->vp_integer;
+                               ut.delay = vp->lvalue;
                                break;
                        case PW_ACCT_SESSION_ID:
                                /*
@@ -293,21 +295,21 @@ static int radutmp_accounting(void *instance, REQUEST *request)
                                 *      Compensate.
                                 */
                                if (vp->length > 0 &&
-                                   vp->vp_strvalue[vp->length - 1] == 0)
+                                   vp->strvalue[vp->length - 1] == 0)
                                        off--;
                                if (off < 0) off = 0;
-                               memcpy(ut.session_id, vp->vp_strvalue + off,
+                               memcpy(ut.session_id, vp->strvalue + off,
                                        sizeof(ut.session_id));
                                break;
                        case PW_NAS_PORT_TYPE:
-                               if (vp->vp_integer <= 4)
-                                       ut.porttype = porttypes[vp->vp_integer];
-                               nas_port_type = vp->vp_integer;
+                               if (vp->lvalue <= 4)
+                                       ut.porttype = porttypes[vp->lvalue];
+                               nas_port_type = vp->lvalue;
                                break;
                        case PW_CALLING_STATION_ID:
                                if(inst->callerid_ok)
-                                       strlcpy(ut.caller_id,
-                                               (char *)vp->vp_strvalue,
+                                       strNcpy(ut.caller_id,
+                                               (char *)vp->strvalue,
                                                sizeof(ut.caller_id));
                                break;
                }
@@ -318,31 +320,32 @@ static int radutmp_accounting(void *instance, REQUEST *request)
         *      originator's IP address.
         */
        if (nas_address == 0) {
-               nas_address = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
+               nas_address = request->packet->src_ipaddr;
                ut.nas_address = nas_address;
-               nas = client_name_old(&request->packet->src_ipaddr); /* MUST be a valid client */
+               nas = client_name(nas_address); /* MUST be a valid client */
 
-       } else if (request->packet->src_ipaddr.ipaddr.ip4addr.s_addr == nas_address) {          /* might be a client, might not be. */
+       } else {                /* might be a client, might not be. */
                RADCLIENT *cl;
 
                /*
                 *      Hack like 'client_name()', but with sane
                 *      fall-back.
                 */
-               cl = client_find_old(&request->packet->src_ipaddr);
-               if (!cl) rad_assert(0 == 1); /* WTF? */
-               if (cl->shortname && cl->shortname[0]) {
-                       nas = cl->shortname;
+               cl = client_find(nas_address);
+               if (cl) {
+                       if (cl->shortname[0]) {
+                               nas = cl->shortname;
+                       } else {
+                               nas = cl->longname;
+                       }
                } else {
-                       nas = cl->longname;
+                       /*
+                        *      The NAS isn't a client, it's behind
+                        *      a proxy server.  In that case, just
+                        *      get the IP address.
+                        */
+                       nas = ip_ntoa(ip_name, nas_address);
                }
-       } else {
-               /*
-                *      The NAS isn't a client, it's behind
-                *      a proxy server.  In that case, just
-                *      get the IP address.
-                */
-               nas = ip_ntoa(ip_name, nas_address);
        }
 
        /*
@@ -403,7 +406,7 @@ static int radutmp_accounting(void *instance, REQUEST *request)
        /*
         *  Copy the previous translated user name.
         */
-       strlcpy(ut.login, buffer, RUT_NAMESIZE);
+       strncpy(ut.login, buffer, RUT_NAMESIZE);
 
        /*
         *      Perhaps we don't want to store this record into
@@ -586,6 +589,7 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
        rlm_radutmp_t   *inst = instance;
        char            login[256];
        char            filename[1024];
+       ssize_t         read_size;
 
        /*
         *      Get the filename, via xlat.
@@ -626,7 +630,7 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
        /*
         *      Loop over utmp, counting how many people MAY be logged in.
         */
-       while (read(fd, &u, sizeof(u)) == sizeof(u)) {
+       while ((read_size = read(fd, &u, sizeof(u))) == sizeof(u)) {
                if (((strncmp(login, u.login, RUT_NAMESIZE) == 0) ||
                     (!inst->case_sensitive &&
                      (strncasecmp(login, u.login, RUT_NAMESIZE) == 0))) &&
@@ -635,6 +639,13 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
                }
        }
 
+       if (read_size < 0) {
+               radlog(L_ERR, "rlm_radutmp: Error reading %s: %s",
+                      filename, strerror(errno));
+               close(fd);
+               return RLM_MODULE_FAIL;
+       }
+
        /*
         *      The number of users logged in is OK,
         *      OR, we've been told to not check the NAS.
@@ -650,9 +661,9 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
         *      Setup some stuff, like for MPP detection.
         */
        if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS)) != NULL)
-               ipno = vp->vp_ipaddr;
+               ipno = vp->lvalue;
        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
-               call_num = vp->vp_strvalue;
+               call_num = vp->strvalue;
 
        /*
         *      lock the file while reading/writing.
@@ -666,7 +677,7 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
         *      static IP's like DSL.
         */
        request->simul_count = 0;
-       while (read(fd, &u, sizeof(u)) == sizeof(u)) {
+       while ((read_size = read(fd, &u, sizeof(u))) == sizeof(u)) {
                if (((strncmp(login, u.login, RUT_NAMESIZE) == 0) ||
                     (!inst->case_sensitive &&
                      (strncasecmp(login, u.login, RUT_NAMESIZE) == 0))) &&
@@ -674,7 +685,7 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
                        char session_id[sizeof(u.session_id) + 1];
                        char utmp_login[sizeof(u.login) + 1];
 
-                       strlcpy(session_id, u.session_id, sizeof(session_id));
+                       strNcpy(session_id, u.session_id, sizeof(session_id));
 
                        /*
                         *      The login name MAY fill the whole field,
@@ -692,7 +703,7 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
                         *      and the NAS says "no", because "BOB"
                         *      is using the port.
                         */
-                       strlcpy(utmp_login, u.login, sizeof(u.login));
+                       strNcpy(utmp_login, u.login, sizeof(u.login));
 
                        /*
                         *      rad_check_ts may take seconds
@@ -704,18 +715,16 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
                                             utmp_login, session_id);
                        rad_lockfd(fd, LOCK_LEN);
 
-                       if (rcode == 0) {
-                               /*
-                                *      Stale record - zap it.
-                                */
-                               session_zap(request, u.nas_address,
-                                           u.nas_port, login, session_id,
-                                           u.framed_address, u.proto,0);
+                       /*
+                        *      Failed to check the terminal server for
+                        *      duplicate logins: Return an error.
+                        */
+                       if (rcode < 0) {
+                               close(fd);
+                               return RLM_MODULE_FAIL;
                        }
-                       else if (rcode == 1) {
-                               /*
-                                *      User is still logged in.
-                                */
+
+                       if (rcode == 1) {
                                ++request->simul_count;
 
                                /*
@@ -730,16 +739,23 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
                        }
                        else {
                                /*
-                                *      Failed to check the terminal
-                                *      server for duplicate logins:
-                                *      Return an error.
+                                *      False record - zap it.
                                 */
-                               close(fd);
-                               radlog(L_ERR, "rlm_radutmp: Failed to check the terminal server for user '%s'.", utmp_login);
-                               return RLM_MODULE_FAIL;
+                               session_zap(request,
+                                           u.nas_address, u.nas_port, login,
+                                           session_id, u.framed_address,
+                                           u.proto);
                        }
                }
        }
+
+       if (read_size < 0) {
+               radlog(L_ERR, "rlm_radutmp: Error reading %s: %s",
+                      filename, strerror(errno));
+               close(fd);
+               return RLM_MODULE_FAIL;
+       }
+
        close(fd);              /* and implicitely release the locks */
 
        return RLM_MODULE_OK;
@@ -747,20 +763,21 @@ static int radutmp_checksimul(void *instance, REQUEST *request)
 
 /* globally exported name */
 module_t rlm_radutmp = {
-       RLM_MODULE_INIT,
-       "radutmp",
-       0,                            /* type: reserved */
-       radutmp_instantiate,          /* instantiation */
-       radutmp_detach,               /* detach */
-       {
-               NULL,                 /* authentication */
-               NULL,                 /* authorization */
-               NULL,                 /* preaccounting */
-               radutmp_accounting,   /* accounting */
-               radutmp_checksimul,     /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "radutmp",
+  0,                            /* type: reserved */
+  NULL,                        /* initialization */
+  radutmp_instantiate,          /* instantiation */
+  {
+         NULL,                 /* authentication */
+         NULL,                 /* authorization */
+         NULL,                 /* preaccounting */
+         radutmp_accounting,   /* accounting */
+         radutmp_checksimul,   /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  radutmp_detach,               /* detach */
+  NULL,                        /* destroy */
 };
 
diff --git a/src/modules/rlm_radutmp/rlm_radutmp2.c b/src/modules/rlm_radutmp/rlm_radutmp2.c
deleted file mode 100644 (file)
index 6670c9e..0000000
+++ /dev/null
@@ -1,1519 +0,0 @@
-/*
- * rlm_radutmp.c
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * Copyright 2000,2001,2002,2003,2004,2006  The FreeRADIUS server project
- */
-
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/radutmp.h>
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/rad_assert.h>
-
-#include       <fcntl.h>
-#include        <limits.h>
-
-#include "config.h"
-
-#define LOCK_LEN sizeof(struct radutmp)
-
-static const char porttypes[] = "ASITX";
-
-/*
- *     Used for caching radutmp lookups in the accounting
- *     component. The session (checksimul) component doesn't use it,
- *     but probably should, though we're not sure how...
- *
- *     The intent here is to keep this structure as small as
- *     possible, so that it doesn't take up too much memory.
- */
-typedef struct nas_port {
-       uint32_t                nas_address;
-       unsigned int            nas_port;
-       off_t                   offset;
-
-       struct nas_port         *next; /* for the free list */
-} NAS_PORT;
-
-
-/*
- *     Per-file information.
- *
- *     Hmm... having multiple filenames managed by one instance
- *     of the module makes it difficult for the module to do
- *     simultaneous-use checking, without more code edits.
- */
-typedef struct radutmp_cache_t {
-       const char      *filename; /* for future reference */
-       time_t          last_used; /* for future reference */
-
-       rbtree_t        *nas_ports;
-       NAS_PORT        *free_offsets;
-       off_t           max_offset;
-       int             cached_file;
-       int             permission;
-#ifdef HAVE_PTHREAD_H
-       pthread_mutex_t mutex;
-#endif
-} radutmp_cache_t;
-
-
-/*
- *     We cache the users, too, so that we only have to read radutmp
- *     once.
- */
-typedef struct radutmp_simul_t {
-       char            login[sizeof(((struct radutmp *) NULL)->login) + 1];
-       int             simul_count;
-} radutmp_simul_t;
-
-
-/*
- *     Data we store per module.
- */
-typedef struct rlm_radutmp_t {
-       char            *filename;
-       char            *username;
-       int             case_sensitive;
-       int             check_nas;
-       int             permission;
-       int             callerid_ok;
-
-       rbtree_t        *user_tree; /* for simultaneous-use */
-
-       /*
-        *      As the filenames can be dynamically translated,
-        *      we want to keep track of them in a separate data
-        *      structure, so that we can have per-file caches.
-        */
-       radutmp_cache_t cache;
-} rlm_radutmp_t;
-
-#ifndef HAVE_PTHREAD_H
-/*
- *     This is easier than ifdef's throughout the code.
- */
-#define pthread_mutex_init(_x, _y)
-#define pthread_mutex_destroy(_x)
-#define pthread_mutex_lock(_x)
-#define pthread_mutex_unlock(_x)
-#endif
-
-static const CONF_PARSER module_config[] = {
-       { "filename", PW_TYPE_STRING_PTR,
-         offsetof(rlm_radutmp_t,filename), NULL,  RADUTMP },
-       { "username", PW_TYPE_STRING_PTR,
-         offsetof(rlm_radutmp_t,username), NULL,  "%{User-Name}"},
-       { "case_sensitive", PW_TYPE_BOOLEAN,
-         offsetof(rlm_radutmp_t,case_sensitive), NULL,  "yes"},
-       { "check_with_nas", PW_TYPE_BOOLEAN,
-         offsetof(rlm_radutmp_t,check_nas), NULL,  "yes"},
-       { "perm",     PW_TYPE_INTEGER,
-         offsetof(rlm_radutmp_t,permission), NULL,  "0644" },
-       { "callerid", PW_TYPE_BOOLEAN,
-         offsetof(rlm_radutmp_t,callerid_ok), NULL, "no" },
-       { NULL, -1, 0, NULL, NULL }             /* end the list */
-};
-
-
-/*
- *     NAS PORT cmp
- */
-static int nas_port_cmp(const void *a, const void *b)
-{
-       const NAS_PORT *one = a;
-       const NAS_PORT *two = b;
-
-       if (one->nas_address < two->nas_address) return -1;
-       if (one->nas_address > two->nas_address) return +1;
-
-       if (one->nas_port < two->nas_port) return -1;
-       if (one->nas_port > two->nas_port) return +1;
-
-       return 0;
-}
-
-
-/*
- *     Compare two user names.
- */
-static int user_cmp(const void *a, const void *b)
-{
-       const radutmp_simul_t *one = a;
-       const radutmp_simul_t *two = b;
-
-       return strcmp(one->login, two->login);
-}
-
-
-/*
- *     Compare two user names, case insensitive.
- */
-static int user_case_cmp(const void *a, const void *b)
-{
-       const radutmp_simul_t *one = a;
-       const radutmp_simul_t *two = b;
-
-       return strcasecmp(one->login, two->login);
-}
-
-
-/*
- *     Detach.
- */
-static int radutmp_detach(void *instance)
-{
-       NAS_PORT        *this, *next;
-       rlm_radutmp_t *inst = instance;
-
-       rbtree_free(inst->cache.nas_ports);
-
-       for (this = inst->cache.free_offsets;
-            this != NULL;
-            this = next) {
-               next = this->next;
-               free(this);
-       }
-
-       if (inst->cache.filename) free(inst->cache.filename);
-
-       pthread_mutex_destroy(&(inst->cache.mutex));
-
-
-       rbtree_free(inst->user_tree);
-
-       free(inst);
-       return 0;
-}
-
-
-/*
- *     Instantiate.
- */
-static int radutmp_instantiate(CONF_SECTION *conf, void **instance)
-{
-       rlm_radutmp_t *inst;
-
-       inst = rad_malloc(sizeof(*inst));
-       if (!inst) {
-               return -1;
-       }
-       memset(inst, 0, sizeof(*inst));
-
-       if (cf_section_parse(conf, inst, module_config)) {
-               radutmp_detach(inst);
-               return -1;
-       }
-
-       inst->cache.nas_ports = rbtree_create(nas_port_cmp, free, 0);
-       if (!inst->cache.nas_ports) {
-               radlog(L_ERR, "rlm_radutmp: Failed to create nas tree");
-               radutmp_detach(inst);
-               return -1;
-       }
-
-       pthread_mutex_init(&(inst->cache.mutex), NULL);
-       inst->cache.permission = inst->permission;
-
-       if (inst->case_sensitive) {
-               inst->user_tree = rbtree_create(user_cmp, free, 0);
-       } else {
-               inst->user_tree = rbtree_create(user_case_cmp, free, 0);
-       }
-       if (!inst->user_tree) {
-               radlog(L_ERR, "rlm_radutmp: Failed to create user tree");
-               radutmp_detach(inst);
-               return -1;
-       }
-
-       *instance = inst;
-       return 0;
-}
-
-
-/*
- *     Reset the cached entries.
- */
-static int cache_reset(rlm_radutmp_t *inst, radutmp_cache_t *cache)
-{
-       NAS_PORT *this, *next;
-
-       /*
-        *      Cache is already reset, do nothing.
-        */
-       if ((rbtree_num_elements(cache->nas_ports) == 0) &&
-           (cache->free_offsets == NULL)) {
-               DEBUG2("  rlm_radutmp: Not resetting the cache");
-               return 1;
-       }
-       DEBUG2("  rlm_radutmp: Resetting the cache");
-
-       pthread_mutex_lock(&cache->mutex);
-
-       rbtree_free(inst->user_tree);
-
-       rbtree_free(cache->nas_ports);
-
-       for (this = cache->free_offsets;
-            this != NULL;
-            this = next) {
-               next = this->next;
-               free(this);
-       }
-       cache->free_offsets = NULL;
-
-       /*
-        *      Re-create the caches.
-        */
-       cache->nas_ports = rbtree_create(nas_port_cmp, free, 0);
-       if (!cache->nas_ports) {
-               pthread_mutex_unlock(&cache->mutex);
-               radlog(L_ERR, "rlm_radutmp: No memory");
-               return 0;
-       }
-
-       cache->max_offset = 0;
-
-       cache->cached_file = 1;
-
-       if (inst->case_sensitive) {
-               inst->user_tree = rbtree_create(user_cmp, free, 0);
-       } else {
-               inst->user_tree = rbtree_create(user_case_cmp, free, 0);
-       }
-       if (!inst->user_tree) {
-               pthread_mutex_unlock(&cache->mutex);
-               radlog(L_ERR, "rlm_radutmp: No memory");
-               return 0;
-       }
-
-       pthread_mutex_unlock(&cache->mutex);
-
-       return 1;
-}
-
-
-/*
- *     Compare two offsets in a tree.
- */
-static int offset_cmp(const void *a, const void *b)
-{
-       const NAS_PORT *one = a;
-       const NAS_PORT *two = b;
-
-       if (one->offset < two->offset) return -1;
-       if (one->offset > two->offset) return +1;
-
-       return 0;
-}
-
-
-/*
- *     Data structure to use when walking the trees, for zap.
- */
-typedef struct offset_walk_t {
-       rlm_radutmp_t   *inst;
-       radutmp_cache_t *cache;
-       rbtree_t        *offset_tree;
-       uint32_t        nas_address;
-       int             fd;
-       time_t          now;
-} offset_walk_t;
-
-
-/*
- *     Walk over the cache, finding entries with the matching NAS IP address.
- */
-static int nas_port_walk(void *context, void *data)
-{
-       offset_walk_t   *walk = context;
-       NAS_PORT        *nas_port = data;
-
-       /*
-        *      Doesn't match, keep going.
-        */
-       if (walk->nas_address != nas_port->nas_address) return 0;
-
-       /*
-        *      Insert it into the offset tree, for later deletion.
-        */
-       if (rbtree_insert(walk->offset_tree, nas_port) != 1) {
-               DEBUG2("  rlm_radumtp: Insertion failed in nas port walk.");
-               return 1;
-       }
-
-       return 0;
-}
-
-
-/*
- *     Walk through the offset tree, operating on the cache
- */
-static int offset_walk(void *context, void *data)
-{
-       offset_walk_t   *walk = context;
-       NAS_PORT        *nas_port = data;
-       struct radutmp  utmp;
-       radutmp_simul_t *user, myUser;
-
-       /*
-        *      Seek to the entry, and possibly re-write it.
-        */
-       if (lseek(walk->fd, nas_port->offset, SEEK_SET) < 0) {
-               rad_assert(0 == 1);
-       }
-
-       if (read(walk->fd, &utmp, sizeof(utmp)) != sizeof(utmp)) {
-               rad_assert(0 == 1);
-       }
-
-       /*
-        *      If the entry in the file is NEWER than the reboot
-        *      packet, don't re-write it, and don't delete it.
-        */
-       if (utmp.time > walk->now) {
-               return 0;
-       }
-
-       utmp.type = P_IDLE;
-       utmp.time = walk->now;
-
-       if (lseek(walk->fd, -(off_t)sizeof(utmp), SEEK_CUR) < 0) {
-               radlog(L_ERR, "rlm_radutmp: offset_walk: failed in lseek: %s",
-                      strerror(errno));
-               return 1;
-       }
-
-       write(walk->fd, &utmp, sizeof(utmp));
-
-       strlcpy(myUser.login, utmp.login, sizeof(myUser.login));
-       user = rbtree_finddata(walk->inst->user_tree, &myUser);
-       rad_assert(user != NULL);
-       rad_assert(user->simul_count > 0);
-       user->simul_count--;
-       if (user->simul_count == 0) {
-               rbtree_deletebydata(walk->inst->user_tree, user);
-       }
-
-       if (rbtree_deletebydata(walk->cache->nas_ports, nas_port) == 0) {
-               radlog(L_ERR, "rlm_radutmp: Failed to delete entry from cache");
-               return 1;
-       }
-
-       /*
-        *      Insert the entry into the free list.
-        */
-       nas_port->next = walk->cache->free_offsets;
-       walk->cache->free_offsets = nas_port;
-
-       return 0;
-}
-
-
-/*
- *     Zap all users on a NAS from the radutmp file.
- */
-static int radutmp_zap(rlm_radutmp_t *inst,
-                      radutmp_cache_t *cache,
-                      uint32_t nas_address,
-                      time_t now)
-{
-       int             rcode;
-       rbtree_t        *offset_tree;
-       offset_walk_t   walk;
-
-       rad_assert(now != 0);
-
-       /*
-        *      If there's nothing in the file, do nothing,
-        *      but truncate the file, just to be safe.
-        */
-       if (rbtree_num_elements(cache->nas_ports) == 0) {
-               truncate(cache->filename, (off_t) 0);
-               DEBUG2("  rlm_radutmp: No entries in file.  Quenching zap.");
-               return 1;
-       }
-
-       /*
-        *      Create the offset tree, as we want to delete utmp
-        *      entries starting from the start of the file, and we
-        *      can't delete nodes from an rbtree while we're walking
-        *      it.
-        */
-       offset_tree = rbtree_create(offset_cmp, NULL, 0);
-       if (!offset_tree) {
-               radlog(L_ERR, "rlm_radutmp: Out of memory");
-               return 0;
-       }
-
-       pthread_mutex_lock(&cache->mutex);
-
-       /*
-        *      Walk through the cache, finding entries for this NAS,
-        *      and add those entries to the offset tree.
-        */
-       memset(&walk, 0, sizeof(walk));
-       walk.inst = inst;
-       walk.offset_tree = offset_tree;
-       walk.nas_address = nas_address;
-       rcode = rbtree_walk(cache->nas_ports, PreOrder, nas_port_walk, &walk);
-       if (rcode != 0) {
-               pthread_mutex_unlock(&cache->mutex);
-               rbtree_free(offset_tree);
-               radlog(L_ERR, "rlm_radutmp: Failed walking the cache.");
-               return 0;
-       }
-
-       /*
-        *      If both trees have the same number of elements, then
-        *      don't do anything special, as UDP packets may be
-        *      received out of order, by several seconds.  The
-        *      "offset_walk" routine MAY NOT delete the entries, if
-        *      it sees that the entries in the file are newer than
-        *      the reboot packet.
-        */
-
-       /*
-        *      If there's nothing to do, don't do anything.
-        */
-       if (rbtree_num_elements(offset_tree) == 0) {
-               DEBUG2("  rlm_radutmp: NAS IP %08x has no users recorded in file %s.",
-                      htonl(nas_address), cache->filename);
-               pthread_mutex_unlock(&cache->mutex);
-               rbtree_free(offset_tree);
-               return 1;
-       }
-
-       /*
-        *      Open the file, to re-write only a few of the entries.
-        */
-       walk.fd = open(cache->filename, O_RDWR);
-       if (walk.fd < 0) {
-               pthread_mutex_unlock(&cache->mutex);
-               rbtree_free(offset_tree);
-               radlog(L_ERR, "rlm_radutmp: Error accessing file %s: %s",
-                      cache->filename, strerror(errno));
-               return 0;
-       }
-
-       /*
-        *      Lock the utmp file, prefer lockf() over flock().
-        *
-        *      FIXME: maybe we want to lock per-record?
-        */
-       rad_lockfd(walk.fd, LOCK_LEN);
-
-       /*
-        *      Walk through the offset tree, from start to finish,
-        *      deleting entries from the NAS tree, adding them to
-        *      the "free offset" cache, and lseek'ing to that offset
-        *      in the file, and clearing out the data.
-        */
-       walk.cache = cache;
-       walk.now = now;
-       rcode = rbtree_walk(offset_tree, InOrder, offset_walk, &walk);
-       rbtree_free(offset_tree);
-       if (rcode != 0) {
-               radlog(L_ERR, "rlm_radutmp: Failed walking the offsets.");
-               return 0;
-       }
-
-       close(walk.fd); /* and implicitly release the locks */
-
-       /*
-        *      Just to clean up the file.  If it's empty,
-        *      nuke everything.
-        */
-       if (rbtree_num_elements(cache->nas_ports) == 0) {
-               NAS_PORT        *this, *next; /* too many copies of code */
-
-               for (this = inst->cache.free_offsets;
-                    this != NULL;
-                    this = next) {
-                       next = this->next;
-                       free(this);
-               }
-
-               truncate(cache->filename, 0);
-               rad_assert(rbtree_num_elements(inst->user_tree) == 0);
-       }
-
-       pthread_mutex_unlock(&cache->mutex);
-
-       return 1;
-}
-
-
-/*
- *     Read a file, to cache all of its entries.
- */
-static int cache_file(rlm_radutmp_t *inst, radutmp_cache_t *cache)
-{
-       int             fd;
-       int             read_size;
-       struct          stat buf;
-       struct          radutmp utmp;
-       NAS_PORT        **tail;
-
-       rad_assert(cache->max_offset == 0);
-       rad_assert(cache->free_offsets == NULL);
-
-       /*
-        *      Doesn't exist, we're fine.
-        */
-       if (stat(cache->filename, &buf) < 0) {
-               if (errno == ENOENT) {
-                       cache->cached_file = 1;
-                       return 0;
-               }
-               radlog(L_ERR, "rlm_radutmp: Cannot stat %s: %s",
-                      cache->filename, strerror(errno));
-               return 1;
-       }
-
-       /*
-        *      Nothing's there, we're OK.
-        */
-       if (buf.st_size == 0) {
-               cache->cached_file = 1;
-               return 0;
-       }
-
-       /*
-        *      Don't let others much around with our data.
-        */
-       pthread_mutex_lock(&cache->mutex);
-
-       /*
-        *      Read the file and cache it's entries.
-        */
-       fd = open(cache->filename, O_RDONLY, cache->permission);
-       if (fd < 0) {
-               pthread_mutex_unlock(&cache->mutex);
-               radlog(L_ERR, "rlm_radutmp: Error opening %s: %s",
-                      cache->filename, strerror(errno));
-               return 1;
-       }
-
-       /*
-        *      Insert free entries into the tail, so that entries
-        *      get used from the start.
-        */
-       tail = &(cache->free_offsets);
-
-       /*
-        *      Don't lock the file, as we're only reading it.
-        */
-       do {
-               read_size = read(fd, &utmp, sizeof(utmp));
-
-               /*
-                *      Read one record.
-                */
-               if (read_size == sizeof(utmp)) {
-                       radutmp_simul_t *user, myUser;
-                       NAS_PORT *nas_port = rad_malloc(sizeof(*nas_port));
-
-                       memset(nas_port, 0, sizeof(nas_port));
-                       nas_port->offset = cache->max_offset;
-                       cache->max_offset += sizeof(utmp);
-
-                       /*
-                        *      Idle.  Add it to the list of free
-                        *      offsets.
-                        */
-                       if (utmp.type == P_IDLE) {
-                               *tail = nas_port;
-                               tail = &(nas_port->next);
-                               continue;
-                       }
-
-                       /*
-                        *      It's a login record,
-                        */
-                       nas_port->nas_address = utmp.nas_address;
-                       nas_port->nas_port = utmp.nas_port;
-
-                       if (!rbtree_insert(cache->nas_ports, nas_port)) {
-                               rad_assert(0 == 1);
-                       }
-
-                       /*
-                        *      Adds a trailing \0, so myUser.login has
-                        *      an extra char allocated..
-                        */
-                       strlcpy(myUser.login, utmp.login, sizeof(myUser.login));
-                       user = rbtree_finddata(inst->user_tree, &myUser);
-                       if (user) {
-                               user->simul_count++;
-                       } else {
-                               /*
-                                *      Allocate new entry, and add it
-                                *      to the tree.
-                                */
-                               user = rad_malloc(sizeof(user));
-                               strlcpy(user->login, utmp.login,
-                                       sizeof(user->login));
-                               user->simul_count = 1;
-
-                               if (!rbtree_insert(inst->user_tree, user)) {
-                                       rad_assert(0 == 1);
-                               }
-                       }
-                       continue;
-               }
-
-               /*
-                *      We've read a partial record.  WTF?
-                */
-               if (read_size != 0) {
-                       pthread_mutex_unlock(&cache->mutex);
-                       close(fd);
-                       radlog(L_ERR, "rlm_radutmp: Badly formed file %s",
-                              cache->filename);
-                       return 1;
-               }
-
-               /*
-                *      Read nothing, stop.
-                */
-       } while (read_size != 0);
-
-       pthread_mutex_unlock(&cache->mutex);
-       close(fd);              /* and release the lock. */
-       cache->cached_file = 1;
-
-       return 0;
-}
-
-
-/*
- *     Store logins in the RADIUS utmp file.
- */
-static int radutmp_accounting(void *instance, REQUEST *request)
-{
-       rlm_radutmp_t   *inst = instance;
-       struct radutmp  utmp, u;
-       VALUE_PAIR      *vp;
-       int             status = -1;
-       uint32_t        nas_address = 0;
-       uint32_t        framed_address = 0;
-       int             protocol = -1;
-       int             fd;
-       int             port_seen = 0;
-       char            buffer[256];
-       char            filename[1024];
-       char            ip_name[32]; /* 255.255.255.255 */
-       const char      *nas;
-       NAS_PORT        *nas_port, myPort;
-       radutmp_cache_t *cache;
-       int             read_size;
-       rbnode_t        *node;
-
-       /*
-        *      Which type is this.
-        */
-       if ((vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) == NULL) {
-               radlog(L_ERR, "rlm_radutmp: No Accounting-Status-Type record.");
-               return RLM_MODULE_NOOP;
-       }
-       status = vp->vp_integer;
-
-       /*
-        *      Look for weird reboot packets.
-        *
-        *      ComOS (up to and including 3.5.1b20) does not send
-        *      standard PW_STATUS_ACCOUNTING_* messages.
-        *
-        *      Check for:  o no Acct-Session-Time, or time of 0
-        *                  o Acct-Session-Id of "00000000".
-        *
-        *      We could also check for NAS-Port, that attribute
-        *      should NOT be present (but we don't right now).
-        */
-       if ((status != PW_STATUS_ACCOUNTING_ON) &&
-           (status != PW_STATUS_ACCOUNTING_OFF)) do {
-               int check1 = 0;
-               int check2 = 0;
-
-               if ((vp = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME))
-                    == NULL || vp->vp_date == 0)
-                       check1 = 1;
-               if ((vp = pairfind(request->packet->vps, PW_ACCT_SESSION_ID))
-                    != NULL && vp->length == 8 &&
-                    memcmp(vp->vp_strvalue, "00000000", 8) == 0)
-                       check2 = 1;
-               if (check1 == 0 || check2 == 0) {
-#if 0 /* Cisco sometimes sends START records without username. */
-                       radlog(L_ERR, "rlm_radutmp: no username in record");
-                       return RLM_MODULE_FAIL;
-#else
-                       break;
-#endif
-               }
-               radlog(L_INFO, "rlm_radutmp: converting reboot records.");
-               if (status == PW_STATUS_STOP)
-                       status = PW_STATUS_ACCOUNTING_OFF;
-               if (status == PW_STATUS_START)
-                       status = PW_STATUS_ACCOUNTING_ON;
-       } while(0);
-
-       memset(&utmp, 0, sizeof(utmp));
-       utmp.porttype = 'A';
-
-       /*
-        *      First, find the interesting attributes.
-        */
-       for (vp = request->packet->vps; vp; vp = vp->next) {
-               switch (vp->attribute) {
-                       case PW_LOGIN_IP_HOST:
-                       case PW_FRAMED_IP_ADDRESS:
-                               framed_address = vp->vp_ipaddr;
-                               utmp.framed_address = vp->vp_ipaddr;
-                               break;
-                       case PW_FRAMED_PROTOCOL:
-                               protocol = vp->vp_integer;
-                               break;
-                       case PW_NAS_IP_ADDRESS:
-                               nas_address = vp->vp_ipaddr;
-                               utmp.nas_address = vp->vp_ipaddr;
-                               break;
-                       case PW_NAS_PORT:
-                               utmp.nas_port = vp->vp_integer;
-                               port_seen = 1;
-                               break;
-                       case PW_ACCT_DELAY_TIME:
-                               utmp.delay = vp->vp_integer;
-                               break;
-                       case PW_ACCT_SESSION_ID:
-                               /*
-                                *      If it's too big, only use the
-                                *      last bit.
-                                */
-                               if (vp->length > sizeof(utmp.session_id)) {
-                                       int length = vp->length - sizeof(utmp.session_id);
-
-                                       /*
-                                        *      Ascend is br0ken - it
-                                        *      adds a \0 to the end
-                                        *      of any string.
-                                        *      Compensate.
-                                        */
-                                       if (vp->vp_strvalue[vp->length - 1] == 0) {
-                                               length--;
-                                       }
-
-                                       memcpy(utmp.session_id,
-                                             vp->vp_strvalue + length,
-                                             sizeof(utmp.session_id));
-                               } else {
-                                       memset(utmp.session_id, 0,
-                                              sizeof(utmp.session_id));
-                                       memcpy(utmp.session_id,
-                                              vp->vp_strvalue,
-                                              vp->length);
-                               }
-                               break;
-                       case PW_NAS_PORT_TYPE:
-                               if (vp->vp_integer <= 4)
-                                       utmp.porttype = porttypes[vp->vp_integer];
-                               break;
-                       case PW_CALLING_STATION_ID:
-                               if(inst->callerid_ok)
-                                       strlcpy(utmp.caller_id,
-                                               (char *)vp->vp_strvalue,
-                                               sizeof(utmp.caller_id));
-                               break;
-               }
-       }
-
-       /*
-        *      If we didn't find out the NAS address, use the
-        *      originator's IP address.
-        */
-       if (nas_address == 0) {
-               nas_address = request->packet->src_ipaddr;
-               utmp.nas_address = nas_address;
-               nas = client_name(nas_address); /* MUST be a valid client */
-
-       } else {                /* might be a client, might not be. */
-               RADCLIENT *cl;
-
-               /*
-                *      Hack like 'client_name()', but with sane
-                *      fall-back.
-                */
-               cl = client_find(nas_address);
-               if (cl) {
-                       if (cl->shortname && cl->shortname[0]) {
-                               nas = cl->shortname;
-                       } else {
-                               nas = cl->longname;
-                       }
-               } else {
-                       /*
-                        *      The NAS isn't a client, it's behind
-                        *      a proxy server.  In that case, just
-                        *      get the IP address.
-                        */
-                       nas = ip_ntoa(ip_name, nas_address);
-               }
-       }
-
-       /*
-        *      Set the protocol field.
-        */
-       if (protocol == PW_PPP)
-               utmp.proto = 'P';
-       else if (protocol == PW_SLIP)
-               utmp.proto = 'S';
-       else
-               utmp.proto = 'T';
-
-       utmp.time = request->timestamp - utmp.delay;
-
-       /*
-        *      Get the utmp filename, via xlat.
-        */
-       radius_xlat(filename, sizeof(filename), inst->filename, request, NULL);
-
-       /*
-        *      Future: look up filename in filename tree, to get
-        *      radutmp_cache_t pointer
-        */
-       cache = &inst->cache;
-
-       /*
-        *      For now, double-check the filename, to be sure it isn't
-        *      changing.
-        */
-       if (!cache->filename) {
-               cache->filename = strdup(filename);
-               rad_assert(cache->filename != NULL);
-
-       } else if (strcmp(cache->filename, filename) != 0) {
-               radlog(L_ERR, "rlm_radutmp: We do not support dynamically named files.");
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      If the lookup failed, create a new one, and add it
-        *      to the filename tree, and cache the file, as below.
-        */
-
-       /*
-        *      For aging, in the future.
-        */
-       cache->last_used = request->timestamp;
-
-       /*
-        *      If we haven't already read the file, then read the
-        *      entire file, in order to cache its entries.
-        */
-       if (!cache->cached_file) {
-               cache_file(inst, cache);
-       }
-
-       /*
-        *      See if this was a reboot.
-        *
-        *      Hmm... we may not want to zap all of the users when
-        *      the NAS comes up, because of issues with receiving
-        *      UDP packets out of order.
-        */
-       if (status == PW_STATUS_ACCOUNTING_ON && nas_address) {
-               radlog(L_INFO, "rlm_radutmp: NAS %s restarted (Accounting-On packet seen)",
-                      nas);
-               if (!radutmp_zap(inst, cache, nas_address, utmp.time)) {
-                       rad_assert(0 == 1);
-               }
-               return RLM_MODULE_OK;
-       }
-
-       if (status == PW_STATUS_ACCOUNTING_OFF && nas_address) {
-               radlog(L_INFO, "rlm_radutmp: NAS %s rebooted (Accounting-Off packet seen)",
-                      nas);
-               if (!radutmp_zap(inst, cache, nas_address, utmp.time)) {
-                       rad_assert(0 == 1);
-               }
-               return RLM_MODULE_OK;
-       }
-
-       /*
-        *      If we don't know this type of entry, then pretend we
-        *      succeeded.
-        */
-       if (status != PW_STATUS_START &&
-           status != PW_STATUS_STOP &&
-           status != PW_STATUS_ALIVE) {
-               radlog(L_ERR, "rlm_radutmp: NAS %s port %u unknown packet type %d, ignoring it.",
-                      nas, utmp.nas_port, status);
-               return RLM_MODULE_NOOP;
-       }
-
-       /*
-        *      Perhaps we don't want to store this record into
-        *      radutmp. We skip records:
-        *
-        *      - without a NAS-Port (telnet / tcp access)
-        *      - with the username "!root" (console admin login)
-        */
-       if (!port_seen) {
-               DEBUG2("  rlm_radutmp: No NAS-Port in the packet.  Cannot do anything.");
-               DEBUG2("  rlm_radumtp: WARNING: checkrad will probably not work!");
-               return RLM_MODULE_NOOP;
-       }
-
-       /*
-        *      Translate the User-Name attribute, or whatever else
-        *      they told us to use.
-        */
-       *buffer = '\0';
-       radius_xlat(buffer, sizeof(buffer), inst->username, request, NULL);
-
-       /*
-        *      Don't log certain things...
-        */
-       if (strcmp(buffer, "!root") == 0) {
-               DEBUG2("  rlm_radutmp: Not recording administrative user");
-
-               return RLM_MODULE_NOOP;
-       }
-       strlcpy(utmp.login, buffer, RUT_NAMESIZE);
-
-       /*
-        *      First, try to open the file.  If it doesn't exist,
-        *      nuke the existing caches, and try to create it.
-        *
-        *      FIXME: Create any intermediate directories, as
-        *      appropriate.  See rlm_detail.
-        */
-       fd = open(cache->filename, O_RDWR, inst->permission);
-       if (fd < 0) {
-               if (errno == ENOENT) {
-                       DEBUG2("  rlm_radutmp: File %s doesn't exist, creating it.", cache->filename);
-                       if (!cache_reset(inst, cache)) return RLM_MODULE_FAIL;
-
-                       /*
-                        *      Try to create the file.
-                        */
-                       fd = open(cache->filename, O_RDWR | O_CREAT,
-                                 inst->permission);
-               }
-       } else {                /* exists, but may be empty */
-               struct stat buf;
-
-               /*
-                *      If the file is empty, reset the cache.
-                */
-               if ((stat(cache->filename, &buf) == 0) &&
-                   (buf.st_size == 0) &&
-                   (!cache_reset(inst, cache))) {
-                       return RLM_MODULE_FAIL;
-               }
-               DEBUG2("  rlm_radutmp: File %s was truncated.  Resetting cache.",
-                      cache->filename);
-       }
-
-       /*
-        *      Error from creation, or error other than ENOENT: die.
-        */
-       if (fd < 0) {
-               radlog(L_ERR, "rlm_radutmp: Error accessing file %s: %s",
-                      cache->filename, strerror(errno));
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      OK.  Now that we've prepared everything we want to do,
-        *      let's see if we've cached the entry.
-        */
-       myPort.nas_address = utmp.nas_address;
-       myPort.nas_port = utmp.nas_port;
-
-       pthread_mutex_lock(&cache->mutex);
-       node = rbtree_find(cache->nas_ports, &myPort);
-       pthread_mutex_unlock(&cache->mutex);
-
-       if (node) {
-               nas_port = rbtree_node2data(cache->nas_ports, node);
-#if 0
-
-               /*
-                *      stat the file, and get excited if it's been
-                *      truncated.
-                *
-                *      i.e wipe out the cache, and re-read the file.
-                */
-
-               /*
-                *      Now find the new entry.
-                */
-               pthread_mutex_lock(&cache->mutex);
-               node = rbtree_find(cache->nas_ports, &myPort);
-               pthread_mutex_unlock(&cache->mutex);
-#endif
-       }
-
-       if (!node) {
-               radutmp_simul_t *user;
-
-               /*
-                *      Not found in the cache, and we're trying to
-                *      delete an existing record: ignore it.
-                */
-               if (status == PW_STATUS_STOP) {
-                       DEBUG2("  rlm_radumtp: Logout entry for NAS %s port %u with no Login: ignoring it.",
-                              nas, utmp.nas_port);
-                       return RLM_MODULE_NOOP;
-               }
-
-               pthread_mutex_lock(&cache->mutex);
-
-               /*
-                *      It's a START or ALIVE.  Try to find a free
-                *      offset where we can store the new entry, or
-                *      create one, if one doesn't already exist.
-                */
-               if (!cache->free_offsets) {
-                       cache->free_offsets = rad_malloc(sizeof(NAS_PORT));
-                       memset(cache->free_offsets, 0,
-                              sizeof(*(cache->free_offsets)));
-                       cache->free_offsets->offset = cache->max_offset;
-                       cache->max_offset += sizeof(u);
-               }
-
-               /*
-                *      Grab the offset, and put it into the various
-                *      caches.
-                */
-               nas_port = cache->free_offsets;
-               cache->free_offsets = nas_port->next;
-
-               nas_port->nas_address = nas_address;
-               nas_port->nas_port = utmp.nas_port;
-
-               if (!rbtree_insert(cache->nas_ports, nas_port)) {
-                       rad_assert(0 == 1);
-               }
-
-               /*
-                *      Allocate new entry, and add it
-                *      to the tree.
-                */
-               user = rad_malloc(sizeof(user));
-               strlcpy(user->login, utmp.login,
-                       sizeof(user->login));
-               user->simul_count = 1;
-
-               if (!rbtree_insert(inst->user_tree, user)) {
-                       rad_assert(0 == 1);
-               }
-
-               pthread_mutex_unlock(&cache->mutex);
-
-       }
-
-       /*
-        *      Entry was found, or newly created in the cache.
-        *      Seek to the place in the file.
-        */
-       lseek(fd, nas_port->offset, SEEK_SET);
-
-       /*
-        *      Lock the utmp file, prefer lockf() over flock().
-        */
-       rad_lockfd(fd, LOCK_LEN);
-
-       /*
-        *      If it WAS found in the cache, double-check it against
-        *      what is in the file.
-        */
-       if (node) {
-               /*
-                *      If we didn't read anything, then this entry
-                *      doesn't exist.
-                *
-                *      Similarly, if the entry in the file doesn't
-                *      match what we recall, then nuke the cache
-                *      entry.
-                */
-               read_size = read(fd, &u, sizeof(u));
-               if ((read_size < 0) ||
-                   ((read_size > 0) && (read_size  != sizeof(u)))) {
-                       /*
-                        *      Bad read, or bad record.
-                        */
-                       radlog(L_ERR, "rlm_radutmp: Badly formed file %s",
-                              cache->filename);
-                       close(fd);
-                       return RLM_MODULE_FAIL;
-               }
-
-               rad_assert(read_size != 0);
-
-               /*
-                *      We've read a record, go poke at it.
-                */
-               if (read_size > 0) {
-                       /*
-                        *      If these aren't true, then
-                        *
-                        *      a) we have cached a "logout" entry,
-                        *         which we don't do.
-                        *
-                        *      b) we have cached the wrong NAS address
-                        *
-                        *      c) we have cached the wrong NAS port.
-                        */
-                       rad_assert(u.type == P_LOGIN);
-                       rad_assert(u.nas_address == utmp.nas_address);
-                       rad_assert(u.nas_port == utmp.nas_port);
-
-                       /*
-                        *      An update for the same session.
-                        */
-                       if (strncmp(utmp.session_id, u.session_id,
-                                   sizeof(u.session_id)) == 0) {
-
-                               /*
-                                *      It's a duplicate start, so we
-                                *      don't bother writing it.
-                                */
-                               if (status == PW_STATUS_START) {
-                                       DEBUG2("  rlm_radutmp: Login entry for NAS %s port %u duplicate, ignoring it.",
-                                              nas, u.nas_port);
-                                       close(fd);
-                                       return RLM_MODULE_OK;
-
-
-                               /*
-                                *      ALIVE for this session, keep the
-                                *      original login time.
-                                */
-                               } else if (status == PW_STATUS_ALIVE) {
-                                       utmp.time = u.time;
-
-                               /*
-                                *      Stop: delete it from our cache.
-                                */
-                               } else if (status == PW_STATUS_STOP) {
-                                       radutmp_simul_t *user, myUser;
-
-                                       pthread_mutex_lock(&cache->mutex);
-                                       rbtree_deletebydata(cache->nas_ports,
-                                                           nas_port);
-
-                                       strlcpy(myUser.login,
-                                               u.login, sizeof(myUser.login));
-                                       user = rbtree_finddata(inst->user_tree,
-                                                              &myUser);
-                                       rad_assert(user != NULL);
-                                       rad_assert(user->simul_count > 0);
-
-                                       user->simul_count--;
-                                       if (user->simul_count == 0) {
-                                               rbtree_deletebydata(inst->user_tree, user);
-                                       }
-
-                                       pthread_mutex_unlock(&cache->mutex);
-
-                               } else {
-                                       /*
-                                        *      We don't know how to
-                                        *      handle this.
-                                        */
-                                       rad_assert(0 == 1);
-                               }
-
-                       } else { /* session ID doesn't match */
-                               /*
-                                *      STOP for the right NAS & port,
-                                *      but the Acct-Session-Id is
-                                *      different.  This means that
-                                *      we missed the original "stop",
-                                *      and a new "start".
-                                */
-                               if (status == PW_STATUS_STOP) {
-                                       radlog(L_ERR, "rlm_radutmp: Logout entry for NAS %s port %u has old Acct-Session-ID, ignoring it.",
-                                              nas, u.nas_port);
-                                       close(fd);
-                                       return RLM_MODULE_OK;
-                               }
-                       } /* checked session ID's */
-               }  /* else we haven't read anything from the file. */
-       } /* else the entry wasn't cached, but could have been inserted */
-
-       /*
-        *      Hmm... we may have received a start or alive packet
-        *      AFTER a stop or nas-down, in that case, we want to
-        *      discard the new packet.  However, the original code
-        *      could over-write an idle record with a new login
-        *      record for another NAS && port, so we won't worry
-        *      about this case too much.
-        */
-
-       /*
-        *      Seek to where the entry is, and write it blindly.
-        */
-       lseek(fd, nas_port->offset, SEEK_SET); /* FIXME: err */
-
-       if (status != PW_STATUS_STOP) {
-               utmp.type = P_LOGIN;
-               rad_assert(nas_port != NULL); /* it WAS cached */
-       } else {
-               /* FIXME: maybe assert that the entry was deleted... */
-               memcpy(&utmp, &u, sizeof(utmp));
-               utmp.type = P_IDLE;
-       }
-
-       write(fd, &utmp, sizeof(utmp)); /* FIXME: err */
-
-       close(fd);      /* and implicitly release the locks */
-
-       return RLM_MODULE_OK;
-}
-
-/*
- *     See if a user is already logged in. Sets request->simul_count
- *     to the current session count for this user and sets
- *     request->simul_mpp to 2 if it looks like a multilink attempt
- *     based on the requested IP address, otherwise leaves
- *     request->simul_mpp alone.
- *
- *     Check twice. If on the first pass the user exceeds his
- *     max. number of logins, do a second pass and validate all
- *     logins by querying the terminal server (using eg. SNMP).
- */
-static int radutmp_checksimul(void *instance, REQUEST *request)
-{
-       struct radutmp  u;
-       int             fd;
-       VALUE_PAIR      *vp;
-       uint32_t        ipno = 0;
-       char            *call_num = NULL;
-       int             rcode;
-       rlm_radutmp_t   *inst = instance;
-       char            login[256];
-       char            filename[1024];
-       radutmp_cache_t *cache;
-       radutmp_simul_t *user, myUser;
-
-       /*
-        *      Get the filename, via xlat.
-        */
-       radius_xlat(filename, sizeof(filename), inst->filename, request, NULL);
-
-       /*
-        *      Future: look up filename in filename tree, to get
-        *      radutmp_cache_t pointer
-        */
-       cache = &inst->cache;
-
-       /*
-        *      For now, double-check the filename, to be sure it isn't
-        *      changing.
-        */
-       if (!cache->filename) {
-               cache->filename = strdup(filename);
-               rad_assert(cache->filename != NULL);
-
-       } else if (strcmp(cache->filename, filename) != 0) {
-               radlog(L_ERR, "rlm_radutmp: We do not support dynamically named files.");
-               return RLM_MODULE_FAIL;
-       }
-
-       *login = '\0';
-       radius_xlat(login, sizeof(login), inst->username, request, NULL);
-       if (!*login) {
-               return RLM_MODULE_NOOP;
-       }
-
-       /*
-        *      WTF?  This is probably wrong... we probably want to
-        *      be able to check users across multiple session accounting
-        *      methods.
-        */
-       request->simul_count = 0;
-
-       strlcpy(myUser.login, login, sizeof(myUser.login));
-       pthread_mutex_lock(&inst->cache.mutex);
-       user = rbtree_finddata(inst->user_tree, &myUser);
-       if (user) request->simul_count = user->simul_count;
-       user = NULL;            /* someone else may delete it */
-       pthread_mutex_unlock(&inst->cache.mutex);
-
-       /*
-        *      The number of users logged in is OK,
-        *      OR, we've been told to not check the NAS.
-        */
-       if ((request->simul_count < request->simul_max) ||
-           !inst->check_nas) {
-               return RLM_MODULE_OK;
-       }
-
-       /*
-        *      The user is logged in at least N times, and
-        *      we're told to check the NAS.  In that case,
-        *      we've got to read the file, and check each
-        *      NAS port by hand.
-        */
-       if ((fd = open(cache->filename, O_RDWR)) < 0) {
-               /*
-                *      If the file doesn't exist, then no users
-                *      are logged in.
-                */
-               if (errno == ENOENT) {
-                       request->simul_count = 0;
-                       return RLM_MODULE_OK;
-               }
-
-               /*
-                *      Error accessing the file.
-                */
-               radlog(L_ERR, "rlm_radumtp: Error accessing file %s: %s",
-                      cache->filename, strerror(errno));
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      Setup some stuff, like for MPP detection.
-        */
-       if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS)) != NULL)
-               ipno = vp->vp_ipaddr;
-       if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
-               call_num = vp->vp_strvalue;
-
-       /*
-        *      lock the file while reading/writing.
-        */
-       rad_lockfd(fd, LOCK_LEN);
-
-       /*
-        *      FIXME: If we get a 'Start' for a user/nas/port which is
-        *      listed, but for which we did NOT get a 'Stop', then
-        *      it's not a duplicate session.  This happens with
-        *      static IP's like DSL.
-        */
-       request->simul_count = 0;
-       while (read(fd, &u, sizeof(u)) == sizeof(u)) {
-               if (((strncmp(login, u.login, RUT_NAMESIZE) == 0) ||
-                    (!inst->case_sensitive &&
-                     (strncasecmp(login, u.login, RUT_NAMESIZE) == 0))) &&
-                   (u.type == P_LOGIN)) {
-                       char session_id[sizeof(u.session_id) + 1];
-                       char utmp_login[sizeof(u.login) + 1];
-
-                       strlcpy(session_id, u.session_id, sizeof(session_id));
-
-                       /*
-                        *      The login name MAY fill the whole field,
-                        *      and thus won't be zero-filled.
-                        *
-                        *      Note that we take the user name from
-                        *      the utmp file, as that's the canonical
-                        *      form.  The 'login' variable may contain
-                        *      a string which is an upper/lowercase
-                        *      version of u.login.  When we call the
-                        *      routine to check the terminal server,
-                        *      the NAS may be case sensitive.
-                        *
-                        *      e.g. We ask if "bob" is using a port,
-                        *      and the NAS says "no", because "BOB"
-                        *      is using the port.
-                        */
-                       strlcpy(utmp_login, u.login, sizeof(u.login));
-
-                       /*
-                        *      rad_check_ts may take seconds
-                        *      to return, and we don't want
-                        *      to block everyone else while
-                        *      that's happening.  */
-                       rad_unlockfd(fd, LOCK_LEN);
-                       rcode = rad_check_ts(u.nas_address, u.nas_port,
-                                            utmp_login, session_id);
-                       rad_lockfd(fd, LOCK_LEN);
-
-                       if (rcode == 0) {
-                               /*
-                                *      Stale record - zap it.
-                                *
-                                *      Hmm... this ends up calling
-                                *      the accounting section
-                                *      recursively...
-                                */
-                               session_zap(request, u.nas_address,
-                                           u.nas_port, login, session_id,
-                                           u.framed_address, u.proto,0);
-                       }
-                       else if (rcode == 1) {
-                               /*
-                                *      User is still logged in.
-                                */
-                               ++request->simul_count;
-
-                               /*
-                                *      Does it look like a MPP attempt?
-                                */
-                               if (strchr("SCPA", u.proto) &&
-                                   ipno && u.framed_address == ipno)
-                                       request->simul_mpp = 2;
-                               else if (strchr("SCPA", u.proto) && call_num &&
-                                       !strncmp(u.caller_id,call_num,16))
-                                       request->simul_mpp = 2;
-                       }
-                       else {
-                               /*
-                                *      Failed to check the terminal
-                                *      server for duplicate logins:
-                                *      Return an error.
-                                */
-                               close(fd);
-                               radlog(L_ERR, "rlm_radutmp: Failed to check the terminal server for user '%s'.", utmp_login);
-                               return RLM_MODULE_FAIL;
-                       }
-               }
-       }
-       close(fd);              /* and implicitly release the locks */
-
-       return RLM_MODULE_OK;
-}
-
-/* globally exported name */
-module_t rlm_radutmp = {
-  "radutmp",
-  0,                           /* type: reserved */
-  NULL,                        /* initialization */
-  radutmp_instantiate,          /* instantiation */
-  {
-         NULL,                 /* authentication */
-         NULL,                 /* authorization */
-         NULL,                 /* preaccounting */
-         radutmp_accounting,   /* accounting */
-         radutmp_checksimul,   /* checksimul */
-         NULL,                 /* pre-proxy */
-         NULL,                 /* post-proxy */
-         NULL                  /* post-auth */
-  },
-  radutmp_detach,               /* detach */
-  NULL,                        /* destroy */
-};
-
index b75a9d5..60e05a5 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * FIXME add copyrights
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "libradius.h"
+#include "radiusd.h"
+#include "modules.h"
+
+static const char rcsid[] = "$Id$";
 
 #define  REALM_FORMAT_PREFIX   0
 #define  REALM_FORMAT_SUFFIX   1
@@ -100,7 +114,7 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
         *      We will be modifing this later, so we want our own copy
         *      of it.
         */
-       strlcpy(namebuf, (char *)request->username->vp_strvalue, sizeof(namebuf));
+       strNcpy(namebuf, (char *)request->username->strvalue, sizeof(namebuf));
        username = namebuf;
 
        switch(inst->format)
@@ -141,34 +155,34 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
         */
        if (realmname) {
                DEBUG2("    rlm_realm: Looking up realm \"%s\" for User-Name = \"%s\"",
-                      realmname, request->username->vp_strvalue);
+                      realmname, request->username->strvalue);
        } else {
                if( inst->ignore_null ) {
                        DEBUG2("    rlm_realm: No '%c' in User-Name = \"%s\", skipping NULL due to config.",
-                       inst->delim[0], request->username->vp_strvalue);
+                       inst->delim[0], request->username->strvalue);
                        return 0;
                }
                DEBUG2("    rlm_realm: No '%c' in User-Name = \"%s\", looking up realm NULL",
-                      inst->delim[0], request->username->vp_strvalue);
+                      inst->delim[0], request->username->strvalue);
        }
 
        /*
         *      Allow DEFAULT realms unless told not to.
         */
-       realm = realm_find(realmname);
+       realm = realm_find(realmname, (request->packet->code == PW_ACCOUNTING_REQUEST));
        if (!realm) {
                DEBUG2("    rlm_realm: No such realm \"%s\"",
                       (realmname == NULL) ? "NULL" : realmname);
                return 0;
        }
        if( inst->ignore_default &&
-           (strcmp(realm->name, "DEFAULT")) == 0) {
+           (strcmp(realm->realm, "DEFAULT")) == 0) {
                DEBUG2("    rlm_realm: Found DEFAULT, but skipping due to config.");
                return 0;
        }
 
 
-       DEBUG2("    rlm_realm: Found realm \"%s\"", realm->name);
+       DEBUG2("    rlm_realm: Found realm \"%s\"", realm->realm);
 
        /*
         *      If we've been told to strip the realm off, then do so.
@@ -180,29 +194,32 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
                 *
                 */
                if (request->username->attribute != PW_STRIPPED_USER_NAME) {
-                       vp = radius_paircreate(request, &request->packet->vps,
-                                              PW_STRIPPED_USER_NAME,
-                                              PW_TYPE_STRING);
+                       vp = paircreate(PW_STRIPPED_USER_NAME, PW_TYPE_STRING);
+                       if (!vp) {
+                               radlog(L_ERR|L_CONS, "no memory");
+                               return -1;
+                       }
+                       pairadd(&request->packet->vps, vp);
                        DEBUG2("    rlm_realm: Adding Stripped-User-Name = \"%s\"", username);
                } else {
                        vp = request->username;
                        DEBUG2("    rlm_realm: Setting Stripped-User-Name = \"%s\"", username);
                }
 
-               strcpy(vp->vp_strvalue, username);
-               vp->length = strlen((char *)vp->vp_strvalue);
+               strcpy(vp->strvalue, username);
+               vp->length = strlen((char *)vp->strvalue);
                request->username = vp;
        }
 
        DEBUG2("    rlm_realm: Proxying request from user %s to realm %s",
-              username, realm->name);
+              username, realm->realm);
 
        /*
         *      Add the realm name to the request.
         */
-       pairadd(&request->packet->vps, pairmake("Realm", realm->name,
+       pairadd(&request->packet->vps, pairmake("Realm", realm->realm,
                                                T_OP_EQ));
-       DEBUG2("    rlm_realm: Adding Realm = \"%s\"", realm->name);
+       DEBUG2("    rlm_realm: Adding Realm = \"%s\"", realm->realm);
 
        /*
         *      Figure out what to do with the request.
@@ -217,20 +234,30 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
                 *      Perhaps accounting proxying was turned off.
                 */
        case PW_ACCOUNTING_REQUEST:
-               if (!realm->acct_pool) {
+               if (realm->acct_ipaddr == htonl(INADDR_NONE)) {
                        DEBUG2("    rlm_realm: Accounting realm is LOCAL.");
                        return 0;
                }
+
+               if (realm->acct_port == 0) {
+                       DEBUG2("    rlm_realm: acct_port is not set.  Proxy cancelled.");
+                       return 0;
+               }
                break;
 
                /*
                 *      Perhaps authentication proxying was turned off.
                 */
        case PW_AUTHENTICATION_REQUEST:
-               if (!realm->auth_pool) {
+               if (realm->ipaddr == htonl(INADDR_NONE)) {
                        DEBUG2("    rlm_realm: Authentication realm is LOCAL.");
                        return 0;
                }
+
+               if (realm->auth_port == 0) {
+                       DEBUG2("    rlm_realm: auth_port is not set.  Proxy cancelled.");
+                       return 0;
+               }
                break;
        }
 
@@ -239,26 +266,19 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
         *      that has already proxied the request, we don't need to do
         *      it again.
         */
-       vp = pairfind(request->packet->vps, PW_FREERADIUS_PROXIED_TO);
-       if (vp) {
-#if 0
-               /*
-                *      FIXME: HOME SERVER
-                *
-                *      What the heck is this code doing, and why?
-                */
-
-               if (request->packet->code == PW_AUTHENTICATION_REQUEST &&
-                   vp->vp_ipaddr == realm->home_auth->ipaddr.ipaddr.ip4addr.s_addr) {
-                       DEBUG2("    rlm_realm: Request not proxied due to Freeradius-Proxied-To");
-                       return 0;
-               }
-               if (request->packet->code == PW_ACCOUNTING_REQUEST &&
-                   vp->vp_ipaddr == realm->home_acct->ipaddr.ipaddr.ip4addr.s_addr) {
-                       DEBUG2("    rlm_realm: Request not proxied due to Freeradius-Proxied-To");
-                       return 0;
+       for (vp = request->packet->vps; vp; vp = vp->next) {
+               if (vp->attribute == PW_FREERADIUS_PROXIED_TO) {
+                       if (request->packet->code == PW_AUTHENTICATION_REQUEST &&
+                           vp->lvalue == realm->ipaddr) {
+                               DEBUG2("    rlm_realm: Request not proxied due to Freeradius-Proxied-To");
+                               return 0;
+                       }
+                       if (request->packet->code == PW_ACCOUNTING_REQUEST &&
+                           vp->lvalue == realm->acct_ipaddr) {
+                               DEBUG2("    rlm_realm: Request not proxied due to Freeradius-Proxied-To");
+                               return 0;
+                       }
                }
-#endif
         }
 
        /*
@@ -279,7 +299,7 @@ static void add_proxy_to_realm(VALUE_PAIR **vps, REALM *realm)
         *      Tell the server to proxy this request to another
         *      realm.
         */
-       vp = pairmake("Proxy-To-Realm", realm->name, T_OP_EQ);
+       vp = pairmake("Proxy-To-Realm", realm->realm, T_OP_EQ);
        if (!vp) {
                radlog(L_ERR|L_CONS, "no memory");
                exit(1);
@@ -321,6 +341,7 @@ static int realm_instantiate(CONF_SECTION *conf, void **instance)
             free(inst);
             return -1;
        }
+       free(inst->formatstring);
        if(strlen(inst->delim) != 1) {
             radlog(L_ERR, "Bad value \"%s\" for realm delimiter value", inst->delim);
             free(inst);
@@ -363,7 +384,7 @@ static int realm_authorize(void *instance, REQUEST *request)
         *      Maybe add a Proxy-To-Realm attribute to the request.
         */
        DEBUG2("    rlm_realm: Preparing to proxy authentication request to realm \"%s\"\n",
-              realm->name);
+              realm->realm);
        add_proxy_to_realm(&request->config_items, realm);
 
        return RLM_MODULE_UPDATED; /* try the next module */
@@ -375,7 +396,7 @@ static int realm_authorize(void *instance, REQUEST *request)
  */
 static int realm_preacct(void *instance, REQUEST *request)
 {
-       const char *name = (char *)request->username->vp_strvalue;
+       const char *name = (char *)request->username->strvalue;
        REALM *realm;
 
        if (!name)
@@ -399,7 +420,7 @@ static int realm_preacct(void *instance, REQUEST *request)
         *      Maybe add a Proxy-To-Realm attribute to the request.
         */
        DEBUG2("    rlm_realm: Preparing to proxy accounting request to realm \"%s\"\n",
-              realm->name);
+              realm->realm);
        add_proxy_to_realm(&request->config_items, realm);
 
        return RLM_MODULE_UPDATED; /* try the next module */
@@ -408,25 +429,27 @@ static int realm_preacct(void *instance, REQUEST *request)
 static int realm_detach(void *instance)
 {
        struct realm_config_t *inst = instance;
+       free(inst->delim);
        free(instance);
        return 0;
 }
 
 /* globally exported name */
 module_t rlm_realm = {
-       RLM_MODULE_INIT,
-       "realm",
-       0,                              /* type: reserved */
-       realm_instantiate,              /* instantiation */
-       realm_detach,                   /* detach */
-       {
-               NULL,                   /* authentication */
-               realm_authorize,        /* authorization */
-               realm_preacct,  /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "realm",
+  0,                           /* type: reserved */
+  NULL,                                /* initialization */
+  realm_instantiate,           /* instantiation */
+  {
+         NULL,                 /* authentication */
+         realm_authorize,      /* authorization */
+         realm_preacct,        /* preaccounting */
+         NULL,                 /* accounting */
+         NULL,                 /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  realm_detach,                        /* detach */
+  NULL,                                /* destroy */
 };
index c7f5bc3..300e607 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Copyright 2004  Michael Richardson <mcr@sandelman.ottawa.on.ca>
- * Copyright 2006  The FreeRADIUS server project
  *
  * (Adapted from rlm_files/rlm_files.c )
  */
  */
 
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/radiusd.h>
-#include       <freeradius-devel/modules.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
 #include       <sys/stat.h>
+
+#include       <stdlib.h>
+#include       <string.h>
+#include       <netdb.h>
 #include       <ctype.h>
 #include       <fcntl.h>
 #include       <limits.h>
 
+#include       "radiusd.h"
+#include       "modules.h"
 #include        "../rlm_eap/libeap/eap_sim.h"
 
 struct sim_file_instance {
@@ -72,7 +76,7 @@ struct sim_file_instance {
        char *file;
 };
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        { "simtriplets",        PW_TYPE_STRING_PTR,
          offsetof(struct sim_file_instance, file),
          NULL, "${raddbdir}/simtriplets.dat" },
@@ -130,7 +134,7 @@ static int sim_file_authorize(void *instance, REQUEST *request)
         *      Grab the canonical user name.
         */
        namepair = request->username;
-       name = namepair ? (char *) namepair->vp_strvalue : "NONE";
+       name = namepair ? (char *) namepair->strvalue : "NONE";
 
        triplets = fopen(inst->file, "r");
 
@@ -271,11 +275,10 @@ static int sim_file_detach(void *instance)
 
 /* globally exported name */
 module_t rlm_sim_files = {
-       RLM_MODULE_INIT,
        "sim_files",
        0,                              /* type: reserved */
+       NULL,                           /* initialization */
        sim_file_instantiate,           /* instantiation */
-       sim_file_detach,                /* detach */
        {
                NULL,                   /* authentication */
                sim_file_authorize,     /* authorization */
@@ -286,5 +289,7 @@ module_t rlm_sim_files = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       sim_file_detach,                /* detach */
+       NULL                            /* destroy */
 };
 
index 5700c29..2dae575 100644 (file)
@@ -3,7 +3,6 @@
    Version 1.9.
    SMB Byte handling
    Copyright (C) Andrew Tridgell 1992-1995
-   Copyright 2006 The FreeRADIUS server project
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -25,9 +24,6 @@
    int manipulation
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(byteorder_h, "$Id$")
-
 #undef CAREFUL_ALIGNMENT
 
 /* we know that the 386 can handle misalignment and has the "right"
index 72ff765..707c0da 100644 (file)
@@ -1,79 +1,45 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to 1 if you have the <arpa/inet.h> header file. */
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
+
+*/
+
+
+/* Define if you have the <arpa/inet.h> header file.  */
 #undef HAVE_ARPA_INET_H
 
-/* Define to 1 if you have the <ctype.h> header file. */
+/* Define if you have the <ctype.h> header file.  */
 #undef HAVE_CTYPE_H
 
-/* Define to 1 if you have the <dirent.h> header file. */
+/* Define if you have the <dirent.h> header file.  */
 #undef HAVE_DIRENT_H
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <netdb.h> header file. */
+/* Define if you have the <netdb.h> header file.  */
 #undef HAVE_NETDB_H
 
-/* Define to 1 if you have the <netinet/in.h> header file. */
+/* Define if you have the <netinet/in.h> header file.  */
 #undef HAVE_NETINET_IN_H
 
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/* Define if you have the <netinet/tcp.h> header file.  */
 #undef HAVE_NETINET_TCP_H
 
-/* Define to 1 if you have the <signal.h> header file. */
+/* Define if you have the <signal.h> header file.  */
 #undef HAVE_SIGNAL_H
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/signal.h> header file. */
+/* Define if you have the <sys/signal.h> header file.  */
 #undef HAVE_SYS_SIGNAL_H
 
-/* Define to 1 if you have the <sys/socket.h> header file. */
+/* Define if you have the <sys/socket.h> header file.  */
 #undef HAVE_SYS_SOCKET_H
 
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <sys/uio.h> header file. */
+/* Define if you have the <sys/uio.h> header file.  */
 #undef HAVE_SYS_UIO_H
 
-/* Define to 1 if you have the <sys/vfs.h> header file. */
+/* Define if you have the <sys/vfs.h> header file.  */
 #undef HAVE_SYS_VFS_H
 
-/* Define to 1 if you have the <unistd.h> header file. */
+/* Define if you have the <unistd.h> header file.  */
 #undef HAVE_UNISTD_H
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
index 4842ecf..f8f380c 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.4 .
+# From configure.in Revision: 1.3 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -944,7 +944,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1866,7 +1866,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1924,7 +1925,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2040,7 +2042,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2094,7 +2097,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2139,7 +2143,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2183,7 +2188,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2547,7 +2553,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2717,7 +2724,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2807,7 +2815,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3734,6 +3743,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3772,12 +3786,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 7375da8..248f6d8 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_smb.c)
 AC_CONFIG_HEADER(config.h)
 AC_REVISION($Revision$)
@@ -67,7 +66,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index c3213a3..0d7d5dd 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Common Structures etc Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rfcnb_common_h, "$Id$")
-
 /* A data structure we need */
 
 typedef struct RFCNB_Pkt {
index 6db9c43..a942434 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Error Response Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rfcnb_error_h, "$Id$")
-
 /* Error responses */
 
 #define RFCNBE_Bad -1          /* Bad response */
index 2c57d73..0869b2a 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB IO Routines ...
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
-
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 /* #include <features.h> */
 #include "std-includes.h"
 #include "rfcnb-priv.h"
@@ -58,6 +53,7 @@ void rfcnb_alarm(int sig)
 int RFCNB_Set_Timeout(int seconds)
 
 {
+  int temp;
   /* If we are on a Bezerkeley system, use sigvec, else sigaction */
 #ifndef SA_RESTART
   struct sigvec invec, outvec;
index 5f8963a..9af8e90 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB IO Routines Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rfcnb_io_h, "$Id$")
-
 int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
 
 int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len);
index 02c071d..f2043d4 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rfcnb_priv_h, "$Id$")
-
 /* Defines we need */
 
 typedef unsigned short uint16;
index 67d2bf3..e241864 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Utility Routines ...
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <string.h>
 
-#include <freeradius-devel/libradius.h>
 #include "std-includes.h"
 #include "rfcnb-priv.h"
 #include "rfcnb-util.h"
@@ -247,11 +242,11 @@ void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
     fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt -> data));
     RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len,
 #ifdef RFCNB_PRINT_DATA
-                   RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len
+                   RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len);
 #else
-                    40
+                    40);
 #endif
-           );
+
   if (Prot_Print_Routine != 0) { /* Print the rest of the packet */
 
     Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len,
@@ -318,20 +313,28 @@ void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
 
 int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
 
-{
-       lrad_ipaddr_t ipaddr;
+{ int addr;         /* Assumes IP4, 32 bit network addresses */
+  struct hostent *hp;
 
-       if (ip_hton(host, AF_INET, &ipaddr) < 0) {
-               /* Try NetBIOS name lookup, how the hell do we do that? */
+        /* Use inet_addr to try to convert the address */
 
-               RFCNB_errno = RFCNBE_BadName;   /* Is this right? */
-               RFCNB_saved_errno = errno;
-               return(RFCNBE_Bad);
+  if ((addr = ip_getaddr(host)) == INADDR_NONE) { /* Not in DNS */
 
-       }
+        /* Try NetBIOS name lookup, how the hell do we do that? */
+
+      RFCNB_errno = RFCNBE_BadName;   /* Is this right? */
+      RFCNB_saved_errno = errno;
+      return(RFCNBE_Bad);
+
+  }
+  else { /* We got an IP address */
+
+    memcpy((void *)Dest_IP, (void *)&addr, sizeof(struct in_addr));
+
+  }
+
+  return 0;
 
-       memcpy(Dest_IP, &ipaddr.ipaddr.ip4addr, sizeof(struct in_addr));
-       return 0;
 }
 
 /* Disconnect the TCP connection to the server */
@@ -401,7 +404,7 @@ int RFCNB_Session_Req(struct RFCNB_Con *con,
 
   /* Response packet should be no more than 9 bytes, make 16 jic */
 
-  char resp[16];
+  char ln1[16], ln2[16], n1[32], n2[32], resp[16];
   int len;
   struct RFCNB_Pkt *pkt, res_pkt;
 
@@ -510,3 +513,12 @@ int RFCNB_Session_Req(struct RFCNB_Con *con,
       break;
     }
 }
+
+
+
+
+
+
+
+
+
index d6e6cc7..b3f2315 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Utility Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rfcnb_util_h, "$Id$")
-
 void RFCNB_CvtPad_Name(char *name1, char *name2);
 
 void RFCNB_AName_To_NBName(char *AName, char *NBName);
index db00d99..72a8cac 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rfcnb_h, "$Id$")
-
 /* Error responses */
 
 #include "rfcnb-error.h"
index fdee2e4..fefc87d 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2002,2006  The FreeRADIUS server project
+ * Copyright 2002  The FreeRADIUS server project
  * Copyright 2002  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "autoconf.h"
+#include "libradius.h"
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 
 #include "valid.h"
 
+static const char rcsid[] = "$Id$";
+
 /*
  *     Define a structure for our module configuration.
  *
@@ -51,7 +57,7 @@ typedef struct rlm_smb_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "server",  PW_TYPE_STRING_PTR, offsetof(rlm_smb_t,server), NULL,  NULL},
   { "backup",  PW_TYPE_STRING_PTR, offsetof(rlm_smb_t,backup), NULL,  NULL},
   { "domain",  PW_TYPE_STRING_PTR, offsetof(rlm_smb_t,domain), NULL,  NULL},
@@ -126,7 +132,7 @@ static int smb_authenticate(void *instance, REQUEST *request)
         *  Ensure that we're being passed a plain-text password,
         *  and not anything else.
         */
-       if (request->password->attribute != PW_USER_PASSWORD) {
+       if (request->password->attribute != PW_PASSWORD) {
                radlog(L_AUTH, "rlm_smb: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
                return RLM_MODULE_INVALID;
        }
@@ -134,8 +140,8 @@ static int smb_authenticate(void *instance, REQUEST *request)
        /*
         *  Call the SMB magic to do the work.
         */
-       rcode = Valid_User(request->username->vp_strvalue,
-                          request->password->vp_strvalue,
+       rcode = Valid_User(request->username->strvalue,
+                          request->password->strvalue,
                           data->server, data->backup, data->domain);
 
        switch (rcode) {
@@ -162,6 +168,9 @@ static int smb_detach(void *instance)
 {
        rlm_smb_t *data = (rlm_smb_t *) instance;
 
+       if (data->server) free(data->server);
+       if (data->backup) free(data->backup);
+       if (data->domain) free(data->domain);
 
        free(instance);
        return 0;
@@ -177,11 +186,10 @@ static int smb_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_smb = {
-       RLM_MODULE_INIT,
        "SMB",
        RLM_TYPE_THREAD_UNSAFE,         /* type */
+       NULL,                           /* initialization */
        smb_instantiate,                /* instantiation */
-       smb_detach,                     /* detach */
        {
                smb_authenticate,       /* authentication */
                NULL,                   /* authorization */
@@ -192,4 +200,6 @@ module_t rlm_smb = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       smb_detach,                     /* detach */
+       NULL,                           /* destroy */
 };
index ed6aa2b..e7c891a 100644 (file)
@@ -4,7 +4,6 @@
    Session Routines ...
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 #include <string.h>
 
 int RFCNB_errno = 0;
@@ -232,8 +228,7 @@ int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length
 
 int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
 
-{
-  struct RFCNB_Pkt *pkt;
+{ struct RFCNB_Pkt *pkt; struct RFCNB_Hdr *hdr;
   int ret_len;
 
   if (con_Handle == NULL){
index 045cc3d..93fa330 100644 (file)
@@ -6,7 +6,6 @@
    SMB authentication protocol
 
    Copyright (C) Andrew Tridgell 1997
-   Copyright 2006 The FreeRADIUS server project
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -46,9 +45,6 @@
    up with a different answer to the one above)
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
 
 
 static int perm1[56] = {57, 49, 41, 33, 25, 17,  9,
index e7ba6e3..7bb1969 100644 (file)
@@ -4,7 +4,6 @@
    SMB parameters and setup
    Copyright (C) Andrew Tridgell 1992-1997
    Modified by Jeremy Allison 1995.
-   Copyright 2006 The FreeRADIUS server project
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+#include "smblib-priv.h"
+#define uchar unsigned char
+extern int DEBUGLEVEL;
+
+#include <string.h>
 
 #include <string.h>
 #ifdef HAVE_SYS_VFS_H
 #include <sys/vfs.h>
 #endif
 
-#include "smblib-priv.h"
-#define uchar unsigned char
-extern int DEBUGLEVEL;
+#include "byteorder.h"
 
+char *StrnCpy(char *dest,char *src,int n);
 void strupper(char *s);
 
 /*
@@ -45,7 +46,7 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
 
   memset(p21,'\0',21);
   memset(p14,'\0',14);
-  strlcpy((char *)p14,(char *)passwd,14);
+  StrnCpy((char *)p14,(char *)passwd,14);
 
   strupper((char *)p14);
   E_P16(p14, p21);
@@ -123,7 +124,7 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
 void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16)
 {
        char passwd[130];
-       strlcpy(passwd, pwd, sizeof(passwd));
+       StrnCpy(passwd, pwd, sizeof(passwd)-1);
 
        /* Calculate the MD4 hash (NT compatible) of the password */
        memset(nt_p16, '\0', 16);
@@ -142,6 +143,22 @@ void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16)
        bzero(passwd, sizeof(passwd));
 }
 
+/****************************************************************************
+line strncpy but always null terminates. Make sure there is room!
+****************************************************************************/
+char *StrnCpy(char *dest,char *src,int n)
+{
+  char *d = dest;
+  if (!dest) return(NULL);
+  if (!src) {
+    *dest = 0;
+    return(dest);
+  }
+  while (n-- && (*d++ = *src++)) ;
+  *d = 0;
+  return(dest);
+}
+
 void strupper(char *s)
 {
   while (*s)
index 13751f6..ff2a160 100644 (file)
@@ -4,7 +4,6 @@
    SMBlib Common Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(smblib_common_h, "$Id$")
-
 /* To get the error class we want the first 8 bits */
 /* Because we just grab 4bytes from the SMB header, we have to re-order */
 /* here, but it makes the NtStatus part easier in future                */
index 34ee24e..2f530d8 100644 (file)
@@ -4,7 +4,6 @@
    SMBlib private Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(smblib_priv_h, "$Id$")
-
 #include "std-includes.h"
 #include "smblib-common.h"
 
index 61f3871..6f62971 100644 (file)
@@ -4,7 +4,6 @@
    SMBlib Utility Routines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <string.h>
 #include "smblib-priv.h"
+
 #include "rfcnb.h"
 
 /* Print out an SMB pkt in all its gory detail ... */
@@ -200,7 +196,8 @@ int SMB_Figure_Protocol(char *dialects[], int prot_index)
 
 int SMB_Negotiate(SMB_Handle_Type Con_Handle, char *Prots[])
 
-{
+{ struct SMB_Neg_Prot_Def *prot_pkt;
+  struct SMB_Neg_Prot_Resp_Def *resp_pkt;
   struct RFCNB_Pkt *pkt;
   int prots_len, i, pkt_len, prot, alloc_len;
   char *p;
@@ -359,7 +356,7 @@ int SMB_Negotiate(SMB_Handle_Type Con_Handle, char *Prots[])
     Con_Handle -> Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);
 
     p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
-    fprintf(stderr, "%s", (char *)(SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
+    fprintf(stderr, "%d", (char *)(SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
     memcpy(Con_Handle->Encrypt_Key, p, 8);
 
     p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len);
@@ -413,7 +410,8 @@ int SMB_Negotiate(SMB_Handle_Type Con_Handle, char *Prots[])
 
 void SMB_Get_My_Name(char *name, int len)
 
-{
+{ int loc;
+
   if (gethostname(name, len) < 0) { /* Error getting name */
 
     strncpy(name, "unknown", len);
@@ -440,9 +438,8 @@ SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle,
                                char *password,
                                char *device)
 
-{
-  struct RFCNB_Pkt *pkt;
-  int param_len, pkt_len;
+{ struct RFCNB_Pkt *pkt;
+  int param_len, i, pkt_len;
   char *p;
   SMB_Tree_Handle tree;
 
@@ -590,8 +587,8 @@ SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle,
 
   if (Con_Handle -> first_tree == NULL) {
 
-    Con_Handle -> first_tree = tree;
-    Con_Handle -> last_tree = tree;
+    Con_Handle -> first_tree == tree;
+    Con_Handle -> last_tree == tree;
 
   }
   else {
index b41ccf0..42640ce 100644 (file)
@@ -4,7 +4,6 @@
    SMBlib Routines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <ctype.h>
-#include <string.h>
-#include "smblib-priv.h"
-#include "rfcnb.h"
-
+int SMBlib_errno;
+int SMBlib_SMB_Error;
 #define SMBLIB_ERRNO
 #define uchar unsigned char
+#include "smblib-priv.h"
+
+#include "rfcnb.h"
 
-int SMBlib_errno;
-int SMBlib_SMB_Error;
 SMB_State_Types SMBlib_State;
 
 /* Initialize the SMBlib package     */
@@ -110,9 +104,8 @@ int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn)
 SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle,
                                   char *server, char *NTdomain)
 
-{
-  SMB_Handle_Type con;
-  char called[80], calling[80], *address;
+{ SMB_Handle_Type con;
+  char temp[80], called[80], calling[80], *address;
   int i;
 
   /* Get a connection structure if one does not exist */
@@ -321,9 +314,8 @@ SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle,
 int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
                     char *PassWord)
 
-{
-  struct RFCNB_Pkt *pkt;
-  int param_len, pkt_len, pass_len;
+{ struct RFCNB_Pkt *pkt;
+  int param_len, i, pkt_len, pass_len,a;
   char *p, pword[256];
 
   /* First we need a packet etc ... but we need to know what protocol has  */
index 67b5b9e..0d6428a 100644 (file)
@@ -4,7 +4,6 @@
    SMBlib Defines
 
    Copyright (C) Richard Sharpe 1996
-   Copyright 2006 The FreeRADIUS server project
 
 */
 
@@ -24,9 +23,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(smblib_h, "$Id$")
-
 #include "std-defines.h"
 #include "smblib-common.h"
 
index 1558097..c999879 100644 (file)
@@ -4,7 +4,6 @@
    RFCNB Standard Includes
 
    Copyright (C) 1996, Richard Sharpe
-   Copyright 2006 The FreeRADIUS server project
 
    One day we will conditionalize these on OS types ...
 
@@ -23,9 +22,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <freeradius-devel/ident.h>
-RCSIDH(std_includes_h, "$Id$")
-
 #include "config.h"
 
 #define BOOL int
index a4af4b7..f3b00c0 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
+#include <sys/types.h>
+#include <unistd.h>
 #include <syslog.h>
 #include "smblib-priv.h"
 #include "valid.h"
index 25c132e..00d068b 100644 (file)
@@ -1,11 +1,5 @@
-/* Copyright 2006 The FreeRADIUS server project */
-
 #ifndef _VALID_H_
 #define _VALID_H_
-
-#include <freeradius-devel/ident.h>
-RCSIDH(valid_h, "$Id$")
-
 /* SMB User verification function */
 
 #define NTV_NO_ERROR 0
index 3235dab..c93be92 100644 (file)
@@ -8,9 +8,6 @@
 *                                     Mike Machado <mike@innercite.com>    *
 ***************************************************************************/
 
-#include <freeradius-devel/ident.h>
-RCSIDH(conf_h, "$Id$")
-
 typedef struct sql_config {
        char   *sql_driver;
        char   *sql_server;
@@ -18,9 +15,9 @@ typedef struct sql_config {
        char   *sql_login;
        char   *sql_password;
        char   *sql_db;
+       char   *sql_nas_table;
        char   *query_user;
        char   *default_profile;
-       char   *nas_query;
        char   *authorize_check_query;
        char   *authorize_reply_query;
        char   *authorize_group_check_query;
@@ -37,12 +34,12 @@ typedef struct sql_config {
        char   *groupmemb_query;
        int     sqltrace;
        int     do_clients;
-       int     read_groups;
        char   *tracefile;
        char   *xlat_name;
        int     deletestalesessions;
        int     num_sql_socks;
        int     connect_failure_retry_delay;
+       int     query_on_not_found;
        char   *postauth_query;
        char   *allowed_chars;
 
index 5b5c322..eef807e 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.3 .
+# From configure.in Revision: 1.2 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -902,7 +902,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1825,7 +1825,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1883,7 +1884,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1999,7 +2001,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2053,7 +2056,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2098,7 +2102,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2142,7 +2147,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3100,6 +3106,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3138,12 +3149,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
@@ -3375,7 +3380,7 @@ echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
    { (exit 1); exit 1; }; }
     fi
 
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
index b5221aa..b7bac8f 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_sql.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_sql])
@@ -55,9 +54,9 @@ if test x$with_[]modname != xno; then
        AC_CONFIG_SUBDIRS($mysubdirs)
        rm install-sh
 
-       dnl #
+       dnl # 
        dnl # Don't bother looking for errors in the child directories
-       dnl #
+       dnl # 
 
        targetname=modname
 else
@@ -72,10 +71,10 @@ if test x"$fail" != x""; then
                AC_MSG_WARN([silently not building ]modname[.])
                AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.])
                if test x"$headersuggestion" != x; then
-                       AC_MSG_WARN([$headersuggestion])
+                       AC_MSG_WARN([$headersuggestion]) 
                fi
                if test x"$libsuggestion" != x; then
-                       AC_MSG_WARN([$libsuggestion])
+                       AC_MSG_WARN([$libsuggestion]) 
                fi
                targetname=""
        fi
index 4660942..fb3f562 100755 (executable)
@@ -908,7 +908,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1826,7 +1826,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1884,7 +1885,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2000,7 +2002,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2054,7 +2057,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2099,7 +2103,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2143,7 +2148,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2475,7 +2481,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2526,7 +2533,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2596,7 +2604,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3463,6 +3472,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3501,12 +3515,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index aa6b623..1817e7b 100644 (file)
@@ -56,7 +56,7 @@ if test x$with_[]modname != xno; then
        else
                sql_ibmdb2_cflags="${sql_ibmdb2_cflags} ${IBMDB2_INCLUDE}"
                AC_MSG_RESULT(yes)
-
+  
                AC_MSG_CHECKING([for SQLConnect in -ldb2])
 
                old_LIBS="$LIBS"
@@ -81,7 +81,7 @@ if test x$with_[]modname != xno; then
                        AC_MSG_WARN([ibmdb2 libraries not found.  Use --with-ibmdb2-lib-dir=<path>.])
                        targetname=   # disabled module
                else
-                       AC_MSG_RESULT(yes)
+                       AC_MSG_RESULT(yes) 
                        sql_ibmdb2_ldflags="$sql_ibmdb2_ldflags $IBMDB2_LIBS"
                fi
        fi
index 6eccceb..b0e7ff8 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Mike Machado <mike@innercite.com>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2001  Joerg Wendland <wendland@scan-plus.de>
  * by Joerg Wendland <wendland@scan-plus.de>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
+#include <stdio.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
 
+#include "radiusd.h"
 #include <sql.h>
 #include <sqlcli.h>
 #include "rlm_sql.h"
index 624ab45..f2a87ed 100644 (file)
@@ -1,16 +1,8 @@
-#
-# $Id$
-#
-
 include ../../../../../Make.inc
 
 TARGET         = @targetname@
 SRCS           = sql_firebird.c sql_fbapi.c
-HEADERS                = sql_fbapi.h
 RLM_SQL_CFLAGS = @sql_firebird_cflags@ $(INCLTDL)
 RLM_SQL_LIBS   = @sql_firebird_ldflags@
 
-# this uses the RLM_SQL_CFLAGS and RLM_SQL_LIBS and SRCS defs to make TARGET.
 include ../rules.mak
-
-$(LT_OBJS): $(HEADERS)
index 47a9204..0477319 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.1.2.1 .
+# From configure.in Revision: 1.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -908,7 +908,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1826,7 +1826,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1884,7 +1885,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2000,7 +2002,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2054,7 +2057,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2099,7 +2103,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2143,7 +2148,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2475,7 +2481,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2526,7 +2533,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2596,7 +2604,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3463,6 +3472,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3501,12 +3515,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 9f46b01..c1679f9 100644 (file)
@@ -56,7 +56,7 @@ if test x$with_[]modname != xno; then
        else
                sql_firebird_cflags="${sql_firebird_cflags} ${FIREBIRD_INCLUDE}"
                AC_MSG_RESULT(yes)
-
+  
                AC_MSG_CHECKING([for isc_attach_database -l$GDS])
 
                old_LIBS="$LIBS"
@@ -81,7 +81,7 @@ if test x$with_[]modname != xno; then
                        AC_MSG_WARN([firebird libraries not found.  Use --with-firebird-lib-dir=<path>.])
                        targetname=   # disabled module
                else
-                       AC_MSG_RESULT(yes)
+                       AC_MSG_RESULT(yes) 
                        sql_firebird_ldflags="$sql_firebird_ldflags $FIREBIRD_LIBS"
                fi
        fi
index d8c6107..e780bc1 100644 (file)
@@ -19,8 +19,6 @@
  * Copyright 2006  Vitaly Bodzhgua <vitaly@eastera.net>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
 
 #include "sql_fbapi.h"
 
@@ -173,9 +171,9 @@ for (i=0, var=sock->sqlda_out->sqlvar; i<sock->sqlda_out->sqld; var++,i++) {
     case SQL_LONG:
     case SQL_INT64:
                {
-               ISC_INT64       value = 0;
-               short           field_width = 0;
-               short           dscale = 0;
+               ISC_INT64       value;
+               short           field_width;
+               short           dscale;
                char *p;
                p=sock->row[i];
                switch (dtype)
@@ -271,7 +269,7 @@ for (i=0, var=sock->sqlda_out->sqlvar; i<sock->sqlda_out->sqld; var++,i++) {
     case SQL_ARRAY:
                 /* Print the blob id on blobs or arrays */
                 bid = *(ISC_QUAD ISC_FAR *) var->sqldata;
-                snprintf(sock->row[i],sock->row_sizes[i],"%08lx:%08lx", bid.gds_quad_high, bid.gds_quad_low);
+                snprintf(sock->row[i],sock->row_sizes[i],"%08x:%08x", bid.gds_quad_high, bid.gds_quad_low);
                 break;
 
  } //END SWITCH
index dfee7f2..4e00451 100644 (file)
 #ifndef _SQL_FBAPI_H_
 #define _SQL_FBAPI_H_
 
-#include <freeradius-devel/ident.h>
-RCSIDH(sql_fbapi_h, "$Id$")
-
-#include <freeradius-devel/autoconf.h>
-
 #include <stdlib.h>
 #include <string.h>
 #include <ibase.h>
 
-#include <freeradius-devel/radiusd.h>
+#include "radiusd.h"
 #include "rlm_sql.h"
 
 #define IS_ISC_ERROR(status)  (status[0] == 1 && status[1])
index 8163661..2995081 100644 (file)
@@ -19,8 +19,6 @@
  * Copyright 2006  Vitaly Bodzhgua <vitaly@eastera.net>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
 
 #include "sql_fbapi.h"
 
@@ -108,7 +106,7 @@ TryAgain:
       deadlock=1;
       goto TryAgain;
    }
-   radlog(L_ERR, "sock_id %i: rlm_sql_firebird,sql_query error:sql_code=%li, error='%s', query=%s\n",
+   radlog(L_ERR, "sock_id %i: rlm_sql_firebird,sql_query error:sql_code=%i, error='%s', query=%s\n",
      sqlsocket->id,
      firebird_sock->sql_code,
      firebird_sock->lasterror,
diff --git a/src/modules/rlm_sql/drivers/rlm_sql_freetds/Makefile b/src/modules/rlm_sql/drivers/rlm_sql_freetds/Makefile
new file mode 100644 (file)
index 0000000..e2baf78
--- /dev/null
@@ -0,0 +1,21 @@
+#
+#  The FreeTDS libraries are still in development, and the API to use
+#  them has not been finalized.  As a result, if you want to use this
+#  module, you MUST edit the source, and update the rest of this
+#  file by hand.
+#
+#  Please do NOT ask questions about the FreeTDS libraries or API's
+#  on the FreeRADIUS list.  No one there can answer your questions.
+#  Instead, ask questions on the FreeTDS mailing list.
+#
+
+include ../../../../../Make.inc
+
+TARGET                 = 
+SRCS                   = sql_freetds.c
+RLM_SQL_CFLAGS         = 
+RLM_SQL_CXXFLAGS       = 
+RLM_SQL_LDFLAGS                =
+RLM_SQL_LIBS           =
+
+include ../rules.mak
index db8fae9..cd57a7b 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.3 .
+# From configure.in Revision: 1.2 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -908,7 +908,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1826,7 +1826,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1884,7 +1885,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2000,7 +2002,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2054,7 +2057,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2099,7 +2103,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2143,7 +2148,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2475,7 +2481,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2527,7 +2534,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2603,7 +2611,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3470,6 +3479,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3508,12 +3522,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index d7949d0..28c5371 100644 (file)
@@ -36,7 +36,7 @@ if test x$with_[]modname != xno; then
        if test "x$IODBC_INCLUDE" = "x"; then
                old_CFLAGS="$CFLAGS"
 
-dnl            FR_LOCATE_DIR(iodbc_include_dir,[isql.h])
+dnl            AC_LOCATE_DIR(iodbc_include_dir,[isql.h])
 
                for try in /usr/local/include /usr/local/iodbc/include $iodbc_include_dir; do
                        CFLAGS="$old_CFLAGS -I$try"
@@ -60,13 +60,13 @@ dnl         FR_LOCATE_DIR(iodbc_include_dir,[isql.h])
                AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_IODBC_H)
 
-
+  
                AC_MSG_CHECKING([for SQLConnect in -liodbc])
 
                old_LIBS="$LIBS"
 
-dnl            FR_LOCATE_DIR(iodbc_lib_dir,[libodbc${libltdl_cv_shlibext}])
-dnl            FR_LOCATE_DIR(iodbc_lib_dir,[libodbc.a])
+dnl            AC_LOCATE_DIR(iodbc_lib_dir,[libodbc${libltdl_cv_shlibext}])
+dnl            AC_LOCATE_DIR(iodbc_lib_dir,[libodbc.a])
 
                for try in /usr/lib /usr/lib/iodbc /usr/local/lib/iodbc /usr/local/iodbc/lib/iodbc $iodbc_lib_dir; do
                        LIBS="$old_LIBS -L$try -liodbc"
@@ -88,7 +88,7 @@ dnl           FR_LOCATE_DIR(iodbc_lib_dir,[libodbc.a])
                        AC_MSG_WARN([iodbc libraries not found.  Use --with-iodbc-lib-dir=<path>.])
                        targetname=   # disabled module
                else
-                       AC_MSG_RESULT(yes)
+                       AC_MSG_RESULT(yes) 
                        sql_iodbc_ldflags="$sql_iodbc_ldflags $IODBC_LIBS"
                fi
        fi
index 0de8861..0784232 100644 (file)
@@ -1,8 +1,6 @@
 /*
  * sql_iodbc.c iODBC support for FreeRadius
  *
- * Version:    $Id$
- *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation; either version 2 of the License, or
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Jeff Carneal <jeff@apex.net>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
+#include <stdio.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include       "radiusd.h"
+#include  "rlm_sql.h"
 
 #include <isql.h>
 #include <isqlext.h>
 #include <sqltypes.h>
-
 #include "rlm_sql.h"
 
 typedef struct rlm_sql_iodbc_sock {
@@ -59,7 +57,6 @@ static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config);
 static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        rlm_sql_iodbc_sock *iodbc_sock;
-       SQLRETURN rcode;
 
        if (!sqlsocket->conn) {
                sqlsocket->conn = (rlm_sql_iodbc_sock *)rad_malloc(sizeof(rlm_sql_iodbc_sock));
@@ -70,25 +67,21 @@ static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
        iodbc_sock = sqlsocket->conn;
        memset(iodbc_sock, 0, sizeof(*iodbc_sock));
 
-       rcode = SQLAllocEnv(&iodbc_sock->env_handle);
-       if (!SQL_SUCCEEDED(rcode)) {
+       if(SQLAllocEnv(&iodbc_sock->env_handle) != SQL_SUCCESS) {
                radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocEnv failed:  %s",
                                sql_error(sqlsocket, config));
                return -1;
        }
 
-       rcode = SQLAllocConnect(iodbc_sock->env_handle,
-                               &iodbc_sock->dbc_handle);
-       if (!SQL_SUCCEEDED(rcode)) {
+       if(SQLAllocConnect(iodbc_sock->env_handle, &iodbc_sock->dbc_handle) != SQL_SUCCESS) {
                radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocConnect failed:  %s",
                                sql_error(sqlsocket, config));
                return -1;
        }
 
-       rcode = SQLConnect(iodbc_sock->dbc_handle, config->sql_db,
-                          SQL_NTS, config->sql_login, SQL_NTS,
-                          config->sql_password, SQL_NTS);
-       if (!SQL_SUCCEEDED(rcode)) {
+       if (SQLConnect(iodbc_sock->dbc_handle, config->sql_db, SQL_NTS,
+                               config->sql_login, SQL_NTS, config->sql_password,
+                               SQL_NTS) != SQL_SUCCESS) {
                radlog(L_CONS|L_ERR, "sql_create_socket: SQLConnectfailed:  %s",
                                sql_error(sqlsocket, config));
                return -1;
@@ -104,7 +97,7 @@ static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
  *     Purpose: Free socket and private connection data
  *
  *************************************************************************/
-static int sql_destroy_socket(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
 {
        free(sqlsocket->conn);
        sqlsocket->conn = NULL;
@@ -122,11 +115,8 @@ static int sql_destroy_socket(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config)
 static int sql_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
 
        rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
-       SQLRETURN rcode;
 
-       rcode = SQLAllocStmt(iodbc_sock->dbc_handle,
-                            &iodbc_sock->stmt_handle);
-       if (!SQL_SUCCEEDED(rcode)) {
+       if(SQLAllocStmt(iodbc_sock->dbc_handle, &iodbc_sock->stmt_handle) != SQL_SUCCESS) {
                radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocStmt failed:  %s",
                                sql_error(sqlsocket, config));
                return -1;
@@ -139,8 +129,7 @@ static int sql_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
                return -1;
        }
 
-       rcode = SQLExecDirect(iodbc_sock->stmt_handle, querystr, SQL_NTS);
-       if (!SQL_SUCCEEDED(rcode)) {
+       if (SQLExecDirect(iodbc_sock->stmt_handle, querystr, SQL_NTS) != SQL_SUCCESS) {
                radlog(L_CONS|L_ERR, "sql_query: failed:  %s",
                                sql_error(sqlsocket, config));
                return -1;
@@ -209,7 +198,7 @@ static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querys
  *               set for the query.
  *
  *************************************************************************/
-static int sql_store_result(UNUSED SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_store_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        return 0;
 }
@@ -223,7 +212,7 @@ static int sql_store_result(UNUSED SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config
  *               of columns from query
  *
  *************************************************************************/
-static int sql_num_fields(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        SQLSMALLINT count=0;
        rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
@@ -241,7 +230,7 @@ static int sql_num_fields(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
  *               query
  *
  *************************************************************************/
-static int sql_num_rows(UNUSED SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_num_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
        /*
         * I presume this function is used to determine the number of
         * rows in a result set *before* fetching them.  I don't think
@@ -261,7 +250,7 @@ static int sql_num_rows(UNUSED SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
  *              0 on success, -1 on failure, SQL_DOWN if 'database is down'
  *
  *************************************************************************/
-static int sql_fetch_row(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_fetch_row(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        SQLRETURN rc;
        rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
@@ -312,7 +301,7 @@ static int sql_free_result(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
  *               connection
  *
  *************************************************************************/
-static char *sql_error(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        SQLINTEGER errornum = 0;
        SQLSMALLINT length = 0;
@@ -334,7 +323,7 @@ static char *sql_error(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
  *               connection and cleans up any open handles.
  *
  *************************************************************************/
-static int sql_close(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_close(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
 
@@ -385,7 +374,7 @@ static int sql_finish_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
  *               or insert)
  *
  *************************************************************************/
-static int sql_affected_rows(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_affected_rows(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
        SQLINTEGER count;
        rlm_sql_iodbc_sock *iodbc_sock = sqlsocket->conn;
index 0d4d035..e205cb9 100644 (file)
@@ -1,4 +1,12 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
+
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
+
+*/
+
 
 /* Define if you have <mysql.h> */
 #undef HAVE_MYSQL_H
@@ -6,17 +14,3 @@
 /* Define if you have <mysql/mysql.h> */
 #undef HAVE_MYSQL_MYSQL_H
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
index f9f540f..e173482 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.12 .
+# From configure.in Revision: 1.9.4.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -904,7 +904,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1875,7 +1875,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1933,7 +1934,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2049,7 +2051,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2103,7 +2106,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2148,7 +2152,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2192,7 +2197,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2308,7 +2314,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2375,7 +2382,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2450,7 +2458,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2521,7 +2530,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2574,7 +2584,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2679,7 +2690,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2762,7 +2774,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2833,7 +2846,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2886,7 +2900,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2991,7 +3006,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3069,7 +3085,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3144,7 +3161,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3197,7 +3215,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3275,7 +3294,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4126,6 +4146,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -4164,12 +4189,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 0e328b1..9146800 100644 (file)
@@ -91,7 +91,7 @@ if test x$with_[]modname != xno; then
            dnl mysql_config didn't work :(
            smart_try_dir="$mysql_lib_dir /usr/lib /usr/lib/mysql \
                /usr/local/lib/mysql /usr/local/mysql/lib/mysql"
-           FR_SMART_CHECK_LIB(mysqlclient_r, mysql_init)
+           AC_SMART_CHECK_LIB(mysqlclient_r, mysql_init)
            if test "x$ac_cv_lib_mysqlclient_r_mysql_init" != "xyes"
                then
                dnl nothing worked :(
@@ -119,7 +119,7 @@ if test x$with_[]modname != xno; then
            dnl mysql_config didn't work :(
            smart_try_dir="$mysql_lib_dir /usr/lib /usr/lib/mysql \
                /usr/local/lib/mysql /usr/local/mysql/lib/mysql"
-           FR_SMART_CHECK_LIB(mysqlclient, mysql_init)
+           AC_SMART_CHECK_LIB(mysqlclient, mysql_init)
            if test "x$ac_cv_lib_mysqlclient_mysql_init" != "xyes"
                then
                dnl nothing worked :(
@@ -153,7 +153,7 @@ if test x$with_[]modname != xno; then
        dnl mysql_config didn't work :(
        smart_try_dir="$mysql_include_dir /usr/local/include \
                /usr/local/mysql/include"
-       FR_SMART_CHECK_INCLUDE(mysql/mysql.h)
+       AC_SMART_CHECK_INCLUDE(mysql/mysql.h)
        if test "$ac_cv_header_mysql_mysql_h" = "yes"; then
            AC_DEFINE(HAVE_MYSQL_MYSQL_H, [],
                      [Define if you have <mysql/mysql.h>])
index 8da0503..483c8d2 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Mike Machado <mike@innercite.com>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
+#include <stdio.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include       "radiusd.h"
 
 #include "config.h"
 
 #ifdef HAVE_MYSQL_MYSQL_H
-#include <mysql/mysql_version.h>
 #include <mysql/errmsg.h>
 #include <mysql/mysql.h>
 #else
 #ifdef HAVE_MYSQL_H
-#include <mysql_version.h>
 #include <errmsg.h>
 #include <mysql.h>
 #endif
@@ -103,7 +101,7 @@ static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
  *     Purpose: Free socket and any private connection data
  *
  *************************************************************************/
-static int sql_destroy_socket(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
 {
        free(sqlsocket->conn);
        sqlsocket->conn = NULL;
@@ -173,7 +171,7 @@ static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
  *               set for the query.
  *
  *************************************************************************/
-static int sql_store_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -199,7 +197,7 @@ static int sql_store_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
  *               of columns from query
  *
  *************************************************************************/
-static int sql_num_fields(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        int     num = 0;
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
@@ -255,7 +253,7 @@ static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config,
  *               query
  *
  *************************************************************************/
-static int sql_num_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_num_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -275,7 +273,7 @@ static int sql_num_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
  *              0 on success, -1 on failure, SQL_DOWN if database is down.
  *
  *************************************************************************/
-static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -303,7 +301,7 @@ static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
  *               for a result set
  *
  *************************************************************************/
-static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -325,7 +323,7 @@ static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
  *               connection
  *
  *************************************************************************/
-static char *sql_error(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -344,7 +342,7 @@ static char *sql_error(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
  *               connection
  *
  *************************************************************************/
-static int sql_close(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
@@ -364,7 +362,7 @@ static int sql_close(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
  *     Purpose: End the query, such as freeing memory
  *
  *************************************************************************/
-static int sql_finish_query(UNUSED SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        return 0;
 }
@@ -393,7 +391,7 @@ static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
  *     Purpose: End the select query, such as freeing memory or result
  *
  *************************************************************************/
-static int sql_affected_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;
 
index b863af2..df1c4a4 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.9 .
+# From configure.in Revision: 1.7 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -901,7 +901,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1822,7 +1822,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1880,7 +1881,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1996,7 +1998,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2050,7 +2053,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2095,7 +2099,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2139,7 +2144,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2447,7 +2453,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2469,96 +2476,6 @@ ORACLE_INCLUDE=
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
-        # Look for Oracle10g "Instant Client" installed from RPM
-        if test "x$ORACLE_INCLUDE" = "x"; then
-                old_CFLAGS="$CFLAGS"
-
-        { echo "$as_me:$LINENO: WARNING: PETER XXXXXXXXXXXXXXXX1." >&5
-echo "$as_me: WARNING: PETER XXXXXXXXXXXXXXXX1." >&2;}
-
-
-if test "x$LOCATE" != "x"; then
-        DIRS=
-  file=oci.h
-
-  for x in `${LOCATE} $file 2>/dev/null`; do
-                                        base=`echo $x | sed "s%/${file}%%"`
-    if test "x$x" = "x$base"; then
-      continue;
-    fi
-
-    dir=`${DIRNAME} $x 2>/dev/null`
-                exclude=`echo ${dir} | ${GREP} /home`
-    if test "x$exclude" != "x"; then
-      continue
-    fi
-
-                    already=`echo \$oracle_include_dir ${DIRS} | ${GREP} ${dir}`
-    if test "x$already" = "x"; then
-      DIRS="$DIRS $dir"
-    fi
-  done
-fi
-
-eval "oracle_include_dir=\"\$oracle_include_dir $DIRS\""
-
-
-                for try in /usr/include/oracle/10.1.0.3/client $oracle_include_dir; do
-                        CFLAGS="$old_CFLAGS -I$try"
-                        cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <oci.h>
-int
-main ()
-{
- int a = 1;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ORACLE_INCLUDE="-I$try"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ORACLE_INCLUDE=
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-                        if test "x$ORACLE_INCLUDE" != "x"; then
-                                ORACLE_LIBS="-L$/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lm"
-                                break;
-                        fi
-                done
-                CFLAGS="$old_CFLAGS"
-        fi
-        # Finish Looking for Oracle10g includes installed from RPM
-
        # Look for Oracle8i.
        if test "x$ORACLE_INCLUDE" = "x"; then
                old_CFLAGS="$CFLAGS"
@@ -2617,7 +2534,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2669,7 +2587,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2758,7 +2677,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2892,7 +2812,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3763,6 +3684,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3801,12 +3727,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 345858c..866654c 100644 (file)
@@ -30,34 +30,11 @@ if test x$with_[]modname != xno; then
                ORACLE_INCLUDE=
        )
 
-        # Look for Oracle10g "Instant Client" installed from RPM
-        if test "x$ORACLE_INCLUDE" = "x"; then
-                old_CFLAGS="$CFLAGS"
-
-        AC_MSG_WARN([PETER XXXXXXXXXXXXXXXX1.])
-                FR_LOCATE_DIR(oracle_include_dir,oci.h)
-
-                for try in /usr/include/oracle/10.1.0.3/client $oracle_include_dir; do
-                        CFLAGS="$old_CFLAGS -I$try"
-                        AC_TRY_COMPILE([#include <oci.h>],
-                                [ int a = 1; ],
-                                ORACLE_INCLUDE="-I$try",
-                                ORACLE_INCLUDE=
-                        )
-                        if test "x$ORACLE_INCLUDE" != "x"; then
-                                ORACLE_LIBS="-L$/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lm"
-                                break;
-                        fi
-                done
-                CFLAGS="$old_CFLAGS"
-        fi
-        # Finish Looking for Oracle10g includes installed from RPM
-
        # Look for Oracle8i.
        if test "x$ORACLE_INCLUDE" = "x"; then
                old_CFLAGS="$CFLAGS"
 
-               FR_LOCATE_DIR(oracle_home_dir,oci.h)
+               AC_LOCATE_DIR(oracle_home_dir,oci.h)
 
                for try in $oracle_home_dir $oracle_include_dir; do
                        CFLAGS="$old_CFLAGS -I${try}/rdbms/demo -I${try}/rdbms/public -I${try}/plsql/public -I${try}/network/public -I${try}/oci/include"
@@ -92,7 +69,7 @@ if test x$with_[]modname != xno; then
        if test "x$ORACLE_INCLUDE" = "x"; then
                old_CFLAGS="$CFLAGS"
 
-               FR_LOCATE_DIR(oracle_include_dir,oci.h)
+               AC_LOCATE_DIR(oracle_include_dir,oci.h)
 
                for try in /usr/local/include/oracle /usr/local/oracle/include $oracle_include_dir; do
                        CFLAGS="$old_CFLAGS -I$try"
@@ -132,8 +109,8 @@ if test x$with_[]modname != xno; then
                        dnl #
                        old_LIBS="$LIBS"
 
-                       FR_LOCATE_DIR(oracle_lib_dir,[oracleclient.so])
-                       FR_LOCATE_DIR(oracle_lib_dir,[oracleclient.a])
+                       AC_LOCATE_DIR(oracle_lib_dir,[oracleclient.so])
+                       AC_LOCATE_DIR(oracle_lib_dir,[oracleclient.a])
 
                        for try in /usr/lib/oracle /usr/local/lib/oracle /usr/local/oracle/lib $oracle_lib_dir; do
                                LIBS="$old_LIBS -L$try -loracleclient"
index 5cd9f53..915ee15 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  David Kerry <davidk@snti.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
+#include <stdio.h>
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include       "radiusd.h"
 
 #include <oci.h>
 #include "rlm_sql.h"
@@ -72,25 +73,6 @@ static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
        }
 }
 
-/*************************************************************************
- *
- *     Function: sql_check_error
- *
- *     Purpose: check the error to see if the server is down
- *
- *************************************************************************/
-static int sql_check_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-
-       if (strstr(sql_error(sqlsocket, config), "ORA-03113") ||
-                       strstr(sql_error(sqlsocket, config), "ORA-03114")) {
-               radlog(L_ERR,"rlm_sql_oracle: OCI_SERVER_NOT_CONNECTED");
-               return SQL_DOWN;
-       }
-       else {
-               radlog(L_ERR,"rlm_sql_oracle: OCI_SERVER_NORMAL");
-               return -1;
-       }
-}
 
 /*************************************************************************
  *
@@ -262,20 +244,22 @@ static int sql_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {
                                (ub4) 0,
                                (OCISnapshot *) NULL,
                                (OCISnapshot *) NULL,
-                               (ub4) OCI_COMMIT_ON_SUCCESS);
-
-       if (x == OCI_SUCCESS) {
-               return 0;
-       }
+                               (ub4) OCI_DEFAULT);
 
-       if (x == OCI_ERROR) {
+       if ((x != OCI_NO_DATA) && (x != OCI_SUCCESS)) {
                radlog(L_ERR,"rlm_sql_oracle: execute query failed in sql_query: %s",
                                sql_error(sqlsocket, config));
-               return sql_check_error(sqlsocket, config);
+               return SQL_DOWN;
        }
-       else {
-               return -1;
+
+       x = OCITransCommit(oracle_sock->conn, oracle_sock->errHandle, (ub4) 0);
+       if (x != OCI_SUCCESS) {
+               radlog(L_ERR,"rlm_sql_oracle: commit failed in sql_query: %s",
+                               sql_error(sqlsocket, config));
+               return SQL_DOWN;
        }
+
+       return 0;
 }
 
 
@@ -327,11 +311,9 @@ static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querys
                /* Nothing to fetch */
                return 0;
        }
-
-       if (x != OCI_SUCCESS) {
-               radlog(L_ERR,"rlm_sql_oracle: query failed in sql_select_query: %s",
-                               sql_error(sqlsocket, config));
-               return sql_check_error(sqlsocket, config);
+       else if (x != OCI_SUCCESS) {
+               radlog(L_ERR,"rlm_sql_oracle: query failed in sql_select_query: %s",sql_error(sqlsocket, config));
+               return SQL_DOWN;
        }
 
        /*
@@ -510,20 +492,18 @@ static int sql_fetch_row(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
                        1,
                        OCI_FETCH_NEXT,
                        OCI_DEFAULT);
-
-       if (x == OCI_SUCCESS) {
-               sqlsocket->row = oracle_sock->results;
-               return 0;
+       if (x == OCI_NO_DATA) {
+               return -1;
        }
-
-       if (x == OCI_ERROR) {
+       else if (x != OCI_SUCCESS) {
+               /* XXX Check if x suggests we should return SQL_DOWN */
                radlog(L_ERR,"rlm_sql_oracle: fetch failed in sql_fetch_row: %s",
                                sql_error(sqlsocket, config));
-               return sql_check_error(sqlsocket, config);
-       }
-       else {
-               return -1;
+               return SQL_DOWN;
        }
+
+       sqlsocket->row = oracle_sock->results;
+       return 0;
 }
 
 
index 3e15c0d..6061c73 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.7 .
+# From configure.in Revision: 1.6 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -902,7 +902,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1825,7 +1825,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1883,7 +1884,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1999,7 +2001,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2053,7 +2056,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2098,7 +2102,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2142,7 +2147,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2262,7 +2268,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2285,8 +2292,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" = "x"; then
@@ -2315,7 +2322,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2393,7 +2401,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2416,8 +2425,8 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
     if test "x$smart_include" != "x"; then
       break;
     fi
-    CFLAGS="$old_CFLAGS"
   done
+  CFLAGS="$old_CFLAGS"
 fi
 
 if test "x$smart_include" != "x"; then
@@ -2474,7 +2483,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2497,8 +2507,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" = "x"; then
@@ -2527,7 +2537,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2632,7 +2643,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2655,8 +2667,8 @@ rm -f conftest.err conftest.$ac_objext \
     if test "x$smart_lib" != "x"; then
       break;
     fi
-    LIBS="$old_LIBS"
   done
+  LIBS="$old_LIBS"
 fi
 
 if test "x$smart_lib" != "x"; then
@@ -3516,6 +3528,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3554,12 +3571,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 9a04671..68af69e 100644 (file)
@@ -42,13 +42,13 @@ if test x$with_[]modname != xno; then
        )
 
        smart_try_dir="$rlm_sql_postgresql_include_dir /usr/include/postgresql /usr/local/pgsql/include /usr/include/pgsql"
-       FR_SMART_CHECK_INCLUDE(libpq-fe.h)
+       AC_SMART_CHECK_INCLUDE(libpq-fe.h)
        if test "x$ac_cv_header_libpqmfe_h" != "xyes"; then
          fail="$fail libpq-fe.h"
        fi
 
        smart_try_dir="$rlm_sql_postgresql_lib_dir /usr/lib /usr/local/pgsql/lib"
-       FR_SMART_CHECK_LIB(pq, PQconnectdb)
+       AC_SMART_CHECK_LIB(pq, PQconnectdb)
         if test "x$ac_cv_lib_pq_PQconnectdb" != "xyes"; then
          fail="$fail libpq"
         fi
@@ -66,10 +66,10 @@ if test x"$fail" != x""; then
                AC_MSG_WARN([silently not building ]modname[.])
                AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.])
                if test x"$headersuggestion" != x; then
-                       AC_MSG_WARN([$headersuggestion])
+                       AC_MSG_WARN([$headersuggestion]) 
                fi
                if test x"$libsuggestion" != x; then
-                       AC_MSG_WARN([$libsuggestion])
+                       AC_MSG_WARN([$libsuggestion]) 
                fi
                targetname=""
        fi
index d795f35..e5ce5df 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Mike Machado <mike@innercite.com>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
  * Bernhard Herzog <bh@intevation.de>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
+/* Modification of rlm_sql_mysql to handle postgres */
 
+#include <stdio.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "radiusd.h"
 
-#include <libpq-fe.h>
-#include "rlm_sql.h"
-#include "sql_postgresql.h"
+#include        <libpq-fe.h>
+#include       "rlm_sql.h"
 
 typedef struct rlm_sql_postgres_sock {
    PGconn          *conn;
    PGresult        *result;
    int             cur_row;
    int             num_fields;
-   int            affected_rows;
+    int                   affected_rows;
    char            **row;
 } rlm_sql_postgres_sock;
 
 /* Prototypes */
-static int sql_close(SQLSOCK *sqlsocket, SQL_CONFIG *config);
+static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config);
+static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config);
+static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config);
 
 /* Internal function. Return true if the postgresql status value
  * indicates successful completion of the query. Return false otherwise
+ */
 static int
 status_is_ok(ExecStatusType status)
 {
        return status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK;
 }
-*/
 
 
 /* Internal function. Return the number of affected rows of the result
@@ -87,51 +90,52 @@ free_result_row(rlm_sql_postgres_sock * pg_sock)
        if (pg_sock->row != NULL) {
                for (i = pg_sock->num_fields-1; i >= 0; i--) {
                        if (pg_sock->row[i] != NULL) {
-                               free(pg_sock->row[i]);
+                               xfree(pg_sock->row[i]);
                        }
                }
-               free((char*)pg_sock->row);
+               xfree((char*)pg_sock->row);
                pg_sock->row = NULL;
                pg_sock->num_fields = 0;
        }
 }
 
-
 /*************************************************************************
-*      Function: check_fatal_error
-*
-*      Purpose:  Check error type and behave accordingly
-*
-*************************************************************************/
-
-static int check_fatal_error (char *errorcode)
-{
-       int x = 0;
-
-       /*
-       Check the error code to see if we should reconnect or not
-       Error Code table taken from
-       http://www.postgresql.org/docs/8.1/interactive/errcodes-appendix.html
-       */
-
-       while(errorcodes[x].errorcode != NULL){
-               if (strcmp(errorcodes[x].errorcode, errorcode) == 0){
-                       radlog(L_DBG, "rlm_sql_postgresql: Postgresql Fatal Error: [%s: %s] Occurred!!", errorcode, errorcodes[x].meaning);
-                       if (errorcodes[x].shouldreconnect == 1)
-                               return SQL_DOWN;
-                       else
-                               return -1;
-               }
-               x++;
-       }
-
-       radlog(L_DBG, "rlm_sql_postgresql: Postgresql Fatal Error: [%s] Occurred!!", errorcode);
-       /*      We don't seem to have a matching error class/code */
-       return -1;
+ *
+ *      Function: sql_check_error
+ *
+ *      Purpose: check the error to see if the server is down
+ *
+ *     Note: It is possible that something other than a connection error
+ *     could cause PGRES_FATAL_ERROR. If that happens a reconnect will
+ *     occur anyway. Not optimal, but I couldn't find a way to check it.
+ *                             Peter Nixon <codemonkey@peternixon.net>
+ *
+
+************************************************************************/
+static int sql_check_error(int error) {
+        switch(error) {
+        case PGRES_FATAL_ERROR:
+        case -1:
+                radlog(L_DBG, "rlm_sql_postgresql: Postgresql check_error: %s, returning SQL_DOWN", PQresStatus(error));
+                return SQL_DOWN;
+                break;
+
+        case PGRES_COMMAND_OK:
+        case PGRES_TUPLES_OK:
+        case 0:
+                return 0;
+                break;
+
+        case PGRES_NONFATAL_ERROR:
+        case PGRES_BAD_RESPONSE:
+        default:
+                radlog(L_DBG, "rlm_sql_postgresql: Postgresql check_error: %s received", PQresStatus(error));
+                return -1;
+                break;
+        }
 }
 
 
-
 /*************************************************************************
  *
  *     Function: sql_create_socket
@@ -175,9 +179,9 @@ static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
        pg_sock->result=NULL;
        pg_sock->conn=PQconnectdb(connstring);
 
-       if (PQstatus(pg_sock->conn) != CONNECTION_OK) {
+       if (PQstatus(pg_sock->conn) == CONNECTION_BAD) {
                radlog(L_ERR, "rlm_sql_postgresql: Couldn't connect socket to PostgreSQL server %s@%s:%s", config->sql_login, config->sql_server, config->sql_db);
-               /*radlog(L_ERR, "rlm_sql_postgresql: Postgresql error '%s'", PQerrorMessage(pg_sock->conn));*/
+               radlog(L_ERR, "rlm_sql_postgresql: Postgresql error '%s'", PQerrorMessage(pg_sock->conn));
                sql_close(sqlsocket, config);
                return SQL_DOWN;
        }
@@ -195,9 +199,6 @@ static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {
 
        rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
-       int numfields = 0;
-       char *errorcode;
-       char *errormsg;
 
        if (config->sqltrace)
                radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr);
@@ -208,97 +209,35 @@ static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {
        }
 
        pg_sock->result = PQexec(pg_sock->conn, querystr);
-               /*
-                * Returns a PGresult pointer or possibly a null pointer.
-                * A non-null pointer will generally be returned except in
+               /* Returns a result pointer or possibly a NULL pointer.
+                * A non-NULL pointer will generally be returned except in
                 * out-of-memory conditions or serious errors such as inability
-                * to send the command to the server. If a null pointer is
-                * returned, it should be treated like a PGRES_FATAL_ERROR
-                * result.
+                * to send the command to the backend. If a NULL is returned,
+                *  it should be treated like a PGRES_FATAL_ERROR result.
+                * Use PQerrorMessage to get more information about the error.
                 */
        if (!pg_sock->result)
        {
                radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
                                PQerrorMessage(pg_sock->conn));
-               /* As this error COULD be a connection error OR an out-of-memory
-                * condition return value WILL be wrong SOME of the time regardless!
-                * Pick your poison....
-                */
                return  SQL_DOWN;
        } else {
                ExecStatusType status = PQresultStatus(pg_sock->result);
-               radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status));
-
-               switch (status){
-
-                       case PGRES_COMMAND_OK:
-                               /*Successful completion of a command returning no data.*/
-
-                               /*affected_rows function only returns
-                               the number of affected rows of a command
-                               returning no data...
-                               */
-                               pg_sock->affected_rows  = affected_rows(pg_sock->result);
-                               radlog(L_DBG, "rlm_sql_postgresql: query affected rows = %i", pg_sock->affected_rows);
-                               return 0;
-
-                       break;
-
-                       case PGRES_TUPLES_OK:
-                               /*Successful completion of a command returning data (such as a SELECT or SHOW).*/
-
-                               pg_sock->cur_row = 0;
-                               pg_sock->affected_rows = PQntuples(pg_sock->result);
-                               numfields = PQnfields(pg_sock->result); /*Check row storing functions..*/
-                               radlog(L_DBG, "rlm_sql_postgresql: query affected rows = %i , fields = %i", pg_sock->affected_rows, numfields);
-                               return 0;
-
-                       break;
-
-                       case PGRES_BAD_RESPONSE:
-                               /*The server's response was not understood.*/
-                               radlog(L_DBG, "rlm_sql_postgresql: Bad Response From Server!!");
-                               return -1;
-
-                       break;
-
-                       case PGRES_NONFATAL_ERROR:
-                               /*A nonfatal error (a notice or warning) occurred. Possibly never returns*/
-
-                               return -1;
-
-                       break;
-
-                       case PGRES_FATAL_ERROR:
-                               /*A fatal error occurred.*/
-
-                               errorcode = PQresultErrorField(pg_sock->result, PG_DIAG_SQLSTATE);
-                               errormsg  = PQresultErrorField(pg_sock->result, PG_DIAG_MESSAGE_PRIMARY);
-                               radlog(L_DBG, "rlm_sql_postgresql: Error %s", errormsg);
-                               return check_fatal_error(errorcode);
-
-                       break;
 
-                       default:
-                               /* FIXME: An unhandled error occurred.*/
-
-                               /* PGRES_EMPTY_QUERY PGRES_COPY_OUT PGRES_COPY_IN */
-
-                               return -1;
+               radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status));
 
-                       break;
+               radlog(L_DBG, "rlm_sql_postgresql: affected rows = %s",
+                               PQcmdTuples(pg_sock->result));
 
+               if (!status_is_ok(status))
+                       return sql_check_error(status);
 
-               }
-
-               /*
-                       Note to self ... sql_store_result returns 0 anyway
-                       after setting the sqlsocket->affected_rows..
-                       sql_num_fields returns 0 at worst case which means the check below
-                       has a really small chance to return false..
-                       lets remove it then .. yuck!!
-               */
-               /*
+               if (strncasecmp("select", querystr, 6) != 0) {
+                       /* store the number of affected rows because the sql module
+                        * calls finish_query before it retrieves the number of affected
+                        * rows from the driver */
+                       pg_sock->affected_rows = affected_rows(pg_sock->result);
+                       return 0;
                } else {
                        if ((sql_store_result(sqlsocket, config) == 0)
                                        && (sql_num_fields(sqlsocket, config) >= 0))
@@ -306,7 +245,6 @@ static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {
                        else
                                return -1;
                }
-               */
        }
 }
 
@@ -325,12 +263,29 @@ static int sql_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *query
 
 /*************************************************************************
  *
+ *     Function: sql_store_result
+ *
+ *     Purpose: database specific store_result function. Returns a result
+ *               set for the query.
+ *
+ *************************************************************************/
+static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
+       rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
+
+       pg_sock->cur_row = 0;
+       pg_sock->affected_rows = PQntuples(pg_sock->result);
+       return 0;
+}
+
+
+/*************************************************************************
+ *
  *      Function: sql_destroy_socket
  *
  *      Purpose: Free socket and private connection data
  *
  *************************************************************************/
-static int sql_destroy_socket(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config)
+static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
 {
         free(sqlsocket->conn);
        sqlsocket->conn = NULL;
@@ -339,14 +294,35 @@ static int sql_destroy_socket(SQLSOCK *sqlsocket, UNUSED SQL_CONFIG *config)
 
 /*************************************************************************
  *
+ *     Function: sql_num_fields
+ *
+ *     Purpose: database specific num_fields function. Returns number
+ *               of columns from query
+ *
+ *************************************************************************/
+static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
+
+       int num = 0;
+       rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
+
+       if (!(num = PQnfields(pg_sock->result))) {
+               radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Error: Cannot get result");
+               radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL error: %s", PQerrorMessage(pg_sock->conn));
+       }
+       return num;
+}
+
+
+/*************************************************************************
+ *
  *     Function: sql_fetch_row
  *
  *     Purpose: database specific fetch_row. Returns a SQL_ROW struct
- *     with all the data for the query in 'sqlsocket->row'. Returns
- *     0 on success, -1 on failure, SQL_DOWN if 'database is down'.
+ *               with all the data for the query in 'sqlsocket->row'. Returns
+ *              0 on success, -1 on failure, SQL_DOWN if 'database is down'.
  *
  *************************************************************************/
-static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 
        int records, i, len;
        rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
@@ -369,13 +345,14 @@ static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
                        len = PQgetlength(pg_sock->result, pg_sock->cur_row, i);
                        pg_sock->row[i] = (char *)rad_malloc(len+1);
                        memset(pg_sock->row[i], '\0', len+1);
-                       strlcpy(pg_sock->row[i], PQgetvalue(pg_sock->result, pg_sock->cur_row,i),len + 1);
+                       strncpy(pg_sock->row[i], PQgetvalue(pg_sock->result, pg_sock->cur_row,i),len);
                }
                pg_sock->cur_row++;
                sqlsocket->row = pg_sock->row;
+               return 0;
+       } else {
+               return 0;
        }
-
-       return 0;
 }
 
 
@@ -388,7 +365,7 @@ static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
  *               for a result set
  *
  *************************************************************************/
-static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 
        rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
 
@@ -396,8 +373,12 @@ static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
                PQclear(pg_sock->result);
                pg_sock->result = NULL;
        }
-
+#if 0
+       /*
+        *  Commented out because it appears to free memory too early.
+        */
        free_result_row(pg_sock);
+#endif
 
        return 0;
 }
@@ -412,7 +393,7 @@ static int sql_free_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
  *               connection
  *
  *************************************************************************/
-static char *sql_error(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
+static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 
        rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
 
@@ -428,7 +409,7 @@ static char *sql_error(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
  *               connection
  *
  *************************************************************************/
-static int sql_close(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
 
        rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
 
@@ -476,7 +457,7 @@ static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *     Purpose: Return the number of rows affected by the last query.
  *
  *************************************************************************/
-static int sql_affected_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
+static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
        rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;
 
        return pg_sock->affected_rows;
@@ -484,7 +465,7 @@ static int sql_affected_rows(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) {
 
 
 static int NEVER_RETURNS
-not_implemented(UNUSED SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
+not_implemented(SQLSOCK * sqlsocket, SQL_CONFIG *config)
 {
        radlog(L_ERR, "sql_postgresql: calling unimplemented function");
        exit(1);
diff --git a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/sql_postgresql.h b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/sql_postgresql.h
deleted file mode 100644 (file)
index e2ac369..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Copyright 2006 The FreeRADIUS server project */
-
-#ifndef _SQL_POSTGRESQL_H_
-#define _SQL_POSTGRESQL_H_
-
-#include <freeradius-devel/ident.h>
-RCSIDH(sql_postgresql_h, "$Id$")
-
-/**************************************************
-* Error Codes and required information Lookup table
-* Does this shite ever needed? Lets c..
-***************************************************/
-typedef struct pgsql_error{
-       char *errorcode;
-       char *meaning;
-       int  shouldreconnect;
-}pgerror;
-
-pgerror errorcodes[]=
-{
-       "1000", "WARNING", 0,
-       "0100C", "DYNAMIC RESULT SETS RETURNED", 0,
-       "1008", "IMPLICIT ZERO BIT PADDING", 0,
-       "1003", "NULL VALUE ELIMINATED IN SET FUNCTION", 0,
-       "1007", "PRIVILEGE NOT GRANTED", 0,
-       "1006", "PRIVILEGE NOT REVOKED", 0,
-       "1004", "STRING DATA RIGHT TRUNCATION", 0,
-       "01P01", "DEPRECATED FEATURE", 0,
-
-       "2000", "NO DATA", 0,
-       "2001", "NO ADDITIONAL DYNAMIC RESULT SETS RETURNED", 0,
-
-       "3000", "SQL STATEMENT NOT YET COMPLETE", 0,
-
-       "8000", "CONNECTION EXCEPTION", 0,
-       "8003", "CONNECTION DOES NOT EXIST", 0,
-       "8006", "CONNECTION FAILURE", 0,
-       "8001", "SQLCLIENT UNABLE TO ESTABLISH SQLCONNECTION", 0,
-       "8004", "SQLSERVER REJECTED ESTABLISHMENT OF SQLCONNECTION", 0,
-       "8007", "TRANSACTION RESOLUTION UNKNOWN", 0,
-       "08P01", "PROTOCOL VIOLATION", 0,
-
-       "9000", "TRIGGERED ACTION EXCEPTION", 0,
-
-       "0A000", "FEATURE NOT SUPPORTED", 0,
-
-       "0B000", "INVALID TRANSACTION INITIATION", 0,
-
-       "0F000", "LOCATOR EXCEPTION", 0,
-       "0F001", "INVALID LOCATOR SPECIFICATION", 0,
-
-       "0L000", "INVALID GRANTOR", 0,
-       "0LP01", "INVALID GRANT OPERATION", 0,
-
-       "21000", "CARDINALITY VIOLATION", 0,
-
-       "22000", "DATA EXCEPTION", 0,
-       "2202E", "ARRAY SUBSCRIPT ERROR", 0,
-       "22021", "CHARACTER NOT IN REPERTOIRE", 0,
-       "22008", "DATETIME FIELD OVERFLOW", 0,
-       "22012", "DIVISION BY ZERO", 0,
-       "22005", "ERROR IN ASSIGNMENT", 0,
-       "2200B", "ESCAPE CHARACTER CONFLICT", 0,
-       "22022", "INDICATOR OVERFLOW", 0,
-       "22015", "INTERVAL FIELD OVERFLOW", 0,
-       "2201E", "INVALID ARGUMENT FOR LOGARITHM", 0,
-       "2201F", "INVALID ARGUMENT FOR POWER FUNCTION", 0,
-       "2201G", "INVALID ARGUMENT FOR WIDTH BUCKET FUNCTION", 0,
-       "22018", "INVALID CHARACTER VALUE FOR CAST", 0,
-       "22007", "INVALID DATETIME FORMAT", 0,
-       "22019", "INVALID ESCAPE CHARACTER", 0,
-       "2200D", "INVALID ESCAPE OCTET", 0,
-       "22025", "INVALID ESCAPE SEQUENCE", 0,
-       "22P06", "NONSTANDARD USE OF ESCAPE CHARACTER", 0,
-       "22010", "INVALID INDICATOR PARAMETER VALUE", 0,
-       "22020", "INVALID LIMIT VALUE", 0,
-       "22023", "INVALID PARAMETER VALUE", 0,
-       "2201B", "INVALID REGULAR EXPRESSION", 0,
-       "22009", "INVALID TIME ZONE DISPLACEMENT VALUE", 0,
-       "2200C", "INVALID USE OF ESCAPE CHARACTER", 0,
-       "2200G", "MOST SPECIFIC TYPE MISMATCH", 0,
-       "22004", "NULL VALUE NOT ALLOWED", 0,
-       "22002", "NULL VALUE NO INDICATOR PARAMETER", 0,
-       "22003", "NUMERIC VALUE OUT OF RANGE", 0,
-       "22026", "STRING DATA LENGTH MISMATCH", 0,
-       "22001", "STRING DATA RIGHT TRUNCATION", 0,
-       "22011", "SUBSTRING ERROR", 0,
-       "22027", "TRIM ERROR", 0,
-       "22024", "UNTERMINATED C STRING", 0,
-       "2200F", "ZERO LENGTH CHARACTER STRING", 0,
-       "22P01", "FLOATING POINT EXCEPTION", 0,
-       "22P02", "INVALID TEXT REPRESENTATION", 0,
-       "22P03", "INVALID BINARY REPRESENTATION", 0,
-       "22P04", "BAD COPY FILE FORMAT", 0,
-       "22P05", "UNTRANSLATABLE CHARACTER", 0,
-
-       "23000", "INTEGRITY CONSTRAINT VIOLATION", 0,
-       "23001", "RESTRICT VIOLATION", 0,
-       "23502", "NOT NULL VIOLATION", 0,
-       "23503", "FOREIGN KEY VIOLATION", 0,
-       "23505", "UNIQUE VIOLATION", 0,
-       "23514", "CHECK VIOLATION", 0,
-
-       "24000", "INVALID CURSOR STATE", 0,
-
-       "25000", "INVALID TRANSACTION STATE", 0,
-       "25001", "ACTIVE SQL TRANSACTION", 0,
-       "25002", "BRANCH TRANSACTION ALREADY ACTIVE", 0,
-       "25008", "HELD CURSOR REQUIRES SAME ISOLATION LEVEL", 0,
-       "25003", "INAPPROPRIATE ACCESS MODE FOR BRANCH TRANSACTION", 0,
-       "25004", "INAPPROPRIATE ISOLATION LEVEL FOR BRANCH TRANSACTION", 0,
-       "25005", "NO ACTIVE SQL TRANSACTION FOR BRANCH TRANSACTION", 0,
-       "25006", "READ ONLY SQL TRANSACTION", 0,
-       "25007", "SCHEMA AND DATA STATEMENT MIXING NOT SUPPORTED", 0,
-       "25P01", "NO ACTIVE SQL TRANSACTION", 0,
-       "25P02", "IN FAILED SQL TRANSACTION", 0,
-
-       "26000", "INVALID SQL STATEMENT NAME", 0,
-
-       "27000", "TRIGGERED DATA CHANGE VIOLATION", 0,
-
-       "28000", "INVALID AUTHORIZATION SPECIFICATION", 0,
-
-       "2B000", "DEPENDENT PRIVILEGE DESCRIPTORS STILL EXIST", 0,
-       "2BP01", "DEPENDENT OBJECTS STILL EXIST", 0,
-
-       "2D000", "INVALID TRANSACTION TERMINATION", 0,
-
-       "2F000", "SQL ROUTINE EXCEPTION", 0,
-       "2F005", "FUNCTION EXECUTED NO RETURN STATEMENT", 0,
-       "2F002", "MODIFYING SQL DATA NOT PERMITTED", 0,
-       "2F003", "PROHIBITED SQL STATEMENT ATTEMPTED", 0,
-       "2F004", "READING SQL DATA NOT PERMITTED", 0,
-
-       "34000", "INVALID CURSOR NAME", 0,
-
-       "38000", "EXTERNAL ROUTINE EXCEPTION", 0,
-       "38001", "CONTAINING SQL NOT PERMITTED", 0,
-       "38002", "MODIFYING SQL DATA NOT PERMITTED", 0,
-       "38003", "PROHIBITED SQL STATEMENT ATTEMPTED", 0,
-       "38004", "READING SQL DATA NOT PERMITTED", 0,
-
-       "39000", "EXTERNAL ROUTINE INVOCATION EXCEPTION", 0,
-       "39001", "INVALID SQLSTATE RETURNED", 0,
-       "39004", "NULL VALUE NOT ALLOWED", 0,
-       "39P01", "TRIGGER PROTOCOL VIOLATED", 0,
-       "39P02", "SRF PROTOCOL VIOLATED", 0,
-
-       "3B000", "SAVEPOINT EXCEPTION", 0,
-       "3B001", "INVALID SAVEPOINT SPECIFICATION", 0,
-
-       "3D000", "INVALID CATALOG NAME", 0,
-       "3F000", "INVALID SCHEMA NAME", 0,
-
-       "40000", "TRANSACTION ROLLBACK", 0,
-       "40002", "TRANSACTION INTEGRITY CONSTRAINT VIOLATION", 0,
-       "40001", "SERIALIZATION FAILURE", 0,
-       "40003", "STATEMENT COMPLETION UNKNOWN", 0,
-       "40P01", "DEADLOCK DETECTED", 0,
-
-       "44000", "WITH CHECK OPTION VIOLATION", 0,
-
-       "53000", "INSUFFICIENT RESOURCES", 0,
-       "53100", "DISK FULL", 0,
-       "53200", "OUT OF MEMORY", 0,
-       "53300", "TOO MANY CONNECTIONS", 0,
-
-       "54000", "PROGRAM LIMIT EXCEEDED", 0,
-       "54001", "STATEMENT TOO COMPLEX", 0,
-       "54011", "TOO MANY COLUMNS", 0,
-       "54023", "TOO MANY ARGUMENTS", 0,
-
-       "55000", "OBJECT NOT IN PREREQUISITE STATE", 0,
-       "55006", "OBJECT IN USE", 0,
-       "55P02", "CANT CHANGE RUNTIME PARAM", 0,
-       "55P03", "LOCK NOT AVAILABLE", 0,
-
-       "57000", "OPERATOR INTERVENTION", 1,
-       "57014", "QUERY CANCELED", 1,
-       "57P01", "ADMIN SHUTDOWN", 1,
-       "57P02", "CRASH SHUTDOWN", 1,
-       "57P03", "CANNOT CONNECT NOW", 1,
-
-       "58030", "IO ERROR", 1,
-       "58P01", "UNDEFINED FILE", 1,
-       "58P02", "DUPLICATE FILE", 1,
-
-       "F0000", "CONFIG FILE ERROR", 1,
-       "F0001", "LOCK FILE EXISTS", 1,
-
-       "P0000", "PLPGSQL ERROR", 0,
-       "P0001", "RAISE EXCEPTION", 0,
-
-       "42000", "SYNTAX ERROR OR ACCESS RULE VIOLATION", 0,
-       "42601", "SYNTAX ERROR", 0,
-       "42501", "INSUFFICIENT PRIVILEGE", 0,
-       "42846", "CANNOT COERCE", 0,
-       "42803", "GROUPING ERROR", 0,
-       "42830", "INVALID FOREIGN KEY", 0,
-       "42602", "INVALID NAME", 0,
-       "42622", "NAME TOO LONG", 0,
-       "42939", "RESERVED NAME", 0,
-       "42804", "DATATYPE MISMATCH", 0,
-       "42P18", "INDETERMINATE DATATYPE", 0,
-       "42809", "WRONG OBJECT TYPE", 0,
-       "42703", "UNDEFINED COLUMN", 0,
-       "42883", "UNDEFINED FUNCTION", 0,
-       "42P01", "UNDEFINED TABLE", 0,
-       "42P02", "UNDEFINED PARAMETER", 0,
-       "42704", "UNDEFINED OBJECT", 0,
-       "42701", "DUPLICATE COLUMN", 0,
-       "42P03", "DUPLICATE CURSOR", 0,
-       "42P04", "DUPLICATE DATABASE", 0,
-       "42723", "DUPLICATE FUNCTION", 0,
-       "42P05", "DUPLICATE PREPARED STATEMENT", 0,
-       "42P06", "DUPLICATE SCHEMA", 0,
-       "42P07", "DUPLICATE TABLE", 0,
-       "42712", "DUPLICATE ALIAS", 0,
-       "42710", "DUPLICATE OBJECT", 0,
-       "42702", "AMBIGUOUS COLUMN", 0,
-       "42725", "AMBIGUOUS FUNCTION", 0,
-       "42P08", "AMBIGUOUS PARAMETER", 0,
-       "42P09", "AMBIGUOUS ALIAS", 0,
-       "42P10", "INVALID COLUMN REFERENCE", 0,
-       "42611", "INVALID COLUMN DEFINITION", 0,
-       "42P11", "INVALID CURSOR DEFINITION", 0,
-       "42P12", "INVALID DATABASE DEFINITION", 0,
-       "42P13", "INVALID FUNCTION DEFINITION", 0,
-       "42P14", "INVALID PREPARED STATEMENT DEFINITION", 0,
-       "42P15", "INVALID SCHEMA DEFINITION", 0,
-       "42P16", "INVALID TABLE DEFINITION", 0,
-       "42P17", "INVALID OBJECT DEFINITION", 0,
-
-       "XX000", "INTERNAL ERROR", 0,
-       "XX001", "DATA CORRUPTED", 0,
-       "XX002", "INDEX CORRUPTED", 0,
-
-       NULL, NULL, 0
-};
-
-#endif /*_SQL_POSTGRESQL_H_*/
index 13228ad..efdd860 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Mattias Sjostrom <mattias@nogui.se>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-
+#include <stdio.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include       "radiusd.h"
 
 #include <ctpublic.h>
 #include "rlm_sql.h"
index 3a75e81..d21d6a3 100755 (executable)
@@ -908,7 +908,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1826,7 +1826,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -1884,7 +1885,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2000,7 +2002,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2054,7 +2057,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2099,7 +2103,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2143,7 +2148,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2475,7 +2481,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2526,7 +2533,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2596,7 +2604,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3463,6 +3472,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3501,12 +3515,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index e21c558..77619ea 100644 (file)
@@ -56,7 +56,7 @@ if test x$with_[]modname != xno; then
        else
                sql_unixodbc_cflags="${sql_unixodbc_cflags} ${UNIXODBC_INCLUDE}"
                AC_MSG_RESULT(yes)
-
+  
                AC_MSG_CHECKING([for SQLConnect in -lodbc])
 
                old_LIBS="$LIBS"
@@ -81,7 +81,7 @@ if test x$with_[]modname != xno; then
                        AC_MSG_WARN([unixODBC libraries not found.  Use --with-unixODBC-lib-dir=<path>.])
                        targetname=   # disabled module
                else
-                       AC_MSG_RESULT(yes)
+                       AC_MSG_RESULT(yes) 
                        sql_unixodbc_ldflags="$sql_unixodbc_ldflags $UNIXODBC_LIBS"
                fi
        fi
index 9676997..3dd0636 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Dmitri Ageev <d_ageev@ortcc.ru>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "radiusd.h"
 
 #include <sqltypes.h>
 #include "rlm_sql.h"
@@ -291,9 +290,7 @@ static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) {
  *
  *************************************************************************/
 static int sql_finish_query(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
-    rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
-
-    SQLFreeStmt(unixodbc_sock->stmt_handle, SQL_CLOSE);
+  /* Not used */
     return 0;
 }
 
@@ -356,11 +353,11 @@ static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) {
     SQLINTEGER errornum = 0;
     SQLSMALLINT length = 255;
     static char result[1024];  /* NOT thread-safe! */
-
+                          
     rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
 
     error[0] = state[0] = '\0';
-
+                              
     SQLError(
        unixodbc_sock->env_handle,
        unixodbc_sock->dbc_handle,
@@ -393,7 +390,7 @@ static int sql_state(long err_handle, SQLSOCK *sqlsocket, SQL_CONFIG *config) {
 
     rlm_sql_unixodbc_sock *unixodbc_sock = sqlsocket->conn;
 
-    if(SQL_SUCCEEDED(err_handle))
+    if(SQL_SUCCEEDED(err_handle))      
        return 0;               /* on success, just return 0 */
 
     error[0] = state[0] = '\0';
index 627b68a..beb24a2 100644 (file)
@@ -38,7 +38,7 @@ all: build-module
 #
 #######################################################################
 LT_OBJS                = $(SRCS:.c=.lo)
-CFLAGS         += -I../.. -I$(top_builddir)/src/
+CFLAGS         += -I../.. -I$(top_builddir)/src/include
 
 #######################################################################
 #
index 643af8e..1d49170 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Mike Machado <mike@innercite.com>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
+static const char rcsid[] =
+       "$Id$";
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/rad_assert.h>
+#include "autoconf.h"
 
+#include <stdio.h>
 #include <sys/stat.h>
+#include <stdlib.h>
 
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
 #include <sys/wait.h>
+#include <string.h>
 
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
 #include "rlm_sql.h"
+#include "rad_assert.h"
 
 static char *allowed_chars = NULL;
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
        {"driver",PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,sql_driver), NULL, "mysql"},
        {"server",PW_TYPE_STRING_PTR,
@@ -51,6 +63,8 @@ static const CONF_PARSER module_config[] = {
         offsetof(SQL_CONFIG,sql_password), NULL, ""},
        {"radius_db", PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,sql_db), NULL, "radius"},
+       {"nas_table", PW_TYPE_STRING_PTR,
+        offsetof(SQL_CONFIG,sql_nas_table), NULL, "nas"},
        {"sqltrace", PW_TYPE_BOOLEAN,
         offsetof(SQL_CONFIG,sqltrace), NULL, "no"},
        {"sqltracefile", PW_TYPE_STRING_PTR,
@@ -58,15 +72,15 @@ static const CONF_PARSER module_config[] = {
        {"readclients", PW_TYPE_BOOLEAN,
         offsetof(SQL_CONFIG,do_clients), NULL, "no"},
        {"deletestalesessions", PW_TYPE_BOOLEAN,
-        offsetof(SQL_CONFIG,deletestalesessions), NULL, "yes"},
+        offsetof(SQL_CONFIG,deletestalesessions), NULL, "no"},
        {"num_sql_socks", PW_TYPE_INTEGER,
         offsetof(SQL_CONFIG,num_sql_socks), NULL, "5"},
        {"sql_user_name", PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,query_user), NULL, ""},
        {"default_user_profile", PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,default_profile), NULL, ""},
-       {"nas_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,nas_query), NULL, "SELECT id,nasname,shortname,type,secret FROM nas"},
+       {"query_on_not_found", PW_TYPE_BOOLEAN,
+        offsetof(SQL_CONFIG,query_on_not_found), NULL, "no"},
        {"authorize_check_query", PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,authorize_check_query), NULL, ""},
        {"authorize_reply_query", PW_TYPE_STRING_PTR,
@@ -100,25 +114,27 @@ static const CONF_PARSER module_config[] = {
        {"postauth_query", PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,postauth_query), NULL, ""},
        {"safe-characters", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,allowed_chars), NULL,
+        offsetof(SQL_CONFIG,allowed_chars), NULL, 
        "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"},
 
        {NULL, -1, 0, NULL, NULL}
 };
 
-/*
- *     Fall-Through checking function from rlm_files.c
- */
-static int fallthrough(VALUE_PAIR *vp)
-{
-       VALUE_PAIR *tmp;
-       tmp = pairfind(vp, PW_FALL_THROUGH);
+/***********************************************************************
+ * start of main routines
+ ***********************************************************************/
+static int rlm_sql_init(void) {
 
-       return tmp ? tmp->vp_integer : 0;
+       /*
+        * FIXME:
+        * We should put the sqlsocket array here once
+        * the module code is reworked to not unload
+        * modules on HUP.  This way we can have
+        * persistant connections.  -jcarneal
+        */
+       return 0;
 }
 
-
-
 /*
  *     Yucky prototype.
  */
@@ -132,7 +148,7 @@ static int sql_escape_func(char *out, int outlen, const char *in);
  */
 static int sql_xlat(void *instance, REQUEST *request,
                    char *fmt, char *out, size_t freespace,
-                   UNUSED RADIUS_ESCAPE_STRING func)
+                   RADIUS_ESCAPE_STRING func)
 {
        SQLSOCK *sqlsocket;
        SQL_ROW row;
@@ -196,7 +212,7 @@ static int sql_xlat(void *instance, REQUEST *request,
                return 0;
        }
        ret = strlen(row[0]);
-       if (ret >= freespace){
+       if (ret > freespace){
                DEBUG("rlm_sql (%s): sql_xlat:: Insufficient string space",
                      inst->config->xlat_name);
                (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
@@ -204,7 +220,7 @@ static int sql_xlat(void *instance, REQUEST *request,
                return 0;
        }
 
-       strlcpy(out,row[0],freespace);
+       strncpy(out,row[0],ret);
 
        DEBUG("rlm_sql (%s): - sql_xlat finished",
              inst->config->xlat_name);
@@ -220,17 +236,18 @@ static int generate_sql_clients(SQL_INST *inst)
        SQL_ROW row;
        char querystr[MAX_QUERY_LEN];
        RADCLIENT *c;
-       char *prefix_ptr = NULL;
+       char *netmask;
        unsigned int i = 0;
+       
+       DEBUG("rlm_sql (%s): - generate_sql_clients",inst->config->xlat_name);
 
-       DEBUG("rlm_sql (%s): Processing generate_sql_clients",
-             inst->config->xlat_name);
-
-       /* NAS query isn't xlat'ed */
-       strlcpy(querystr, inst->config->nas_query, sizeof(querystr));
-       DEBUG("rlm_sql (%s) in generate_sql_clients: query is %s",
-             inst->config->xlat_name, querystr);
+       if (inst->config->sql_nas_table == NULL){
+               radlog(L_ERR, "rlm_sql (%s): sql_nas_table is NULL.",inst->config->xlat_name);
+               return -1;
+       }
+       snprintf(querystr,MAX_QUERY_LEN - 1,"SELECT * FROM %s",inst->config->sql_nas_table);
 
+       DEBUG("rlm_sql (%s): Query: %s",inst->config->xlat_name,querystr);
        sqlsocket = sql_get_socket(inst);
        if (sqlsocket == NULL)
                return -1;
@@ -247,15 +264,14 @@ static int generate_sql_clients(SQL_INST *inst)
                row = sqlsocket->row;
                if (row == NULL)
                        break;
-       /*
-        *  The return data for each row MUST be in the following order:
-        *
-        *  0. Row ID (currently unused)
-        *  1. Name (or IP address)
-        *  2. Shortname
-        *  3. Type
-        *  4. Secret
-        */
+/*
+ * Format:
+ * Row1        Row2    Row3            Row4    Row5    Row6    Row7            Row8
+ *
+ * id  nasname shortname       type    ports   secret  community       description
+ *
+ */
+
                if (!row[0]){
                        radlog(L_ERR, "rlm_sql (%s): No row id found on pass %d",inst->config->xlat_name,i);
                        continue;
@@ -264,79 +280,101 @@ static int generate_sql_clients(SQL_INST *inst)
                        radlog(L_ERR, "rlm_sql (%s): No nasname found for row %s",inst->config->xlat_name,row[0]);
                        continue;
                }
+               if (strlen(row[1]) >= sizeof(c->longname)){
+                       radlog(L_ERR, "rlm_sql (%s): nasname of length %d is greater than the allowed maximum of %d",
+                               inst->config->xlat_name,strlen(row[1]),sizeof(c->longname) - 1);
+                       continue;
+               }       
+               
                if (!row[2]){
                        radlog(L_ERR, "rlm_sql (%s): No short name found for row %s",inst->config->xlat_name,row[0]);
                        continue;
                }
-               if (!row[4]){
+               if (strlen(row[2]) >= sizeof(c->shortname)){
+                       radlog(L_ERR, "rlm_sql (%s): shortname of length %d is greater than the allowed maximum of %d",
+                               inst->config->xlat_name,strlen(row[2]),sizeof(c->shortname) - 1);
+                       continue;
+               }
+               if (row[3] && strlen(row[3]) >= sizeof(c->nastype)){
+                       radlog(L_ERR, "rlm_sql (%s): nastype of length %d is greater than the allowed maximum of %d",
+                               inst->config->xlat_name,strlen(row[3]),sizeof(c->nastype) - 1);
+                       continue;
+               }
+               if (!row[5]){
                        radlog(L_ERR, "rlm_sql (%s): No secret found for row %s",inst->config->xlat_name,row[0]);
                        continue;
                }
+               if (strlen(row[5]) >= sizeof(c->secret)){
+                       radlog(L_ERR, "rlm_sql (%s): secret of length %d is greater than the allowed maximum of %d",
+                               inst->config->xlat_name,strlen(row[5]),sizeof(c->secret) - 1);
+                       continue;
+               }
 
                DEBUG("rlm_sql (%s): Read entry nasname=%s,shortname=%s,secret=%s",inst->config->xlat_name,
-                       row[1],row[2],row[4]);
+                       row[1],row[2],row[5]);
 
-               c = rad_malloc(sizeof(*c));
-               memset(c, 0, sizeof(*c));
+               c = rad_malloc(sizeof(RADCLIENT));
+               memset(c, 0, sizeof(RADCLIENT));
 
+               c->netmask = ~0;
+               netmask = strchr(row[1], '/');
+               
                /*
-                *      Look for prefixes
+                *      Look for netmasks.
                 */
-               c->prefix = -1;
-               prefix_ptr = strchr(row[1], '/');
-               if (prefix_ptr) {
-                       c->prefix = atoi(prefix_ptr + 1);
-                       if ((c->prefix < 0) || (c->prefix > 128)) {
-                               radlog(L_ERR, "rlm_sql (%s): Invalid Prefix value '%s' for IP.",
-                                      inst->config->xlat_name, prefix_ptr + 1);
+               c->netmask = ~0;
+               if (netmask) {
+                       int mask_length;
+
+                       mask_length = atoi(netmask + 1);
+                       if ((mask_length < 0) || (mask_length > 32)) {
+                               radlog(L_ERR, "rlm_sql (%s): Invalid value '%s' for IP network mask for nasname %s.",
+                                               inst->config->xlat_name, netmask + 1,row[1]);
                                free(c);
                                continue;
                        }
-                       /* Replace '/' with '\0' */
-                       *prefix_ptr = '\0';
+
+                       if (mask_length == 0) {
+                               c->netmask = 0;
+                       } else {
+                               c->netmask = ~0 << (32 - mask_length);
+                       }
+
+                       *netmask = '\0';
+                       c->netmask = htonl(c->netmask);
                }
 
-               /*
-                *      Always get the numeric representation of IP
-                */
-               if (ip_hton(row[1], AF_UNSPEC, &c->ipaddr) < 0) {
-                       radlog(L_CONS|L_ERR, "rlm_sql (%s): Failed to look up hostname %s: %s",
-                              inst->config->xlat_name,
-                              row[1], librad_errstr);
+               c->ipaddr = ip_getaddr(row[1]);
+               if (c->ipaddr == INADDR_NONE) {
+                       radlog(L_CONS|L_ERR, "rlm_sql (%s): Failed to look up hostname %s",
+                                       inst->config->xlat_name, row[1]);
                        free(c);
                        continue;
-               } else {
-                       char buffer[256];
-                       ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
-                       c->longname = strdup(buffer);
-               }
-
-               if (c->prefix < 0) switch (c->ipaddr.af) {
-               case AF_INET:
-                       c->prefix = 32;
-                       break;
-               case AF_INET6:
-                       c->prefix = 128;
-                       break;
-               default:
-                       break;
                }
 
                /*
-                *      Other values (secret, shortname, nastype)
+                *      Update the client name again...
                 */
-               c->secret = (u_char *)strdup(row[4]);
-               c->shortname = strdup(row[2]);
+               if (netmask) {
+                       *netmask = '/';
+                       c->ipaddr &= c->netmask;
+                       strcpy(c->longname, row[1]);
+               } else {
+                       ip_hostname(c->longname, sizeof(c->longname),
+                                       c->ipaddr);
+               }
+
+               strcpy((char *)c->secret, row[5]);
+               strcpy(c->shortname, row[2]);
                if(row[3] != NULL)
-                       c->nastype = strdup(row[3]);
+                       strcpy(c->nastype, row[3]);
+
+               DEBUG("rlm_sql (%s): Adding client %s (%s) to clients list",inst->config->xlat_name,
+                       c->longname,c->shortname);
+
+               c->next = mainconfig.clients;
+               mainconfig.clients = c;
 
-               DEBUG("rlm_sql (%s): Adding client %s (%s) to clients list",
-                     inst->config->xlat_name,
-                     c->longname,c->shortname);
-               if (!client_add(mainconfig.clients, c)) {
-                       client_free(c);
-                       return -1;
-               }
        }
        (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
        sql_release_socket(inst, sqlsocket);
@@ -414,94 +452,29 @@ static int sql_set_user(SQL_INST *inst, REQUEST *request, char *sqlusername, con
        pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
 
        if (username != NULL) {
-               strlcpy(tmpuser, username, sizeof(tmpuser));
+               strNcpy(tmpuser, username, MAX_STRING_LEN);
        } else if (strlen(inst->config->query_user)) {
                radius_xlat(tmpuser, sizeof(tmpuser), inst->config->query_user, request, NULL);
        } else {
                return 0;
        }
 
-       strlcpy(sqlusername, tmpuser, MAX_STRING_LEN);
-       DEBUG2("rlm_sql (%s): sql_set_user escaped user --> '%s'",
+       if (*tmpuser) {
+               strNcpy(sqlusername, tmpuser, MAX_STRING_LEN);
+               DEBUG2("rlm_sql (%s): sql_set_user escaped user --> '%s'",
                       inst->config->xlat_name, sqlusername);
-       vp = pairmake("SQL-User-Name", sqlusername, 0);
-       if (vp == NULL) {
-               radlog(L_ERR, "%s", librad_errstr);
-               return -1;
-       }
-
-       pairadd(&request->packet->vps, vp);
-       return 0;
-
-}
-
-
-static void sql_grouplist_free (SQL_GROUPLIST **group_list)
-{
-       SQL_GROUPLIST *last;
-
-       while(*group_list) {
-               last = *group_list;
-               *group_list = (*group_list)->next;
-               free(last);
-       }
-}
-
-
-static int sql_get_grouplist (SQL_INST *inst, SQLSOCK *sqlsocket, REQUEST *request, SQL_GROUPLIST **group_list)
-{
-       char    querystr[MAX_QUERY_LEN];
-       int     num_groups = 0;
-       SQL_ROW row;
-       SQL_GROUPLIST   *group_list_tmp;
-
-       /* NOTE: sql_set_user should have been run before calling this function */
-
-       group_list_tmp = *group_list = NULL;
-
-       if (inst->config->groupmemb_query[0] == 0)
-               return 1;
-
-       if (!radius_xlat(querystr, sizeof(querystr), inst->config->groupmemb_query, request, sql_escape_func)) {
-               radlog(L_ERR, "rlm_sql (%s): xlat failed.",
-                       inst->config->xlat_name);
-               return -1;
-       }
-
-       if (rlm_sql_select_query(sqlsocket, inst, querystr) < 0) {
-               radlog(L_ERR, "rlm_sql (%s): database query error, %s: %s",
-                       inst->config->xlat_name,querystr,
-                       (char *)(inst->module->sql_error)(sqlsocket,inst->config));
-               return -1;
-       }
-       while (rlm_sql_fetch_row(sqlsocket, inst) == 0) {
-               row = sqlsocket->row;
-               if (row == NULL)
-                       break;
-               if (row[0] == NULL){
-                       DEBUG("rlm_sql (%s): row[0] returned NULL",
-                               inst->config->xlat_name);
-                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-                       sql_grouplist_free(group_list);
+               vp = pairmake("SQL-User-Name", sqlusername, 0);
+               if (vp == NULL) {
+                       radlog(L_ERR, "%s", librad_errstr);
                        return -1;
                }
-               if (*group_list == NULL) {
-                       *group_list = rad_malloc(sizeof(SQL_GROUPLIST));
-                       group_list_tmp = *group_list;
-               } else {
-                       group_list_tmp->next = rad_malloc(sizeof(SQL_GROUPLIST));
-                       group_list_tmp = group_list_tmp->next;
-               }
-               group_list_tmp->next = NULL;
-               strlcpy(group_list_tmp->groupname, row[0], MAX_STRING_LEN);
-       }
 
-       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-
-       return num_groups;
+               pairadd(&request->packet->vps, vp);
+               return 0;
+       }
+       return -1;
 }
 
-
 /*
  * sql groupcmp function. That way we can do group comparisons (in the users file for example)
  * with the group memberships reciding in sql
@@ -513,16 +486,16 @@ static int sql_groupcmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE
                        VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 {
        SQLSOCK *sqlsocket;
+       SQL_ROW row;
        SQL_INST *inst = instance;
+       char querystr[MAX_QUERY_LEN];
        char sqlusername[MAX_STRING_LEN];
-       SQL_GROUPLIST *group_list, *group_list_tmp;
 
        check_pairs = check_pairs;
        reply_pairs = reply_pairs;
-       request = request;
 
        DEBUG("rlm_sql (%s): - sql_groupcmp", inst->config->xlat_name);
-       if (!check || !check->vp_strvalue || !check->length){
+       if (!check || !check->strvalue || !check->length){
                DEBUG("rlm_sql (%s): sql_groupcmp: Illegal group name",
                      inst->config->xlat_name);
                return 1;
@@ -532,189 +505,63 @@ static int sql_groupcmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE
                      inst->config->xlat_name);
                return 1;
        }
+       if (inst->config->groupmemb_query[0] == 0)
+               return 1;
        /*
         * Set, escape, and check the user attr here
         */
        if (sql_set_user(inst, req, sqlusername, NULL) < 0)
                return 1;
-
-       /*
-        *      Get a socket for this lookup
-        */
-       sqlsocket = sql_get_socket(inst);
-       if (sqlsocket == NULL) {
+       if (!radius_xlat(querystr, sizeof(querystr), inst->config->groupmemb_query, req, sql_escape_func)){
+               radlog(L_ERR, "rlm_sql (%s): xlat failed.",
+                      inst->config->xlat_name);
                /* Remove the username we (maybe) added above */
                pairdelete(&req->packet->vps, PW_SQL_USER_NAME);
                return 1;
        }
+       /* Remove the username we (maybe) added above */
+       pairdelete(&req->packet->vps, PW_SQL_USER_NAME);
 
-       /*
-        *      Get the list of groups this user is a member of
-        */
-       if (sql_get_grouplist(inst, sqlsocket, req, &group_list)) {
-               radlog(L_ERR, "rlm_sql (%s): Error getting group membership",
-                      inst->config->xlat_name);
-               /* Remove the username we (maybe) added above */
-               pairdelete(&req->packet->vps, PW_SQL_USER_NAME);
-               sql_release_socket(inst, sqlsocket);
+       sqlsocket = sql_get_socket(inst);
+       if (sqlsocket == NULL)
+               return 1;
+       if ((inst->module->sql_select_query)(sqlsocket,inst->config,querystr) <0){
+               radlog(L_ERR, "rlm_sql (%s): database query error, %s: %s",
+                      inst->config->xlat_name,querystr,
+                      (char *)(inst->module->sql_error)(sqlsocket,inst->config));
+               sql_release_socket(inst,sqlsocket);
                return 1;
        }
-
-       for (group_list_tmp = group_list; group_list_tmp != NULL; group_list_tmp = group_list_tmp->next) {
-               if (strcmp(group_list_tmp->groupname, check->vp_strvalue) == 0){
-                       DEBUG("rlm_sql (%s): - sql_groupcmp finished: User is a member of group %s",
-                             inst->config->xlat_name,
-                             (char *)check->vp_strvalue);
-                       /* Free the grouplist */
-                       sql_grouplist_free(&group_list);
-                       /* Remove the username we (maybe) added above */
-                       pairdelete(&req->packet->vps, PW_SQL_USER_NAME);
+       while (rlm_sql_fetch_row(sqlsocket, inst) == 0) {
+               row = sqlsocket->row;
+               if (row == NULL)
+                       break;
+               if (row[0] == NULL){
+                       DEBUG("rlm_sql (%s): row[0] returned NULL",
+                             inst->config->xlat_name);
+                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
                        sql_release_socket(inst, sqlsocket);
+                       return 1;
+               }
+               if (strcmp(row[0],check->strvalue) == 0){
+                       DEBUG("rlm_sql (%s): - sql_groupcmp finished: User belongs in group %s",
+                             inst->config->xlat_name,
+                             (char *)check->strvalue);
+                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);                       sql_release_socket(inst, sqlsocket);
                        return 0;
                }
        }
 
-       /* Free the grouplist */
-       sql_grouplist_free(&group_list);
-       /* Remove the username we (maybe) added above */
-       pairdelete(&req->packet->vps, PW_SQL_USER_NAME);
+       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
        sql_release_socket(inst,sqlsocket);
 
-       DEBUG("rlm_sql (%s): - sql_groupcmp finished: User is NOT a member of group %s",
-             inst->config->xlat_name, (char *)check->vp_strvalue);
+       DEBUG("rlm_sql (%s): - sql_groupcmp finished: User does not belong in group %s",
+             inst->config->xlat_name, (char *)check->strvalue);
 
        return 1;
 }
 
 
-
-static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sqlsocket, int *dofallthrough)
-{
-       VALUE_PAIR *check_tmp = NULL;
-       VALUE_PAIR *reply_tmp = NULL;
-       SQL_GROUPLIST *group_list, *group_list_tmp;
-       VALUE_PAIR *sql_group = NULL;
-       char    querystr[MAX_QUERY_LEN];
-       int found = 0;
-       int rows;
-
-       /*
-        *      Get the list of groups this user is a member of
-        */
-       if (sql_get_grouplist(inst, sqlsocket, request, &group_list)) {
-               radlog(L_ERR, "rlm_sql (%s): Error retrieving group list",
-                      inst->config->xlat_name);
-               return -1;
-       }
-
-       for (group_list_tmp = group_list; group_list_tmp != NULL && *dofallthrough != 0; group_list_tmp = group_list_tmp->next) {
-               /*
-                *      Add the Sql-Group attribute to the request list so we know
-                *      which group we're retrieving attributes for
-                */
-               sql_group = pairmake("Sql-Group", group_list_tmp->groupname, T_OP_EQ);
-               if (!sql_group) {
-                       radlog(L_ERR, "rlm_sql (%s): Error creating Sql-Group attribute",
-                              inst->config->xlat_name);
-                       return -1;
-               }
-               pairadd(&request->packet->vps, sql_group);
-               if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func)) {
-                       radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",
-                              inst->config->xlat_name);
-                       /* Remove the grouup we added above */
-                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
-                       return -1;
-               }
-               rows = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr);
-               if (rows < 0) {
-                       radlog(L_ERR, "rlm_sql (%s): Error retrieving check pairs for group %s",
-                              inst->config->xlat_name, group_list_tmp->groupname);
-                       /* Remove the grouup we added above */
-                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
-                       pairfree(&check_tmp);
-                       return -1;
-               } else if (rows > 0) {
-                       /*
-                        *      Only do this if *some* check pairs were returned
-                        */
-                       if (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0) {
-                               found = 1;
-                               DEBUG2("rlm_sql (%s): User found in group %s",
-                                       inst->config->xlat_name, group_list_tmp->groupname);
-                               /*
-                                *      Now get the reply pairs since the paircompare matched
-                                */
-                               if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func)) {
-                                       radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",
-                                              inst->config->xlat_name);
-                                       /* Remove the grouup we added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
-                                       pairfree(&check_tmp);
-                                       return -1;
-                               }
-                               if (sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr) < 0) {
-                                       radlog(L_ERR, "rlm_sql (%s): Error retrieving reply pairs for group %s",
-                                              inst->config->xlat_name, group_list_tmp->groupname);
-                                       /* Remove the grouup we added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
-                                       pairfree(&check_tmp);
-                                       pairfree(&reply_tmp);
-                                       return -1;
-                               }
-                               *dofallthrough = fallthrough(reply_tmp);
-                               pairxlatmove(request, &request->reply->vps, &reply_tmp);
-                               pairxlatmove(request, &request->config_items, &check_tmp);
-                       }
-               } else {
-                       /*
-                        *      rows == 0.  This is like having the username on a line
-                        *      in the user's file with no check vp's.  As such, we treat
-                        *      it as found and add the reply attributes, so that we
-                        *      match expected behavior
-                        */
-                       found = 1;
-                       DEBUG2("rlm_sql (%s): User found in group %s",
-                               inst->config->xlat_name, group_list_tmp->groupname);
-                       /*
-                        *      Now get the reply pairs since the paircompare matched
-                        */
-                       if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func)) {
-                               radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",
-                                      inst->config->xlat_name);
-                               /* Remove the grouup we added above */
-                               pairdelete(&request->packet->vps, PW_SQL_GROUP);
-                               pairfree(&check_tmp);
-                               return -1;
-                       }
-                       if (sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr) < 0) {
-                               radlog(L_ERR, "rlm_sql (%s): Error retrieving reply pairs for group %s",
-                                      inst->config->xlat_name, group_list_tmp->groupname);
-                               /* Remove the grouup we added above */
-                               pairdelete(&request->packet->vps, PW_SQL_GROUP);
-                               pairfree(&check_tmp);
-                               pairfree(&reply_tmp);
-                               return -1;
-                       }
-                       *dofallthrough = fallthrough(reply_tmp);
-                       pairxlatmove(request, &request->reply->vps, &reply_tmp);
-                       pairxlatmove(request, &request->config_items, &check_tmp);
-               }
-
-               /*
-                * Delete the Sql-Group we added above
-                * And clear out the pairlists
-                */
-               pairdelete(&request->packet->vps, PW_SQL_GROUP);
-               pairfree(&check_tmp);
-               pairfree(&reply_tmp);
-       }
-
-       sql_grouplist_free(&group_list);
-       return found;
-}
-
-
 static int rlm_sql_detach(void *instance)
 {
        SQL_INST *inst = instance;
@@ -729,7 +576,7 @@ static int rlm_sql_detach(void *instance)
                }
 
                if (inst->config->xlat_name) {
-                       xlat_unregister(inst->config->xlat_name,(RAD_XLAT_FUNC)sql_xlat);
+                       xlat_unregister(inst->config->xlat_name,sql_xlat);
                        free(inst->config->xlat_name);
                }
 
@@ -775,7 +622,7 @@ static int rlm_sql_detach(void *instance)
 static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
 {
        SQL_INST *inst;
-       const char *xlat_name;
+       char *xlat_name;
 
        inst = rad_malloc(sizeof(SQL_INST));
        memset(inst, 0, sizeof(SQL_INST));
@@ -797,7 +644,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                xlat_name = cf_section_name1(conf);
        if (xlat_name){
                inst->config->xlat_name = strdup(xlat_name);
-               xlat_register(xlat_name, (RAD_XLAT_FUNC)sql_xlat, inst);
+               xlat_register(xlat_name, sql_xlat, inst);
        }
 
        if (inst->config->num_sql_socks > MAX_SQL_SOCKS) {
@@ -865,6 +712,11 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
        return RLM_MODULE_OK;
 }
 
+static int rlm_sql_destroy(void)
+{
+       return 0;
+}
+
 
 static int rlm_sql_authorize(void *instance, REQUEST * request)
 {
@@ -872,29 +724,27 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
        VALUE_PAIR *reply_tmp = NULL;
        VALUE_PAIR *user_profile = NULL;
        int     found = 0;
-       int     dofallthrough = 1;
-       int     rows;
        SQLSOCK *sqlsocket;
        SQL_INST *inst = instance;
        char    querystr[MAX_QUERY_LEN];
        char    sqlusername[MAX_STRING_LEN];
+
        /*
-        * the profile username is used as the sqlusername during
-        * profile checking so that we don't overwrite the orignal
-        * sqlusername string
+        *      They MUST have a user name to do SQL authorization.
         */
-       char   profileusername[MAX_STRING_LEN];
+       if ((request->username == NULL) ||
+           (request->username->length == 0)) {
+               radlog(L_ERR, "rlm_sql (%s): zero length username not permitted\n", inst->config->xlat_name);
+               return RLM_MODULE_INVALID;
+       }
 
        /*
-        * Set, escape, and check the user attr here
+        *      Set, escape, and check the user attr here.
         */
        if (sql_set_user(inst, request, sqlusername, NULL) < 0)
                return RLM_MODULE_FAIL;
+       radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func);
 
-
-       /*
-        * reserve a socket
-        */
        sqlsocket = sql_get_socket(inst);
        if (sqlsocket == NULL) {
                /* Remove the username we (maybe) added above */
@@ -902,24 +752,22 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                return RLM_MODULE_FAIL;
        }
 
-
        /*
-        *  After this point, ALL 'return's MUST release the SQL socket!
+        *      After this point, ALL 'return's MUST release the SQL socket!
         */
 
+       found = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_USERDATA);
        /*
-        * Alright, start by getting the specific entry for the user
+        *      Find the entry for the user.
         */
-       if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func)) {
-               radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",
-                      inst->config->xlat_name);
-               sql_release_socket(inst, sqlsocket);
-               /* Remove the username we (maybe) added above */
-               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
-               return RLM_MODULE_FAIL;
-       }
-       rows = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr);
-       if (rows < 0) {
+       if (found > 0) {
+               radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func);
+               sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_GROUPDATA);
+               radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func);
+               sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_USERDATA);
+               radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func);
+               sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_GROUPDATA);
+       } else if (found < 0) {
                radlog(L_ERR, "rlm_sql (%s): SQL query error; rejecting user",
                       inst->config->xlat_name);
                sql_release_socket(inst, sqlsocket);
@@ -927,73 +775,26 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
                pairfree(&check_tmp);
                return RLM_MODULE_FAIL;
-       } else if (rows > 0) {
-               /*
-                *      Only do this if *some* check pairs were returned
-                */
-               if (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0) {
-                       found = 1;
-                       DEBUG2("rlm_sql (%s): User found in radcheck table", inst->config->xlat_name);
-                       /*
-                        *      Now get the reply pairs since the paircompare matched
-                        */
-                       if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func)) {
-                               radlog(L_ERR, "rlm_sql (%s): Error generating query; rejecting user",
-                                      inst->config->xlat_name);
-                               sql_release_socket(inst, sqlsocket);
-                               /* Remove the username we (maybe) added above */
-                               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
-                               pairfree(&check_tmp);
-                               return RLM_MODULE_FAIL;
-                       }
-                       if (sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr) < 0) {
-                               radlog(L_ERR, "rlm_sql (%s): SQL query error; rejecting user",
-                                      inst->config->xlat_name);
-                               sql_release_socket(inst, sqlsocket);
-                               /* Remove the username we (maybe) added above */
-                               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
-                               pairfree(&check_tmp);
-                               pairfree(&reply_tmp);
-                               return RLM_MODULE_FAIL;
-                       }
-                       if (!inst->config->read_groups)
-                               dofallthrough = fallthrough(reply_tmp);
-                       pairxlatmove(request, &request->reply->vps, &reply_tmp);
-                       pairxlatmove(request, &request->config_items, &check_tmp);
-               }
-       }
 
-       /*
-        *      Clear out the pairlists
-        */
-       pairfree(&check_tmp);
-       pairfree(&reply_tmp);
+       } else {
+               radlog(L_DBG, "rlm_sql (%s): User %s not found in radcheck",
+                      inst->config->xlat_name, sqlusername);
 
-       /*
-        *      dofallthrough is set to 1 by default so that if the user information
-        *      is not found, we will still process groups.  If the user information,
-        *      however, *is* found, Fall-Through must be set in order to process
-        *      the groups as well
-        */
-       if (dofallthrough) {
-               rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough);
-               if (rows < 0) {
-                       radlog(L_ERR, "rlm_sql (%s): Error processing groups; rejecting user",
-                              inst->config->xlat_name);
-                       sql_release_socket(inst, sqlsocket);
-                       /* Remove the username we (maybe) added above */
-                       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
-                       return RLM_MODULE_FAIL;
-               } else if (rows > 0) {
-                       found = 1;
-               }
-       }
+                /*
+                * We didn't find the user in radcheck, so we try looking
+                * for radgroupcheck entry
+                */
+                radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func);
+                found = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_GROUPDATA);
+                radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func);
+                sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_GROUPDATA);
+        }
+       if (!found)
+               radlog(L_DBG, "rlm_sql (%s): User %s not found in radgroupcheck",
+                      inst->config->xlat_name, sqlusername);
+       if (found || (!found && inst->config->query_on_not_found)){
+               int def_found = 0;
 
-       /*
-        *      repeat the above process with the default profile or User-Profile
-        */
-       if (dofallthrough) {
-               int profile_found = 0;
                /*
                * Check for a default_profile or for a User-Profile.
                */
@@ -1002,49 +803,74 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                        char *profile = inst->config->default_profile;
 
                        if (user_profile != NULL)
-                               profile = user_profile->vp_strvalue;
+                               profile = user_profile->strvalue;
                        if (profile && strlen(profile)){
                                radlog(L_DBG, "rlm_sql (%s): Checking profile %s",
                                       inst->config->xlat_name, profile);
-                               if (sql_set_user(inst, request, profileusername, profile) < 0) {
-                                       radlog(L_ERR, "rlm_sql (%s): Error setting profile; rejecting user",
-                                              inst->config->xlat_name);
+                               if (sql_set_user(inst, request, sqlusername, profile) < 0) {
                                        sql_release_socket(inst, sqlsocket);
-                                       /* Remove the username we (maybe) added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+                                       pairfree(&reply_tmp);
+                                       pairfree(&check_tmp);
                                        return RLM_MODULE_FAIL;
-                               } else {
-                                       profile_found = 1;
                                }
-                       }
-               }
-
-               if (profile_found) {
-                       rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough);
-                       if (rows < 0) {
-                               radlog(L_ERR, "rlm_sql (%s): Error processing profile groups; rejecting user",
-                                      inst->config->xlat_name);
-                               sql_release_socket(inst, sqlsocket);
-                               /* Remove the username we (maybe) added above */
-                               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
-                               return RLM_MODULE_FAIL;
-                       } else if (rows > 0) {
-                               found = 1;
+                               radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query,
+                                                                       request, sql_escape_func);
+                               def_found = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr, PW_VP_GROUPDATA);
+                               if (def_found)
+                                       found = 1;
+                               radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query,
+                                                                       request, sql_escape_func);
+                               sql_getvpdata(inst, sqlsocket, &reply_tmp, querystr, PW_VP_GROUPDATA);
                        }
                }
        }
 
-       /* Remove the username we (maybe) added above */
-       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+       /*
+        *      We don't need the SQL socket anymore.
+        */
        sql_release_socket(inst, sqlsocket);
 
        if (!found) {
-               radlog(L_DBG, "rlm_sql (%s): User %s not found",
+               radlog(L_DBG, "rlm_sql (%s): User not found",
+                      inst->config->xlat_name);
+               /* Remove the username we (maybe) added above */
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+               pairfree(&reply_tmp);
+               pairfree(&check_tmp);
+               return RLM_MODULE_NOTFOUND;
+       }
+
+       /*
+        * Uncomment these lines for debugging
+        * Recompile, and run 'radiusd -X'
+        */
+
+       /*
+       DEBUG2("rlm_sql:  check items");
+       vp_listdebug(check_tmp);
+       DEBUG2("rlm_sql:  reply items");
+       vp_listdebug(reply_tmp);
+       */
+
+       if (paircmp(request, request->packet->vps, check_tmp, &reply_tmp) != 0) {
+               radlog(L_INFO, "rlm_sql (%s): No matching entry in the database for request from user [%s]",
                       inst->config->xlat_name, sqlusername);
+               /* Remove the username we (maybe) added above */
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+               pairfree(&reply_tmp);
+               pairfree(&check_tmp);
                return RLM_MODULE_NOTFOUND;
-       } else {
-               return RLM_MODULE_OK;
        }
+
+       pairxlatmove(request, &request->reply->vps, &reply_tmp);
+       pairxlatmove(request, &request->config_items, &check_tmp);
+       pairfree(&reply_tmp);
+       pairfree(&check_tmp);
+
+       /* Remove the username we (maybe) added above */
+       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+
+       return RLM_MODULE_OK;
 }
 
 /*
@@ -1072,7 +898,7 @@ static int rlm_sql_accounting(void *instance, REQUEST * request) {
         * Find the Acct Status Type
         */
        if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {
-               acctstatustype = pair->vp_integer;
+               acctstatustype = pair->lvalue;
        } else {
                radius_xlat(logstr, sizeof(logstr), "packet has no accounting status type. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);
                radlog(L_ERR, "rlm_sql (%s) in sql_accounting: %s",
@@ -1240,7 +1066,7 @@ static int rlm_sql_accounting(void *instance, REQUEST * request) {
                                                 * table with bogus crap
                                                 */
                                                if ((pair = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME)) != NULL)
-                                                       acctsessiontime = pair->vp_integer;
+                                                       acctsessiontime = pair->lvalue;
 
                                                if (acctsessiontime <= 0) {
                                                        radius_xlat(logstr, sizeof(logstr), "stop packet with zero session length. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);
@@ -1357,11 +1183,10 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
                return RLM_MODULE_OK;
        }
 
-       /*
-        *      Looks like too many sessions, so let's start verifying
-        *      them, unless told to rely on count query only.
-        */
-       if (inst->config->simul_verify_query[0] == '\0') {
+       /* Looks like too many sessions, so lets start verifying them */
+
+       if (inst->config->simul_verify_query[0] == 0) {
+               /* No verify query defined, so skip verify step and rely on count query only */
                sql_release_socket(inst, sqlsocket);
                return RLM_MODULE_OK;
        }
@@ -1379,9 +1204,9 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
        request->simul_count = 0;
 
         if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS)) != NULL)
-                ipno = vp->vp_ipaddr;
+                ipno = vp->lvalue;
         if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
-                call_num = vp->vp_strvalue;
+                call_num = vp->strvalue;
 
 
        while (rlm_sql_fetch_row(sqlsocket, inst) == 0) {
@@ -1407,34 +1232,19 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
 
                check = rad_check_ts(nas_addr, nas_port, row[2], row[1]);
 
-               if (check == 0) {
-                       /*
-                        *      Stale record - zap it.
-                        */
-                       if (inst->config->deletestalesessions == TRUE) {
-                               uint32_t framed_addr = 0;
-                               char proto = 0;
-                               int sess_time = 0;
-
-                               if (row[5])
-                                       framed_addr = inet_addr(row[5]);
-                               if (row[7]){
-                                       if (strcmp(row[7], "PPP") == 0)
-                                               proto = 'P';
-                                       else if (strcmp(row[7], "SLIP") == 0)
-                                               proto = 'S';
-                               }
-                               if (row[8])
-                                       sess_time = atoi(row[8]);
-                               session_zap(request, nas_addr, nas_port,
-                                           row[2], row[1], framed_addr,
-                                           proto, sess_time);
-                       }
+                /*
+                 *      Failed to check the terminal server for
+                 *      duplicate logins: Return an error.
+                 */
+               if (check < 0) {
+                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
+                       sql_release_socket(inst, sqlsocket);
+                       DEBUG("rlm_sql (%s) rad_check_ts() failed.",
+                             inst->config->xlat_name);
+                       return RLM_MODULE_FAIL;
                }
-               else if (check == 1) {
-                       /*
-                        *      User is still logged in.
-                        */
+
+               if(check == 1) {
                        ++request->simul_count;
 
                         /*
@@ -1447,26 +1257,31 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
                                 request->simul_mpp = 2;
                }
                else {
-                       /*
-                        *      Failed to check the terminal server for
-                        *      duplicate logins: return an error.
-                        */
-                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-                       sql_release_socket(inst, sqlsocket);
-                       radlog(L_ERR, "rlm_sql (%s): sql_checksimul: Failed to check the terminal server for user '%s'.", inst->config->xlat_name, row[2]);
-                       return RLM_MODULE_FAIL;
+                        /*
+                         *      Stale record - zap it.
+                         */
+                       uint32_t framed_addr = 0;
+                       char proto = 'P';
+
+                       if (row[5])
+                               framed_addr = inet_addr(row[5]);
+                       if (row[7])
+                               if (strcmp(row[7],"SLIP") == 0)
+                                       proto = 'S';
+
+                       session_zap(request,
+                                   nas_addr,nas_port,row[2],row[1],
+                                   framed_addr, proto);
                }
        }
 
        (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
        sql_release_socket(inst, sqlsocket);
 
-       /*
-        *      The Auth module apparently looks at request->simul_count,
-        *      not the return value of this module when deciding to deny
-        *      a call for too many sessions.
-        */
+       /* The Auth module apparently looks at request->simul_count, not the return value
+          of this module when deciding to deny a call for too many sessions */
        return RLM_MODULE_OK;
+
 }
 
 /*
@@ -1516,11 +1331,10 @@ static int rlm_sql_postauth(void *instance, REQUEST *request) {
 
 /* globally exported name */
 module_t rlm_sql = {
-       RLM_MODULE_INIT,
        "SQL",
        RLM_TYPE_THREAD_SAFE,   /* type: reserved */
+       rlm_sql_init,           /* initialization */
        rlm_sql_instantiate,    /* instantiation */
-       rlm_sql_detach,         /* detach */
        {
                NULL,                   /* authentication */
                rlm_sql_authorize,      /* authorization */
@@ -1531,4 +1345,6 @@ module_t rlm_sql = {
                NULL,                   /* post-proxy */
                rlm_sql_postauth        /* post-auth */
        },
+       rlm_sql_detach,         /* detach */
+       rlm_sql_destroy,        /* destroy */
 };
index b69539a..03e47ff 100644 (file)
@@ -8,9 +8,6 @@
 #ifndef _RLM_SQL_H
 #define _RLM_SQL_H
 
-#include <freeradius-devel/ident.h>
-RCSIDH(rlm_sql_h, "$Id$")
-
 #ifdef HAVE_PTHREAD_H
 #include        <pthread.h>
 #endif
@@ -18,10 +15,15 @@ RCSIDH(rlm_sql_h, "$Id$")
 #include       <ltdl.h>
 
 #include "conf.h"
+#include "conffile.h"
 
 #define SQLSOCK_LOCKED         0
 #define SQLSOCK_UNLOCKED       1
 
+#define PW_VP_USERDATA         1
+#define PW_VP_GROUPDATA                2
+#define PW_VP_REALMDATA                3
+
 #define PW_ITEM_CHECK                  0
 #define PW_ITEM_REPLY                  1
 
@@ -67,20 +69,15 @@ typedef struct sql_inst {
        rlm_sql_module_t *module;
 } SQL_INST;
 
-typedef struct sql_grouplist {
-       char                    groupname[MAX_STRING_LEN];
-       struct sql_grouplist    *next;
-} SQL_GROUPLIST;
-
 
 int     sql_init_socketpool(SQL_INST * inst);
 void    sql_poolfree(SQL_INST * inst);
 int     sql_close_socket(SQL_INST *inst, SQLSOCK * sqlsocket);
 SQLSOCK *sql_get_socket(SQL_INST * inst);
 int     sql_release_socket(SQL_INST * inst, SQLSOCK * sqlsocket);
-int     sql_userparse(VALUE_PAIR ** first_pair, SQL_ROW row);
+int     sql_userparse(VALUE_PAIR ** first_pair, SQL_ROW row, int mode);
 int     sql_read_realms(SQLSOCK * sqlsocket);
-int     sql_getvpdata(SQL_INST * inst, SQLSOCK * sqlsocket, VALUE_PAIR **pair, char *query);
+int     sql_getvpdata(SQL_INST * inst, SQLSOCK * sqlsocket, VALUE_PAIR **pair, char *query, int mode);
 int     sql_read_naslist(SQLSOCK * sqlsocket);
 int     sql_read_clients(SQLSOCK * sqlsocket);
 int     sql_dict_init(SQLSOCK * sqlsocket);
index 72c164b..6888477 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2000  Mike Machado <mike@innercite.com>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  * Copyright 2001  Chad Miller <cmiller@surfsouth.com>
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
 
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <sys/time.h>
 #include       <sys/file.h>
+#include       <string.h>
 #include       <sys/stat.h>
+#include       <netinet/in.h>
 
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <netdb.h>
 #include       <pwd.h>
+#include       <time.h>
 #include       <ctype.h>
+#include       <unistd.h>
 #include       <signal.h>
+#include       <errno.h>
 #include       <sys/wait.h>
 
+#include       "radiusd.h"
+#include       "conffile.h"
 #include       "rlm_sql.h"
 
 #ifdef HAVE_PTHREAD_H
+#include       <pthread.h>
 #endif
 
 
@@ -315,9 +325,9 @@ int sql_release_socket(SQL_INST * inst, SQLSOCK * sqlsocket)
  *     Purpose: Read entries from the database and fill VALUE_PAIR structures
  *
  *************************************************************************/
-int sql_userparse(VALUE_PAIR ** first_pair, SQL_ROW row)
+int sql_userparse(VALUE_PAIR ** first_pair, SQL_ROW row, int querymode)
 {
-       VALUE_PAIR *pair;
+       VALUE_PAIR *pair, *check;
        char *ptr, *value;
        char buf[MAX_STRING_LEN];
        char do_xlat = 0;
@@ -396,11 +406,25 @@ int sql_userparse(VALUE_PAIR ** first_pair, SQL_ROW row)
        }
        if (do_xlat) {
                pair->flags.do_xlat = 1;
-               strlcpy(pair->vp_strvalue, buf, sizeof(pair->vp_strvalue));
+               strNcpy(pair->strvalue, buf, sizeof(pair->strvalue));
                pair->length = 0;
        }
 
        /*
+        *      If attribute is already there, skip it because we
+        *      checked usercheck first and we want user settings to
+        *      override group settings
+        */
+       if (operator != T_OP_ADD && (check = pairfind(*first_pair, pair->attribute)) != NULL &&
+#ifdef ASCEND_BINARY
+           pair->type != PW_TYPE_ABINARY &&
+#endif
+           querymode == PW_VP_GROUPDATA) {
+               pairbasicfree(pair);
+               return 0;
+       }
+
+       /*
         *      Add the pair into the packet
         */
        pairadd(first_pair, pair);
@@ -548,7 +572,7 @@ int rlm_sql_select_query(SQLSOCK *sqlsocket, SQL_INST *inst, char *query)
  *     Purpose: Get any group check or reply pairs
  *
  *************************************************************************/
-int sql_getvpdata(SQL_INST * inst, SQLSOCK * sqlsocket, VALUE_PAIR **pair, char *query)
+int sql_getvpdata(SQL_INST * inst, SQLSOCK * sqlsocket, VALUE_PAIR **pair, char *query, int mode)
 {
        SQL_ROW row;
        int     rows = 0;
@@ -568,7 +592,7 @@ int sql_getvpdata(SQL_INST * inst, SQLSOCK * sqlsocket, VALUE_PAIR **pair, char
                row = sqlsocket->row;
                if (!row)
                        break;
-               if (sql_userparse(pair, row) != 0) {
+               if (sql_userparse(pair, row, mode) != 0) {
                        radlog(L_ERR | L_CONS, "rlm_sql (%s): Error getting data from database", inst->config->xlat_name);
                        (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
                        return -1;
index bd1c798..8705845 100644 (file)
@@ -7,7 +7,6 @@
  *  Author:     Nicolas Baradakis <nicolas.baradakis@cegetel.net>
  *
  *  Copyright (C) 2005 Cegetel
- *  Copyright 2006 The FreeRADIUS server project
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "autoconf.h"
 
 #include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <sys/stat.h>
 
+#include "libradius.h"
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
+static const char rcsid[] = "$Id$";
+
 static int sql_log_instantiate(CONF_SECTION *conf, void **instance);
 static int sql_log_detach(void *instance);
 static int sql_log_accounting(void *instance, REQUEST *request);
@@ -226,7 +230,7 @@ static int sql_set_user(rlm_sql_log_t *inst, REQUEST *request, char *sqlusername
        pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
 
        if (username != NULL) {
-               strlcpy(tmpuser, username, MAX_STRING_LEN);
+               strNcpy(tmpuser, username, MAX_STRING_LEN);
        } else if (inst->sql_user_name[0] != '\0') {
                radius_xlat(tmpuser, sizeof(tmpuser), inst->sql_user_name,
                            request, NULL);
@@ -235,7 +239,7 @@ static int sql_set_user(rlm_sql_log_t *inst, REQUEST *request, char *sqlusername
        }
 
        if (tmpuser[0] != '\0') {
-               strlcpy(sqlusername, tmpuser, sizeof(tmpuser));
+               strNcpy(sqlusername, tmpuser, sizeof(tmpuser));
                DEBUG2("rlm_sql_log (%s): sql_set_user escaped user --> '%s'",
                       inst->name, sqlusername);
                vp = pairmake("SQL-User-Name", sqlusername, 0);
@@ -372,9 +376,9 @@ static int sql_log_accounting(void *instance, REQUEST *request)
        }
 
        /* Search the query in conf section of the module */
-       if ((dval = dict_valbyattr(PW_ACCT_STATUS_TYPE, pair->vp_integer)) == NULL) {
+       if ((dval = dict_valbyattr(PW_ACCT_STATUS_TYPE, pair->lvalue)) == NULL) {
                radlog(L_ERR, "rlm_sql_log (%s): Unsupported Acct-Status-Type = %d",
-                      inst->name, pair->vp_integer);
+                      inst->name, pair->lvalue);
                return RLM_MODULE_NOOP;
        }
        if ((cp = cf_pair_find(inst->conf_section, dval->name)) == NULL) {
@@ -424,11 +428,10 @@ static int sql_log_postauth(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_sql_log = {
-       RLM_MODULE_INIT,
        "sql_log",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        sql_log_instantiate,            /* instantiation */
-       sql_log_detach,                 /* detach */
        {
                NULL,                   /* authentication */
                NULL,                   /* authorization */
@@ -439,4 +442,6 @@ module_t rlm_sql_log = {
                NULL,                   /* post-proxy */
                sql_log_postauth        /* post-auth */
        },
+       sql_log_detach,                 /* detach */
+       NULL,                           /* destroy */
 };
index bd853f0..3e7fdb5 100644 (file)
@@ -4,10 +4,6 @@
 
 TARGET      = @targetname@
 SRCS        = rlm_sqlcounter.c
-HEADERS     =
-RLM_CFLAGS  = @sqlcounter_cflags@
-RLM_LIBS    = @sqlcounter_ldflags@
-RLM_INSTALL =
 
 include ../rules.mak
 
diff --git a/src/modules/rlm_sqlcounter/acconfig.h b/src/modules/rlm_sqlcounter/acconfig.h
new file mode 100644 (file)
index 0000000..1ec861a
--- /dev/null
@@ -0,0 +1 @@
+/* do we need anything in here? */
index 14531ed..e8a6040 100644 (file)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.4 .
+# From configure.in Revision: 1.2.6.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -273,7 +273,7 @@ PACKAGE_STRING=
 PACKAGE_BUGREPORT=
 
 ac_unique_file="rlm_sqlcounter.c"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP sqlcounter_ldflags sqlcounter_cflags targetname LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS targetname LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -714,26 +714,6 @@ ac_env_target_alias_set=${target_alias+set}
 ac_env_target_alias_value=$target_alias
 ac_cv_env_target_alias_set=${target_alias+set}
 ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
 
 #
 # Report the --help message.
@@ -801,18 +781,6 @@ if test -n "$ac_init_help"; then
 
   cat <<\_ACEOF
 
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
-              headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
 _ACEOF
 fi
 
@@ -901,7 +869,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -1253,1164 +1221,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 if test x$with_rlm_sqlcounter != xno; then
 
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  test -n "$ac_ct_CC" && break
-done
-
-  CC=$ac_ct_CC
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
-  (eval $ac_link_default) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Find the output, starting from the most likely.  This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
-       ;;
-    conftest.$ac_ext )
-       # This is the source file.
-       ;;
-    [ab].out )
-       # We found the default executable, but exeext='' is most
-       # certainly right.
-       break;;
-    *.* )
-       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       # FIXME: I believe we export ac_cv_exeext for Libtool,
-       # but it would be cool to find out if it's true.  Does anybody
-       # maintain Libtool? --akim.
-       export ac_cv_exeext
-       break;;
-    * )
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-         export ac_cv_exeext
-         break;;
-    * ) break;;
-  esac
-done
-else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std1 is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std1.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX                  -qlanglvl=ansi
-# Ultrix and OSF/1     -std1
-# HP-UX 10.20 and later        -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4                 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_stdc=$ac_arg
-break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
-  x|xno)
-    echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
-  *)
-    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
-    CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
-# Some people use a C++ compiler to compile C.  Since we use `exit',
-# in C++ we need to declare it.  In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
-  choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  for ac_declaration in \
-   '' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
-fi
-
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether non-existent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether non-existent headers
-  # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  # Broken: success on invalid input.
-continue
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
-else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
 
        targetname=rlm_sqlcounter
 else
@@ -2418,24 +1228,6 @@ else
        echo \*\*\* module rlm_sqlcounter is disabled.
 fi
 
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               { { echo "$as_me:$LINENO: error: set --without-rlm_sqlcounter to disable it explicitly." >&5
-echo "$as_me: error: set --without-rlm_sqlcounter to disable it explicitly." >&2;}
-   { (exit 1); exit 1; }; }
-       else
-               { echo "$as_me:$LINENO: WARNING: silently not building rlm_sqlcounter." >&5
-echo "$as_me: WARNING: silently not building rlm_sqlcounter." >&2;}
-               { echo "$as_me:$LINENO: WARNING: FAILURE: rlm_sqlcounter requires: $fail." >&5
-echo "$as_me: WARNING: FAILURE: rlm_sqlcounter requires: $fail." >&2;};
-               targetname=""
-       fi
-fi
-
-sqlcounter_ldflags=$SMART_LIBS
-sqlcounter_cflags=$SMART_CFLAGS
-
-
 
           ac_config_files="$ac_config_files Makefile"
 cat >confcache <<\_ACEOF
@@ -3072,16 +1864,6 @@ s,@ECHO_C@,$ECHO_C,;t t
 s,@ECHO_N@,$ECHO_N,;t t
 s,@ECHO_T@,$ECHO_T,;t t
 s,@LIBS@,$LIBS,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@CPP@,$CPP,;t t
-s,@sqlcounter_ldflags@,$sqlcounter_ldflags,;t t
-s,@sqlcounter_cflags@,$sqlcounter_cflags,;t t
 s,@targetname@,$targetname,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
@@ -3247,6 +2029,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -3285,12 +2072,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index fc66dd7..7230e45 100644 (file)
@@ -1,12 +1,11 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_sqlcounter.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_sqlcounter])
 
 if test x$with_[]modname != xno; then
 
-       AC_PROG_CC
-       AC_PROG_CPP
+       dnl  This module doesn't need any autoconf test which is not already
+       dnl  in top-level configure.
 
        targetname=modname
 else
@@ -14,19 +13,5 @@ else
        echo \*\*\* module modname is disabled.
 fi
 
-if test x"$fail" != x""; then
-       if test x"${enable_strict_dependencies}" = x"yes"; then
-               AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
-       else
-               AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
-               targetname=""
-       fi
-fi
-
-sqlcounter_ldflags=$SMART_LIBS
-sqlcounter_cflags=$SMART_CFLAGS
-AC_SUBST(sqlcounter_ldflags)
-AC_SUBST(sqlcounter_cflags)
 AC_SUBST(targetname)
 AC_OUTPUT(Makefile)
index 3b5071f..379c687 100644 (file)
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2001,2006  The FreeRADIUS server project
+ * Copyright 2001  The FreeRADIUS server project
  * Copyright 2001  Alan DeKok <aland@ox.org>
  */
 
 /* This module is based directly on the rlm_counter module */
 
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
+#include "autoconf.h"
+#include "libradius.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+
 #define MAX_QUERY_LEN 1024
 
-static int sqlcounter_detach(void *instance);
+#include <time.h>
 
-/*
- *     Note: When your counter spans more than 1 period (ie 3 months
- *     or 2 weeks), this module probably does NOT do what you want! It
- *     calculates the range of dates to count across by first calculating
- *     the End of the Current period and then subtracting the number of
- *     periods you specify from that to determine the beginning of the
- *     range.
+
+/*     Note: When your counter spans more than 1 period (ie 3 months or 2 weeks), this module
+ *     probably does NOT do what you want!  It calculates the range of dates to count across
+ *     by first calculating the End of the Current period and then subtracting the number of
+ *     periods you specify from that to determine the beginning of the range.
  *
- *     For example, if you specify a 3 month counter and today is June 15th,
- *     the end of the current period is June 30. Subtracting 3 months from
- *     that gives April 1st. So, the counter will sum radacct entries from
- *     April 1st to June 30. Then, next month, it will sum entries from
- *     May 1st to July 31st.
+ *     For example, if you specify a 3 month counter and today is June 15th, the end of the current
+ *     period is June 30. Subtracting 3 months from that gives April 1st.  So, the counter will
+ *     sum radacct entries from April 1st to June 30. Then, next month, it will sum entries
+ *     from May 1st to July 31st.
  *
- *     To fix this behavior, we need to add some way of storing the Next
- *     Reset Time.
+ *     To fix this behavior, we need to add some way of storing the Next Reset Time
  */
 
+
+static const char rcsid[] = "$Id$";
+
 /*
  *     Define a structure for our module configuration.
  *
@@ -86,7 +89,7 @@ typedef struct rlm_sqlcounter_t {
  *     to the strdup'd string into 'config.string'.  This gets around
  *     buffer over-flows.
  */
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
   { "counter-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,counter_name), NULL,  NULL },
   { "check-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,check_name), NULL, NULL },
   { "reply-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,reply_name), NULL, NULL },
@@ -151,28 +154,28 @@ static int sql_escape_func(char *out, int outlen, const char *in)
 
 static int find_next_reset(rlm_sqlcounter_t *data, time_t timeval)
 {
-       int ret = 0;
-       size_t len;
-       unsigned int num = 1;
-       char last = '\0';
+       int ret=0;
+       unsigned int num=1;
+       char last = 0;
        struct tm *tm, s_tm;
        char sCurrentTime[40], sNextTime[40];
 
        tm = localtime_r(&timeval, &s_tm);
-       len = strftime(sCurrentTime, sizeof(sCurrentTime), "%Y-%m-%d %H:%M:%S", tm);
-       if (len == 0) *sCurrentTime = '\0';
+       strftime(sCurrentTime, sizeof(sCurrentTime),"%Y-%m-%d %H:%M:%S",tm);
        tm->tm_sec = tm->tm_min = 0;
 
        if (data->reset == NULL)
                return -1;
        if (isdigit((int) data->reset[0])){
+               unsigned int len=0;
+
                len = strlen(data->reset);
                if (len == 0)
                        return -1;
                last = data->reset[len - 1];
                if (!isalpha((int) last))
                        last = 'd';
-               num = atoi(data->reset);
+/*             num = atoi(data->reset); */
                DEBUG("rlm_sqlcounter: num=%d, last=%c",num,last);
        }
        if (strcmp(data->reset, "hourly") == 0 || last == 'h') {
@@ -207,11 +210,9 @@ static int find_next_reset(rlm_sqlcounter_t *data, time_t timeval)
                        data->reset);
                return -1;
        }
-
-       len = strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
-       if (len == 0) *sNextTime = '\0';
-       DEBUG2("rlm_sqlcounter: Current Time: %li [%s], Next reset %li [%s]",
-               timeval, sCurrentTime, data->reset_time, sNextTime);
+       strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
+       DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Next reset %d [%s]",
+               (int)timeval,sCurrentTime,(int)data->reset_time, sNextTime);
 
        return ret;
 }
@@ -223,21 +224,21 @@ static int find_next_reset(rlm_sqlcounter_t *data, time_t timeval)
 
 static int find_prev_reset(rlm_sqlcounter_t *data, time_t timeval)
 {
-       int ret = 0;
-       size_t len;
-       unsigned int num = 1;
-       char last = '\0';
+       int ret=0;
+       unsigned int num=1;
+       char last = 0;
        struct tm *tm, s_tm;
        char sCurrentTime[40], sPrevTime[40];
 
        tm = localtime_r(&timeval, &s_tm);
-       len = strftime(sCurrentTime, sizeof(sCurrentTime), "%Y-%m-%d %H:%M:%S", tm);
-       if (len == 0) *sCurrentTime = '\0';
+       strftime(sCurrentTime, sizeof(sCurrentTime),"%Y-%m-%d %H:%M:%S",tm);
        tm->tm_sec = tm->tm_min = 0;
 
        if (data->reset == NULL)
                return -1;
        if (isdigit((int) data->reset[0])){
+               unsigned int len=0;
+
                len = strlen(data->reset);
                if (len == 0)
                        return -1;
@@ -279,10 +280,9 @@ static int find_prev_reset(rlm_sqlcounter_t *data, time_t timeval)
                        data->reset);
                return -1;
        }
-       len = strftime(sPrevTime, sizeof(sPrevTime), "%Y-%m-%d %H:%M:%S", tm);
-       if (len == 0) *sPrevTime = '\0';
-       DEBUG2("rlm_sqlcounter: Current Time: %li [%s], Prev reset %li [%s]",
-              timeval, sCurrentTime, data->last_reset, sPrevTime);
+       strftime(sPrevTime, sizeof(sPrevTime),"%Y-%m-%d %H:%M:%S",tm);
+       DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Prev reset %d [%s]",
+               (int)timeval,sCurrentTime,(int)data->last_reset, sPrevTime);
 
        return ret;
 }
@@ -305,7 +305,6 @@ static int sqlcounter_expand(char *out, int outlen, const char *fmt, void *insta
        const char *p;
        char *q;
        char tmpdt[40]; /* For temporary storing of dates */
-       int openbraces=0;
 
        q = out;
        for (p = fmt; *p ; p++) {
@@ -315,15 +314,6 @@ static int sqlcounter_expand(char *out, int outlen, const char *fmt, void *insta
                        break;
                c = *p;
                if ((c != '%') && (c != '$') && (c != '\\')) {
-                       /*
-                        * We check if we're inside an open brace.  If we are
-                        * then we assume this brace is NOT literal, but is
-                        * a closing brace and apply it
-                        */
-                       if((c == '}') && openbraces) {
-                               openbraces--;
-                               continue;
-                       }
                        *q++ = *p;
                        continue;
                }
@@ -349,20 +339,20 @@ static int sqlcounter_expand(char *out, int outlen, const char *fmt, void *insta
                                *q++ = *p;
                        case 'b': /* last_reset */
                                snprintf(tmpdt, sizeof(tmpdt), "%lu", data->last_reset);
-                               strlcpy(q, tmpdt, freespace);
+                               strNcpy(q, tmpdt, freespace);
                                q += strlen(q);
                                break;
                        case 'e': /* reset_time */
                                snprintf(tmpdt, sizeof(tmpdt), "%lu", data->reset_time);
-                               strlcpy(q, tmpdt, freespace);
+                               strNcpy(q, tmpdt, freespace);
                                q += strlen(q);
                                break;
                        case 'k': /* Key Name */
-                               strlcpy(q, data->key_name, freespace);
+                               strNcpy(q, data->key_name, freespace);
                                q += strlen(q);
                                break;
                        case 'S': /* SQL module instance */
-                               strlcpy(q, data->sqlmod_inst, freespace);
+                               strNcpy(q, data->sqlmod_inst, freespace);
                                q += strlen(q);
                                break;
                        default:
@@ -382,9 +372,8 @@ static int sqlcounter_expand(char *out, int outlen, const char *fmt, void *insta
 /*
  *     See if the counter matches.
  */
-static int sqlcounter_cmp(void *instance, REQUEST *req,
-                         UNUSED VALUE_PAIR *request, VALUE_PAIR *check,
-                         VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
+static int sqlcounter_cmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
+               VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 {
        rlm_sqlcounter_t *data = (rlm_sqlcounter_t *) instance;
        int counter;
@@ -409,7 +398,7 @@ static int sqlcounter_cmp(void *instance, REQUEST *req,
 
        counter = atoi(querystr);
 
-       return counter - check->vp_integer;
+       return counter - check->lvalue;
 }
 
 
@@ -436,7 +425,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        data = rad_malloc(sizeof(*data));
        if (!data) {
-               radlog(L_ERR, "rlm_sqlcounter: Not enough memory.");
                return -1;
        }
        memset(data, 0, sizeof(*data));
@@ -446,8 +434,7 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         *      fail.
         */
        if (cf_section_parse(conf, data, module_config) < 0) {
-               radlog(L_ERR, "rlm_sqlcounter: Unable to parse parameters.");
-               sqlcounter_detach(data);
+               free(data);
                return -1;
        }
 
@@ -456,7 +443,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (data->query == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: 'query' must be set.");
-               sqlcounter_detach(data);
                return -1;
        }
 
@@ -471,20 +457,17 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (data->key_name == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: 'key' must be set.");
-               sqlcounter_detach(data);
                return -1;
        }
        sql_escape_func(buffer, sizeof(buffer), data->key_name);
        if (strcmp(buffer, data->key_name) != 0) {
                radlog(L_ERR, "rlm_sqlcounter: The value for option 'key' is too long or contains unsafe characters.");
-               sqlcounter_detach(data);
                return -1;
        }
        dattr = dict_attrbyname(data->key_name);
        if (dattr == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: No such attribute %s",
                                data->key_name);
-               sqlcounter_detach(data);
                return -1;
        }
        data->key_attr = dattr->attr;
@@ -504,7 +487,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
                if (dattr == NULL) {
                        radlog(L_ERR, "rlm_sqlcounter: No such attribute %s",
                               data->reply_name);
-                       sqlcounter_detach(data);
                        return -1;
                }
                data->reply_attr = dattr->attr;
@@ -517,13 +499,11 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (data->sqlmod_inst == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: 'sqlmod-inst' must be set.");
-               sqlcounter_detach(data);
                return -1;
        }
        sql_escape_func(buffer, sizeof(buffer), data->sqlmod_inst);
        if (strcmp(buffer, data->sqlmod_inst) != 0) {
                radlog(L_ERR, "rlm_sqlcounter: The value for option 'sqlmod-inst' is too long or contains unsafe characters.");
-               sqlcounter_detach(data);
                return -1;
        }
 
@@ -532,7 +512,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (data->counter_name == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: 'counter-name' must be set.");
-               sqlcounter_detach(data);
                return -1;
        }
 
@@ -542,7 +521,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
        if (dattr == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: Failed to create counter attribute %s",
                                data->counter_name);
-               sqlcounter_detach(data);
                return -1;
        }
        data->dict_attr = dattr->attr;
@@ -554,7 +532,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (data->check_name == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: 'check-name' must be set.");
-               sqlcounter_detach(data);
                return -1;
        }
        dict_addattr(data->check_name, 0, PW_TYPE_INTEGER, -1, flags);
@@ -562,7 +539,6 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
        if (dattr == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: Failed to create check attribute %s",
                                data->check_name);
-               sqlcounter_detach(data);
                return -1;
        }
        DEBUG2("rlm_sqlcounter: Check attribute %s is number %d",
@@ -573,28 +549,22 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance)
         */
        if (data->reset == NULL) {
                radlog(L_ERR, "rlm_sqlcounter: 'reset' must be set.");
-               sqlcounter_detach(data);
                return -1;
        }
        now = time(NULL);
        data->reset_time = 0;
 
-       if (find_next_reset(data,now) == -1) {
-               radlog(L_ERR, "rlm_sqlcounter: Failed to find the next reset time.");
-               sqlcounter_detach(data);
+       if (find_next_reset(data,now) == -1)
                return -1;
-       }
 
        /*
         *  Discover the beginning of the current time period.
         */
        data->last_reset = 0;
 
-       if (find_prev_reset(data,now) == -1) {
-               radlog(L_ERR, "rlm_sqlcounter: Failed to find the previous reset time.");
-               sqlcounter_detach(data);
+       if (find_prev_reset(data,now) == -1)
                return -1;
-       }
+
 
        /*
         *      Register the counter comparison operation.
@@ -685,7 +655,7 @@ static int sqlcounter_authorize(void *instance, REQUEST *request)
        /*
         * Check if check item > counter
         */
-       res=check_vp->vp_integer - counter;
+       res=check_vp->lvalue - counter;
        if (res > 0) {
                DEBUG2("rlm_sqlcounter: (Check item - counter) is greater than zero");
                /*
@@ -708,26 +678,27 @@ static int sqlcounter_authorize(void *instance, REQUEST *request)
                if (data->reset_time && (
                        res >= (data->reset_time - request->timestamp))) {
                        res = data->reset_time - request->timestamp;
-                       res += check_vp->vp_integer;
+                       res += check_vp->lvalue;
                }
 
                if ((reply_item = pairfind(request->reply->vps, data->reply_attr)) != NULL) {
-                       if (reply_item->vp_integer > res)
-                               reply_item->vp_integer = res;
+                       if (reply_item->lvalue > res)
+                               reply_item->lvalue = res;
                } else {
-                       reply_item = radius_paircreate(request,
-                                                      &request->reply->vps,
-                                                      data->reply_attr,
-                                                      PW_TYPE_INTEGER);
-                       reply_item->vp_integer = res;
+                       if ((reply_item = paircreate(data->reply_attr, PW_TYPE_INTEGER)) == NULL) {
+                               radlog(L_ERR|L_CONS, "no memory");
+                               return RLM_MODULE_NOOP;
+                       }
+                       reply_item->lvalue = res;
+                       pairadd(&request->reply->vps, reply_item);
                }
 
                ret=RLM_MODULE_OK;
 
                DEBUG2("rlm_sqlcounter: Authorized user %s, check_item=%d, counter=%d",
-                               key_vp->vp_strvalue,check_vp->vp_integer,counter);
+                               key_vp->strvalue,check_vp->lvalue,counter);
                DEBUG2("rlm_sqlcounter: Sent Reply-Item for user %s, Type=%s, value=%d",
-                               key_vp->vp_strvalue,data->reply_name,reply_item->vp_integer);
+                               key_vp->strvalue,data->reply_name,reply_item->lvalue);
        }
        else{
                char module_fmsg[MAX_STRING_LEN];
@@ -749,7 +720,7 @@ static int sqlcounter_authorize(void *instance, REQUEST *request)
                ret=RLM_MODULE_REJECT;
 
                DEBUG2("rlm_sqlcounter: Rejected user %s, check_item=%d, counter=%d",
-                               key_vp->vp_strvalue,check_vp->vp_integer,counter);
+                               key_vp->strvalue,check_vp->lvalue,counter);
        }
 
        return ret;
@@ -757,35 +728,19 @@ static int sqlcounter_authorize(void *instance, REQUEST *request)
 
 static int sqlcounter_detach(void *instance)
 {
-       int i;
-       char **p;
-       rlm_sqlcounter_t *inst = (rlm_sqlcounter_t *)instance;
+       rlm_sqlcounter_t *data = (rlm_sqlcounter_t *) instance;
 
+       paircompare_unregister(data->dict_attr, sqlcounter_cmp);
+       free(data->reset);
+       free(data->query);
+       free(data->check_name);
+       if (data->reply_name) free(data->reply_name);
+       free(data->sqlmod_inst);
+       free(data->counter_name);
+       free(data->allowed_chars);
        allowed_chars = NULL;
-       paircompare_unregister(inst->dict_attr, sqlcounter_cmp);
-
-       /*
-        *      Free up dynamically allocated string pointers.
-        */
-       for (i = 0; module_config[i].name != NULL; i++) {
-               if (module_config[i].type != PW_TYPE_STRING_PTR) {
-                       continue;
-               }
 
-               /*
-                *      Treat 'config' as an opaque array of bytes,
-                *      and take the offset into it.  There's a
-                *      (char*) pointer at that offset, and we want
-                *      to point to it.
-                */
-               p = (char **) (((char *)inst) + module_config[i].offset);
-               if (!*p) { /* nothing allocated */
-                       continue;
-               }
-               free(*p);
-               *p = NULL;
-       }
-       free(inst);
+       free(instance);
        return 0;
 }
 
@@ -799,11 +754,10 @@ static int sqlcounter_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_sqlcounter = {
-       RLM_MODULE_INIT,
        "SQL Counter",
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        sqlcounter_instantiate,         /* instantiation */
-       sqlcounter_detach,              /* detach */
        {
                NULL,                   /* authentication */
                sqlcounter_authorize,   /* authorization */
@@ -814,5 +768,7 @@ module_t rlm_sqlcounter = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
+       sqlcounter_detach,              /* detach */
+       NULL,                           /* destroy */
 };
 
index d17ff20..e05ce6c 100644 (file)
@@ -18,7 +18,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index 739f920..55f1571 100644 (file)
  */
 
 #include "config.h"
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/modpriv.h>
+#include "autoconf.h"
+#include "libradius.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
+#include <stdarg.h>
+#include <netinet/in.h>
+
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+#include "modpriv.h"
 
 #include "rlm_sql.h"
 
@@ -321,7 +330,7 @@ static int sqlhpwippool_instantiate(CONF_SECTION *conf, void **instance)
 
        data->sincesync = 0;
 
-       modinst = find_module_instance(cf_section_find("modules"), (data->sqlinst_name) );
+       modinst = find_module_instance(data->sqlinst_name);
        if (!modinst) {
                nvp_log(__LINE__, data, L_ERR,
                        "sqlhpwippool_instantiate(): cannot find module instance "
@@ -379,7 +388,7 @@ static int sqlhpwippool_postauth(void *instance, REQUEST *request)
        /* if no pool name, we don't need to do anything */
        vp = pairfind(request->reply->vps, PW_ASN_IP_POOL_NAME);
        if (vp) {
-               pname = vp->vp_strvalue;
+               pname = vp->strvalue;
                nvp_log(__LINE__, data, L_DBG,
                        "sqlhpwippool_postauth(): pool name = '%s'",
                        pname);
@@ -393,7 +402,7 @@ static int sqlhpwippool_postauth(void *instance, REQUEST *request)
        /* if no NAS IP address, assign 0 */
        vp = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS);
        if (vp) {
-               nasip = ntohl(vp->vp_ipaddr);
+               nasip = ntohl(vp->lvalue);
        }
        else {
                nasip = 0;
@@ -660,9 +669,19 @@ end_gid:
        }
 
        /* add IP address to reply packet */
-       vp = radius_paircreate(request, &request->reply->vps,
-                              PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR);
-       vp->vp_ipaddr = ip.s_addr;
+       vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR);
+       if (!vp) {
+               nvp_log(__LINE__, data, L_ERR,
+                       "sqlhpwippool_postauth(): couldn't save chosen IP - no memory - "
+                       "exiting with error");
+
+               /* don't free chosen IP, because we have no memory (now adress will need to
+                * wait for timeout, what's not so bad, BTW) */
+               return RLM_MODULE_FAIL;
+       }
+
+       vp->lvalue = ip.s_addr;
+       pairadd(&request->reply->vps, vp);
 
        nvp_log(__LINE__, data, L_DBG, "sqlhpwippool_postauth(): returning %s",
                inet_ntoa(ip));
@@ -684,7 +703,7 @@ static int sqlhpwippool_accounting(void *instance, REQUEST *request)
        /* if no unique session ID, don't even try */
        vp = pairfind(request->packet->vps, PW_ACCT_UNIQUE_SESSION_ID);
        if (vp) {
-               sessid = vp->vp_strvalue;
+               sessid = vp->strvalue;
        }
        else {
                nvp_log(__LINE__, data, L_ERR,
@@ -694,7 +713,7 @@ static int sqlhpwippool_accounting(void *instance, REQUEST *request)
 
        vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE);
        if (vp) {
-               acct_type = vp->vp_integer;
+               acct_type = vp->lvalue;
        }
        else {
                nvp_log(__LINE__, data, L_ERR, "sqlhpwippool_accounting(): "
@@ -729,7 +748,7 @@ static int sqlhpwippool_accounting(void *instance, REQUEST *request)
                                return RLM_MODULE_FAIL;
                        }
 
-                       framedip = ntohl(vp->vp_ipaddr);
+                       framedip = ntohl(vp->lvalue);
 
                        if (!nvp_query(__LINE__, data, sqlsock,
                            "UPDATE `%s`.`ips` "
@@ -769,7 +788,7 @@ static int sqlhpwippool_accounting(void *instance, REQUEST *request)
                                return RLM_MODULE_FAIL;
                        }
 
-                       nasip.s_addr = vp->vp_ipaddr;
+                       nasip.s_addr = vp->lvalue;
                        strncpy(nasipstr, inet_ntoa(nasip), sizeof(nasipstr) - 1);
                        nasipstr[sizeof(nasipstr)] = 0;
 
@@ -793,19 +812,20 @@ static int sqlhpwippool_accounting(void *instance, REQUEST *request)
 }
 
 module_t rlm_sqlhpwippool = {
-       RLM_MODULE_INIT,
-       "sqlhpwippool",                 /* name */
-       RLM_TYPE_THREAD_SAFE,           /* type */
-       sqlhpwippool_instantiate,       /* instantiation */
-       sqlhpwippool_detach,            /* detach */
+       "sqlhpwippool",             /* name */
+       RLM_TYPE_THREAD_SAFE,      /* type */
+       NULL,
+       sqlhpwippool_instantiate,   /* instantiation */
        {
-               NULL,                   /* authentication */
-               NULL,                   /* authorization */
-               NULL,                   /* preaccounting */
-               sqlhpwippool_accounting,/* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               sqlhpwippool_postauth   /* post-auth */
+               NULL,                    /* authentication */
+               NULL,                    /* authorization */
+               NULL,                    /* preaccounting */
+               sqlhpwippool_accounting,  /* accounting */
+               NULL,                    /* checksimul */
+               NULL,                    /* pre-proxy */
+               NULL,                    /* post-proxy */
+               sqlhpwippool_postauth     /* post-auth */
        },
+       sqlhpwippool_detach,        /* detach */
+       NULL
 };
index 3c56d8a..1eb4e33 100644 (file)
@@ -1,61 +1,65 @@
 ---
---- Draft of Netvim SQL schema just for rlm_sqlhpwippool
+--- SQL schema for rlm_sqlhpwippool
 ---
 
-CREATE DATABASE `netvim` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
-USE netvim;
+-- CREATE DATABASE netvim DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
+-- USE netvim;
 
-CREATE TABLE `gid_ip` (
-  `gid` int(10) unsigned NOT NULL default '0' COMMENT 'Host group ID',
-  `ip_start` bigint(20) unsigned NOT NULL default '0' COMMENT 'Beginning of IP range',
-  `ip_stop` bigint(20) unsigned NOT NULL default '0' COMMENT 'End of IP range',
-  KEY `gid` (`gid`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: host groups to IP ranges relations';
+CREATE TABLE gid_ip (
+  gid int NOT NULL CHECK (gid > 0) default '0' PRIMARY KEY,
+  ip_start bigint NOT NULL CHECK (ip_start > 0) default '0',
+  ip_stop bigint NOT NULL CHECK (ip_stop > 0) default '0'
+);
+--COMMENT ON TABLE gid_ip IS 'Netvim: host groups to IP ranges relations';
 
-CREATE TABLE `host_groups` (
-  `gid` int(10) unsigned NOT NULL default '0' COMMENT 'Host group ID',
-  `parent` int(10) unsigned default NULL COMMENT 'ID of parent group',
-  `name` varchar(128) NOT NULL default '' COMMENT 'Host group UNIX name',
-  PRIMARY KEY  (`gid`),
-  UNIQUE KEY `group_name` (`name`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: host groups';
+CREATE TABLE host_groups (
+  gid int NOT NULL CHECK (gid > 0) default '0' PRIMARY KEY,
+  parent int default NULL CHECK (parent > 0),
+  name varchar(128) NOT NULL default ''
+);
+CREATE UNIQUE INDEX group_name ON host_groups (name);
+--COMMENT ON TABLE host_groups IS 'Netvim: host groups';
 
-CREATE TABLE `ids` (
-  `id` int(10) unsigned NOT NULL auto_increment COMMENT 'The One True ID',
-  `enabled` tinyint(1) NOT NULL default '1' COMMENT 'If 0, ignore the object',
-  `modified` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'Time when any of object properties were modified',
-  `created` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'Object creation date',
-  `type` varchar(64) default NULL COMMENT 'Link to an ef action',
-  PRIMARY KEY  (`id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Entity: the source of ID numbers';
+CREATE TABLE ids (
+  id SERIAL,
+  enabled BOOLEAN NOT NULL default '1',
+  modified TIMESTAMP NOT NULL default '0',
+  created TIMESTAMP NOT NULL default '0',
+  type varchar(64) default NULL,
+  PRIMARY KEY (id)
+);
+--COMMENT ON TABLE ids IS 'Entity: the source of ID numbers';
 
-CREATE TABLE `ip_pools` (
-  `pid` int(10) unsigned NOT NULL default '0' COMMENT 'Named pool ID',
-  `gid` int(10) unsigned NOT NULL default '0' COMMENT 'Host group ID',
-  `pnid` int(10) unsigned NOT NULL default '0' COMMENT 'Pool name ID',
-  `ip_start` bigint(20) unsigned NOT NULL default '0' COMMENT 'Beginning of IP range',
-  `ip_stop` bigint(20) unsigned NOT NULL default '0' COMMENT 'End of IP range',
-  `prio` int(11) NOT NULL default '0' COMMENT 'Pool priority',
-  `weight` int(10) unsigned NOT NULL default '1' COMMENT 'Pool weight',
-  `total` bigint(20) unsigned NOT NULL default '0' COMMENT 'Total number of IPs in pool',
-  `free` bigint(20) unsigned NOT NULL default '0' COMMENT 'Number of free IPs in pool',
-  PRIMARY KEY  (`pid`),
-  KEY `gid` (`gid`,`pnid`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: named IP pools assigned to given host group';
+CREATE TABLE ip_pools (
+  pid int NOT NULL CHECK (pid > 0) default '0' COMMENT 'Named pool ID',
+  gid int NOT NULL CHECK (gid > 0) default '0' COMMENT 'Host group ID',
+  pnid int NOT NULL CHECK (pnid > 0) default '0' COMMENT 'Pool name ID',
+  ip_start bigint NOT NULL CHECK (ip_start > 0) default '0' COMMENT 'Beginning of IP range',
+  ip_stop bigint NOT NULL CHECK (ip_stop > 0) default '0' COMMENT 'End of IP range',
+  prio int NOT NULL default '0' COMMENT 'Pool priority',
+  weight int unsigned NOT NULL default '1' COMMENT 'Pool weight',
+  total bigint unsigned NOT NULL default '0' COMMENT 'Total number of IPs in pool',
+  free bigint unsigned NOT NULL default '0' COMMENT 'Number of free IPs in pool',
+  PRIMARY KEY (pid),
+  KEY gid (gid,pnid)
+);
+-- ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: named IP pools assigned to given host group';
 
-CREATE TABLE `ips` (
-  `ip` bigint(20) unsigned NOT NULL default '0' COMMENT 'IP address',
-  `pid` int(10) unsigned NOT NULL default '0' COMMENT 'Named pool ID',
-  `rsv_since` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'Time when IP was reserved',
-  `rsv_by` varchar(64) default NULL COMMENT 'Who/what reserved IP',
-  `rsv_until` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'Reservation timeout',
-  PRIMARY KEY  (`ip`),
-  KEY `pid` (`pid`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: states of single IP addresses';
+CREATE TABLE ips (
+  ip bigint unsigned NOT NULL default '0' COMMENT 'IP address',
+  pid int NOT NULL CHECK (pid > 0) default '0' COMMENT 'Named pool ID',
+  rsv_since TIMESTAMP NOT NULL default '0000-00-00 00:00:00' COMMENT 'Time when IP was reserved',
+  rsv_by varchar(64) default NULL COMMENT 'Who/what reserved IP',
+  rsv_until TIMESTAMP NOT NULL default '0000-00-00 00:00:00' COMMENT 'Reservation timeout',
+  PRIMARY KEY (ip),
+  KEY pid (pid)
+);
+-- ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: states of single IP addresses';
 
-CREATE TABLE `pool_names` (
-  `pnid` int(10) unsigned NOT NULL default '0' COMMENT 'Named pool ID',
-  `name` varchar(128) NOT NULL default '' COMMENT 'Pool UNIX name',
-  PRIMARY KEY  (`pnid`),
-  UNIQUE KEY `pool_name` (`name`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: definitions of pool names';
+CREATE TABLE pool_names (
+  pnid int NOT NULL CHECK (pnid > 0) default '0' COMMENT 'Named pool ID',
+  name varchar(128) NOT NULL default '' COMMENT 'Pool UNIX name',
+  PRIMARY KEY (pnid),
+  UNIQUE KEY pool_name (name)
+);
+-- ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Netvim: definitions of pool names';
index af28710..c0eda85 100644 (file)
@@ -2,8 +2,6 @@
 # $Id$
 #
 
-INCLUDE += -I/usr/local/include/
-
 TARGET      = @targetname@
 SRCS        = rlm_sqlippool.c
 HEADERS     = $(top_builddir)/src/modules/rlm_sql/rlm_sql.h
index 42d0884..00f9483 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.2 .
+# From configure.in Revision: 1.1.2.3 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -869,7 +869,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -2029,6 +2029,11 @@ esac
 
 
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -2067,12 +2072,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
index 67c6259..8cbaad9 100644 (file)
@@ -4,7 +4,6 @@
 # Version:     $Id$
 #
 
-AC_PREREQ([2.59])
 AC_INIT(rlm_sqlippool.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_sqlippool])
index e6d3c21..378aff3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  rlm_sqlippool.c     rlm_sqlippool - FreeRADIUS SQL IP Pool Module
  *
- * Version:  $Id$
+ * Version:     $Id$
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  * Copyright 2006  Suntel Communications
  */
 
-#include <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
+#include "autoconf.h"
+#include "libradius.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
+#include <netinet/in.h>
 
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/modpriv.h>
+#include "radiusd.h"
+#include "modules.h"
+#include "conffile.h"
+#include "modpriv.h"
 
 #include <rlm_sql.h>
 
+static const char rcsid[] = "$Id$";
+
+
+
 /*
  *     Define a structure for our module configuration.
  */
@@ -46,10 +54,10 @@ typedef struct rlm_sqlippool_t {
 
        char *pool_name;
 
-       /* We ended up removing the init
+       /* We ended up removing the init 
           queries so that its up to user
           to create the db structure and put the required
-          information in there
+          information in there                 
        */
                                /* Allocation sequence */
        char *allocate_begin;   /* SQL query to begin */
@@ -59,8 +67,6 @@ typedef struct rlm_sqlippool_t {
        char *allocate_commit;  /* SQL query to commit */
        char *allocate_rollback; /* SQL query to rollback */
 
-       char *pool_check;       /* Query to check for the existence of the pool */
-
                                /* Start sequence */
        char *start_begin;      /* SQL query to begin */
        char *start_update;     /* SQL query to update an IP entry */
@@ -90,18 +96,24 @@ typedef struct rlm_sqlippool_t {
        char *off_clear;        /* SQL query to clear an entire NAS */
        char *off_commit;       /* SQL query to commit */
        char *off_rollback;     /* SQL query to rollback */
+       
+#ifdef HAVE_PTHREAD_H
+       pthread_mutex_t dlock;
+       long owner;
+#endif 
 
-                               /* Logging Section */
-       char *log_exists;       /* There was an ip address already assigned */
-       char *log_success;      /* We successfully allocated ip address from pool */
-       char *log_clear;        /* We successfully deallocated ip address from pool */
-       char *log_failed;       /* Failed to allocate ip from the pool */
-       char *log_nopool;       /* There was no Framed-IP-Address but also no Pool-Name */
+} rlm_sqlippool_t;
 
-                               /* Reserved to handle 255.255.255.254 Requests */
-       char *defaultpool;      /* Default Pool-Name if there is non in the check items */
+#ifndef HAVE_PTHREAD_H
+/*
+ *  This is easier than ifdef's throughout the code.
+ */
+#define pthread_mutex_init(_x, _y)
+#define pthread_mutex_destroy(_x)
+#define pthread_mutex_lock(_x)
+#define pthread_mutex_unlock(_x)
+#endif
 
-} rlm_sqlippool_t;
 
 /*
  *     A mapping of configuration file names to internal variables.
@@ -119,48 +131,38 @@ static CONF_PARSER module_config[] = {
 
   { "pool-name"            , PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, pool_name), NULL, ""},
 
-  { "allocate-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_begin), NULL, "START TRANSACTION" },
+  { "allocate-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_begin), NULL, "BEGIN" },
   { "allocate-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_clear), NULL, "" },
   { "allocate-find", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_find), NULL, "" },
   { "allocate-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_update), NULL, "" },
   { "allocate-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_commit), NULL, "COMMIT" },
   { "allocate-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_rollback), NULL, "ROLLBACK" },
 
-  { "pool-check", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,pool_check), NULL, "" },
-
-  { "start-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_begin), NULL, "START TRANSACTION" },
+  { "start-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_begin), NULL, "BEGIN" },
   { "start-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_update), NULL, "" },
   { "start-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_commit), NULL, "COMMIT" },
   { "start-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_rollback), NULL, "ROLLBACK" },
 
-  { "alive-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_begin), NULL, "START TRANSACTION" },
+  { "alive-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_begin), NULL, "BEGIN" },
   { "alive-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_update), NULL, "" },
   { "alive-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_commit), NULL, "COMMIT" },
   { "alive-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_rollback), NULL, "ROLLBACK" },
 
-  { "stop-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_begin), NULL, "START TRANSACTION" },
+  { "stop-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_begin), NULL, "BEGIN" },
   { "stop-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_clear), NULL, "" },
   { "stop-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_commit), NULL, "COMMIT" },
   { "stop-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_rollback), NULL, "ROLLBACK" },
 
-  { "on-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_begin), NULL, "START TRANSACTION" },
+  { "on-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_begin), NULL, "BEGIN" },
   { "on-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_clear), NULL, "" },
   { "on-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_commit), NULL, "COMMIT" },
   { "on-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_rollback), NULL, "ROLLBACK" },
 
-  { "off-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_begin), NULL, "START TRANSACTION" },
+  { "off-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_begin), NULL, "BEGIN" },
   { "off-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_clear), NULL, "" },
   { "off-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_commit), NULL, "COMMIT" },
   { "off-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_rollback), NULL, "ROLLBACK" },
 
-  { "sqlippool_log_exists", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_exists), NULL, "" },
-  { "sqlippool_log_success", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_success), NULL, "" },
-  { "sqlippool_log_clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_clear), NULL, "" },
-  { "sqlippool_log_failed", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_failed), NULL, "" },
-  { "sqlippool_log_nopool", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_nopool), NULL, "" },
-
-  { "defaultpool", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, defaultpool), NULL, "main_pool" },
-
   { NULL, -1, 0, NULL, NULL }
 };
 
@@ -196,7 +198,7 @@ static int sqlippool_expand(char * out, int outlen, const char * fmt, void * ins
                        /*
                         * We check if we're inside an open brace.  If we are
                         * then we assume this brace is NOT literal, but is
-                        * a closing brace and apply it
+                        * a closing brace and apply it 
                         */
                        if((c == '}') && openbraces) {
                                openbraces--;
@@ -232,13 +234,13 @@ static int sqlippool_expand(char * out, int outlen, const char * fmt, void * ins
                                *q++ = *p;
                                break;
                        case 'P': /* pool name */
-                               strlcpy(q, data->pool_name, freespace);
+                               strNcpy(q, data->pool_name, freespace); 
                                q += strlen(q);
                                break;
                        case 'I': /* IP address */
                                if (param && param_len > 0) {
                                        if (param_len > freespace) {
-                                               strlcpy(q, param, freespace);
+                                               strNcpy(q, param, freespace);
                                                q += strlen(q);
                                        }
                                        else {
@@ -249,7 +251,7 @@ static int sqlippool_expand(char * out, int outlen, const char * fmt, void * ins
                                break;
                        case 'J': /* lease duration */
                                sprintf(tmp, "%d", data->lease_duration);
-                               strlcpy(q, tmp, freespace);
+                               strNcpy(q, tmp, freespace); 
                                q += strlen(q);
                                break;
                        default:
@@ -284,7 +286,7 @@ static int sqlippool_command(const char * fmt, SQLSOCK * sqlsocket, void * insta
         */
        if (request) {
                if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {
-                       radlog(L_ERR, "sqlippool_command: xlat failed on: '%s'", query);
+                       radlog(L_ERR, "sqlippool_command: xlat failed.");
                        return 0;
                }
        }
@@ -296,7 +298,7 @@ static int sqlippool_command(const char * fmt, SQLSOCK * sqlsocket, void * insta
        DEBUG2("sqlippool_command: '%s'", query);
 #endif
        if (rlm_sql_query(sqlsocket, data->sql_inst, query)){
-               radlog(L_ERR, "sqlippool_command: database query error in: '%s'", query);
+               radlog(L_ERR, "sqlippool_command: database query error");
                return 0;
        }
 
@@ -313,7 +315,7 @@ static int sqlippool_query1(char * out, int outlen, const char * fmt, SQLSOCK *
        char expansion[MAX_STRING_LEN * 4];
        char query[MAX_STRING_LEN * 4];
        SQL_ROW row;
-       int rlen, retval = 0;
+       int r;
 
        sqlippool_expand(expansion, sizeof(expansion), fmt, instance, param, param_len);
 
@@ -340,21 +342,39 @@ static int sqlippool_query1(char * out, int outlen, const char * fmt, SQLSOCK *
                return 0;
        }
 
-       out[0] = '\0';
+       r = rlm_sql_fetch_row(sqlsocket, data->sql_inst);
+       (data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);
 
-       if (!rlm_sql_fetch_row(sqlsocket, data->sql_inst)) {
-               if (sqlsocket->row) {
-                       if (sqlsocket->row[0]) {
-                               if ((rlen = strlen(sqlsocket->row[0])) < outlen) {
-                                       strcpy(out, sqlsocket->row[0]);
-                                       retval = rlen;
-                               } else DEBUG("sqlippool_query1: insufficient string space");
-                       } else DEBUG("sqlippool_query1: row[0] returned NULL");
-               } else DEBUG("sqlippool_query1: SQL query did not return any results");
-       } else DEBUG("sqlippool_query1: SQL query did not succeed");
+       if (r) {
+               DEBUG("sqlippool_query1: SQL query did not succeed");
+               out[0] = '\0';
+               return 0;
+       }
 
-       (data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);
-       return retval;
+       row = sqlsocket->row;
+       if (row == NULL) {
+               DEBUG("sqlippool_query1: SQL query did not return any results");
+               out[0] = '\0';
+               return 0;
+       }
+
+       if (row[0] == NULL){
+               DEBUG("sqlippool_query1: row[0] returned NULL");
+               out[0] = '\0';
+               return 0;
+       }
+
+       r = strlen(row[0]);
+       if (r >= outlen){
+               DEBUG("sqlippool_query1: insufficient string space");
+               out[0] = '\0';
+               return 0;
+       }
+
+       strncpy(out, row[0], r);
+       out[r] = '\0';
+
+       return r;
 }
 
 static int sqlippool_initialize_sql(void * instance)
@@ -467,7 +487,7 @@ static int sqlippool_instantiate(CONF_SECTION * conf, void ** instance)
        else
                data->pool_name = strdup("ippool");
 
-       if ( !(data->sql_inst = (SQL_INST *) (find_module_instance(cf_section_find("modules"), data->sql_instance_name))->insthandle) )
+       if ( !(data->sql_inst = (SQL_INST *) (find_module_instance(data->sql_instance_name))->insthandle) )
        {
                radlog(L_ERR, "sqlippool_instantiate: failed to find sql instance named %s", data->sql_instance_name);
                free(data);
@@ -475,23 +495,11 @@ static int sqlippool_instantiate(CONF_SECTION * conf, void ** instance)
        }
 
        sqlippool_initialize_sql(data);
+       pthread_mutex_init(&data->dlock, NULL);
        *instance = data;
        return 0;
 }
 
-
-/*
- * if we have something to log, then we log it
- * otherwise we return the retcode as soon as possible
- */
-static int do_logging(char *str, int retcode)
-{
-       if (strlen(str))
-               radlog(L_INFO,"%s", str);
-       return retcode;
-}
-
-
 /*
  *     Allocate an IP number from the pool.
  */
@@ -503,34 +511,27 @@ static int sqlippool_postauth(void *instance, REQUEST * request)
        uint32_t ip_allocation;
        VALUE_PAIR * vp;
        SQLSOCK * sqlsocket;
-       lrad_ipaddr_t ipaddr;
-
-       VALUE_PAIR *callingsid;
-       VALUE_PAIR *pair;
-
-       int do_callingsid = 0;
-       int do_calledsid = 0;
-
-       char    logstr[MAX_STRING_LEN];
+       long self = (long) pthread_self();
 
        /*
         * If there is a Framed-IP-Address attribute in the reply do nothing
         */
        if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS) != NULL) {
-               /* We already have a Framed-IP-Address */
-               radius_xlat(logstr, sizeof(logstr), data->log_exists, request, NULL);
                DEBUG("rlm_sqlippool: Framed-IP-Address already exists");
-
-               return do_logging(logstr, RLM_MODULE_NOOP);
+               return RLM_MODULE_NOOP;
        }
 
-       if (pairfind(request->config_items, PW_POOL_NAME) == NULL) {
-               DEBUG("rlm_sqlippool: We Dont have Pool-Name in check items.. Lets do nothing..");
-               radius_xlat(logstr, sizeof(logstr), data->log_nopool, request, NULL);
-
-               return do_logging(logstr, RLM_MODULE_NOOP);
+       if ((vp = pairfind(request->config_items, PW_POOL_NAME)) != NULL) {
+               DEBUG("Value Of the Pool-Name is [%s] and its [%i] Chars \n", vp->strvalue, vp->length);
+               pthread_mutex_lock(&data->dlock);
+               strNcpy(data->pool_name, vp->strvalue, (vp->length + 1));
+               pthread_mutex_unlock(&data->dlock);     
        }
-
+       else {
+               DEBUG("rlm_sqlippool: missing pool_name");
+               return RLM_MODULE_NOOP;
+       }
+       
        if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
                DEBUG("rlm_sqlippool: unknown NAS-IP-Address");
                return RLM_MODULE_NOOP;
@@ -544,7 +545,7 @@ static int sqlippool_postauth(void *instance, REQUEST * request)
        sqlsocket = sql_get_socket(data->sql_inst);
        if (sqlsocket == NULL) {
                DEBUG("rlm_sqlippool: cannot allocate sql connection");
-               return RLM_MODULE_FAIL;
+               return RLM_MODULE_NOOP;
        }
 
        /*
@@ -565,66 +566,23 @@ static int sqlippool_postauth(void *instance, REQUEST * request)
        allocation_len = sqlippool_query1(allocation, sizeof(allocation),
                                          data->allocate_find, sqlsocket, instance, request,
                                          (char *) NULL, 0);
+       radlog(L_INFO,"rlm_sqlippool: ip=[%s] len=%d", allocation, allocation_len);
 
        if (allocation_len == 0)
-       {
+       {       
                /*
                 * COMMIT
                 */
                sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
                                  (char *) NULL, 0);
 
-               /*
-                * Should we perform pool-check ?
-                */
-               if (data->pool_check && *data->pool_check) {
-
-                       /*
-                        * Ok, so the allocate-find query found nothing ...
-                        * Let's check if the pool exists at all
-                        */
-                       allocation_len = sqlippool_query1(allocation, sizeof(allocation),
-                                                data->pool_check, sqlsocket, instance, request,
-                                               (char *) NULL, 0);
-
-                       sql_release_socket(data->sql_inst, sqlsocket);
-
-                       if (allocation_len) {
-
-                               /*
-                                * Pool exists after all... So, the failure to allocate
-                                * the IP address was most likely due to the depletion
-                                * of the pool. In that case, we should return NOTFOUND
-                                */
-                               DEBUG("rlm_sqlippool: IP address could not be allocated.");
-                               radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
-                               return do_logging(logstr, RLM_MODULE_NOTFOUND);
-
-                       }
-                       /*
-                        * Pool doesn't exist in the table. It may be handled by some
-                        * other instance of sqlippool, so we should just ignore
-                        * this allocation failure and return NOOP
-                        */
-                       DEBUG("rlm_sqlippool: IP address could not be allocated as not pool exists with that name.");
-                       return RLM_MODULE_NOOP;
-
-               }
-
+               DEBUG("rlm_sqlippool: IP number could not be allocated.");
                sql_release_socket(data->sql_inst, sqlsocket);
-
-               DEBUG("rlm_sqlippool: IP address could not be allocated.");
-               radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
-
-               return do_logging(logstr, RLM_MODULE_NOOP);
+               return RLM_MODULE_NOTFOUND;
        }
 
-
-       /*
-        *  FIXME: Make it work with the ipv6 addresses
-        */
-       if ((ip_hton(allocation, AF_INET, &ipaddr) < 0) ||
-           ((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE))
+       ip_allocation = ip_addr(allocation);
+       if (ip_allocation == INADDR_NONE)
        {
                /*
                 * COMMIT
@@ -634,9 +592,7 @@ static int sqlippool_postauth(void *instance, REQUEST * request)
 
                DEBUG("rlm_sqlippool: Invalid IP number [%s] returned from database query.", allocation);
                sql_release_socket(data->sql_inst, sqlsocket);
-               radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
-
-               return do_logging(logstr, RLM_MODULE_NOOP);
+               return RLM_MODULE_NOOP;
        }
 
        /*
@@ -647,9 +603,13 @@ static int sqlippool_postauth(void *instance, REQUEST * request)
 
        DEBUG("rlm_sqlippool: Allocated IP %s [%08x]", allocation, ip_allocation);
 
-       vp = radius_paircreate(request, &request->reply->vps,
-                              PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR);
-       vp->vp_ipaddr = ip_allocation;
+       if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) {
+               radlog(L_ERR|L_CONS, "no memory");
+               sql_release_socket(data->sql_inst, sqlsocket);
+               return RLM_MODULE_NOOP;
+       }
+       vp->lvalue = ip_allocation;
+       pairadd(&request->reply->vps, vp);
 
        /*
         * COMMIT
@@ -658,9 +618,7 @@ static int sqlippool_postauth(void *instance, REQUEST * request)
                          (char *) NULL, 0);
 
        sql_release_socket(data->sql_inst, sqlsocket);
-       radius_xlat(logstr, sizeof(logstr), data->log_success, request, NULL);
-
-       return do_logging(logstr, RLM_MODULE_OK);
+       return RLM_MODULE_OK;
 }
 
 static int sqlippool_accounting_start(void * instance, REQUEST * request)
@@ -753,8 +711,6 @@ static int sqlippool_accounting_alive(void * instance, REQUEST * request)
 
 static int sqlippool_accounting_stop(void * instance, REQUEST * request)
 {
-       char    logstr[MAX_STRING_LEN];
-
        rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
        SQLSOCK * sqlsocket;
 
@@ -793,9 +749,8 @@ static int sqlippool_accounting_stop(void * instance, REQUEST * request)
                          (char *) NULL, 0);
 
        sql_release_socket(data->sql_inst, sqlsocket);
-       radius_xlat(logstr, sizeof(logstr), data->log_clear, request, NULL);
 
-       return do_logging(logstr, RLM_MODULE_OK);
+       return RLM_MODULE_OK;
 }
 
 static int sqlippool_accounting_on(void * instance, REQUEST * request)
@@ -878,7 +833,7 @@ static int sqlippool_accounting_off(void * instance, REQUEST * request)
 
 /*
  *     Check for an Accounting-Stop
- *     If we find one and we have allocated an IP to this nas/port combination, deallocate it.
+ *     If we find one and we have allocated an IP to this nas/port combination, deallocate it. 
  */
 static int sqlippool_accounting(void * instance, REQUEST * request)
 {
@@ -890,7 +845,7 @@ static int sqlippool_accounting(void * instance, REQUEST * request)
                DEBUG("rlm_sqlippool: Could not find account status type in packet.");
                return RLM_MODULE_NOOP;
        }
-       acct_status_type = vp->vp_integer;
+       acct_status_type = vp->lvalue;
 
        switch (acct_status_type) {
        case PW_STATUS_START:
@@ -914,8 +869,44 @@ static int sqlippool_accounting(void * instance, REQUEST * request)
        }
 }
 
-static int sqlippool_detach(UNUSED void *instance)
+static int sqlippool_detach(void *instance)
 {
+       rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
+
+       free(data->sql_instance_name);
+       free(data->pool_name);
+
+       free(data->allocate_begin);
+       free(data->allocate_clear);
+       free(data->allocate_find);
+       free(data->allocate_update);
+       free(data->allocate_commit);
+       free(data->allocate_rollback);
+
+       free(data->start_begin);
+       free(data->start_update);
+       free(data->start_commit);
+       free(data->start_rollback);
+
+       free(data->alive_begin);
+       free(data->alive_update);
+       free(data->alive_commit);
+       free(data->alive_rollback);
+
+       free(data->stop_begin);
+       free(data->stop_clear);
+       free(data->stop_commit);
+       free(data->stop_rollback);
+
+       free(data->on_begin);
+       free(data->on_clear);
+       free(data->on_commit);
+       free(data->on_rollback);
+
+       free(data->off_begin);
+       free(data->off_clear);
+       free(data->off_commit);
+       free(data->off_rollback);
 
        return 0;
 }
@@ -930,11 +921,10 @@ static int sqlippool_detach(UNUSED void *instance)
  *     is single-threaded.
  */
 module_t rlm_sqlippool = {
-       RLM_MODULE_INIT,
-       "SQL IP Pool",
+       "SQL IP Pool",  
        RLM_TYPE_THREAD_SAFE,           /* type */
+       NULL,                           /* initialization */
        sqlippool_instantiate,          /* instantiation */
-       sqlippool_detach,               /* detach */
        {
                NULL,                   /* authentication */
                NULL,                   /* authorization */
@@ -945,4 +935,6 @@ module_t rlm_sqlippool = {
                NULL,                   /* post-proxy */
                sqlippool_postauth      /* post-auth */
        },
+       sqlippool_detach,               /* detach */
+       NULL,                           /* destroy */
 };
index 4b891ec..69de3ce 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 TARGET     = @targetname@
-SRCS       = rlm_unix.c
+SRCS       = rlm_unix.c cache.c compat.c
 HEADERS    =
 RLM_LIBS   = @unix_ldflags@
 RLM_CFLAGS = @unix_cflags@
diff --git a/src/modules/rlm_unix/cache.c b/src/modules/rlm_unix/cache.c
new file mode 100644 (file)
index 0000000..b05bc1b
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * cache.c     Offers ability to cache /etc/group, /etc/passwd,
+ *             /etc/shadow,
+ *
+ *             All users in the passwd/shadow files are stored in a hash table.
+ *             the hash lookup is VERY fast,  generally 1.0673 comparisons per
+ *             lookup.  For the unitiated, that's blazing.  You can't have less
+ *             than one comparison, for example.
+ *
+ *             The /etc/group file is stored in a singly linked list, as that
+ *             appears to be fast enough.  It's generally a small enough file
+ *             that hashing is unnecessary.
+ *
+ * Version: $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2000  The FreeRADIUS server project.
+ * Copyright 1999  Jeff Carneal <jeff@apex.com>, Apex Internet Services, Inc.
+ * Copyright 2000  Alan DeKok <aland@ox.org>
+ */
+static const char rcsid[] = "$Id$";
+
+#include "autoconf.h"
+#include       "libradius.h"
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SHADOW_H
+#  include <shadow.h>
+#endif
+
+#include "radiusd.h"
+#include "cache.h"
+#include "compat.h"
+
+/*
+ *  Static prototypes
+ */
+static struct mypasswd *findHashUser(struct pwcache *cache, const char *user);
+static int storeHashUser(struct pwcache *cache, struct mypasswd *new, int idx);
+static int hashUserName(const char *s);
+
+/* Builds the hash table up by storing passwd/shadow fields
+ * in memory.  Returns NULL on failure, pointer to the cache on success.
+ */
+struct pwcache *unix_buildpwcache(const char *passwd_file,
+                                  const char *shadow_file,
+                                  const char *group_file)
+{
+       FILE *passwd;
+#ifdef HAVE_SHADOW_H
+       FILE *shadow;
+#endif
+       FILE *group;
+       char buffer[BUFSIZE];
+       char idtmp[10];
+       char username[256];
+       char *ptr, *bufptr;
+       int len, hashindex, numread=0;
+       struct mypasswd *new, *cur;
+
+       int len2, idx;
+       struct group *grp;
+       struct mygroup *g_new;
+       char **member;
+
+        struct pwcache *cache;
+
+       if (!passwd_file) {
+               radlog(L_ERR, "rlm_unix:  You MUST specify a password file!");
+               return NULL;
+       }
+
+       if (!group_file) {
+               radlog(L_ERR, "rlm_unix:  You MUST specify a group file!");
+               return NULL;
+       }
+
+#ifdef HAVE_SHADOW_H
+       if (!shadow_file) {
+               radlog(L_ERR, "rlm_unix:  You MUST specify a shadow password file!");
+               return NULL;
+       }
+#endif
+
+       cache = rad_malloc(sizeof(*cache));
+
+       memset(username, 0, sizeof(username));
+
+       /* Init hash array */
+       memset(cache->hashtable, 0, sizeof cache->hashtable);
+       cache->grphead = NULL;
+
+       if ((passwd = fopen(passwd_file, "r")) == NULL) {
+               radlog(L_ERR, "rlm_unix:  Can't open file password file %s: %s",
+                   passwd_file, strerror(errno));
+               unix_freepwcache(cache);
+               return NULL;
+       }
+
+       while(fgets(buffer, BUFSIZE , passwd) != (char *)NULL) {
+               numread++;
+
+               bufptr = buffer;
+               /* Get usernames from password file */
+               for(ptr = bufptr; *ptr!=':'; ptr++);
+               len = ptr - bufptr;
+               if((len+1) > MAX_STRING_LEN) {
+                       radlog(L_ERR, "rlm_unix:  Username too long in line: %s", buffer);
+               }
+               strncpy(username, buffer, len);
+               username[len] = '\0';
+
+               /* Hash the username */
+               hashindex = hashUserName(username);
+               /*printf("%s:%d\n", username, hashindex);*/
+
+               /* Allocate space for structure to go in hashtable */
+               new = (struct mypasswd *)rad_malloc(sizeof(struct mypasswd));
+               memset(new, 0, sizeof(struct mypasswd));
+
+               /* Put username into new structure */
+               new->pw_name = (char *)rad_malloc(strlen(username)+1);
+               strncpy(new->pw_name, username, strlen(username)+1);
+
+               /* Put passwords into array, if not shadowed */
+               /* Get passwords from password file (shadow comes later) */
+               ptr++;
+               bufptr = ptr;
+               while(*ptr!=':')
+                       ptr++;
+
+#if !HAVE_SHADOW_H
+               /* Put passwords into new structure (*/
+               len = ptr - bufptr;
+
+               if (len > 0) {
+                       new->pw_passwd = (char *)rad_malloc(len+1);
+                       strncpy(new->pw_passwd, bufptr, len);
+                       new->pw_passwd[len] = '\0';
+               } else {
+                       new->pw_passwd = NULL;
+               }
+
+#endif /* !HAVE_SHADOW_H */
+
+               /*
+                * Put uid into structure.  Not sure why, but
+                * at least we'll have it later if we need it
+                */
+               ptr++;
+               bufptr = ptr;
+               while(*ptr!=':')
+                       ptr++;
+               len = ptr - bufptr;
+               strncpy(idtmp, bufptr, len);
+               idtmp[len] = '\0';
+               new->pw_uid = (uid_t)atoi(idtmp);
+
+               /*
+                * Put gid into structure.
+                */
+               ptr++;
+               bufptr = ptr;
+               while(*ptr!=':')
+                       ptr++;
+               len = ptr - bufptr;
+               strncpy(idtmp, bufptr, len);
+               idtmp[len] = '\0';
+               new->pw_gid = (gid_t)atoi(idtmp);
+
+               /*
+                * Put name into structure.
+                */
+               ptr++;
+               bufptr = ptr;
+               while(*ptr!=':')
+                       ptr++;
+
+               len = ptr - bufptr;
+               new->pw_gecos = (char *)rad_malloc(len+1);
+               strncpy(new->pw_gecos, bufptr, len);
+               new->pw_gecos[len] = '\0';
+
+               /*
+                * We'll skip home dir and shell
+                * as I can't think of any use for storing them
+                */
+
+               /*printf("User:  %s, UID:  %d, GID:  %d\n", new->pw_name, new->pw_uid, new->pw_gid);*/
+               /* Store user in the hash */
+               storeHashUser(cache, new, hashindex);
+       }       /* End while(fgets(buffer, BUFSIZE , passwd) != (char *)NULL) */
+       fclose(passwd);
+
+#ifdef HAVE_SHADOW_H
+       /*
+        *      FIXME: Check for password expiry!
+        */
+       if ((shadow = fopen(shadow_file, "r")) == NULL) {
+               radlog(L_ERR, "HASH:  Can't open file %s: %s",
+                   shadow_file, strerror(errno));
+               unix_freepwcache(cache);
+               return NULL;
+       } else {
+               while(fgets(buffer, BUFSIZE , shadow) != (char *)NULL) {
+
+                       bufptr = buffer;
+                       /* Get usernames from shadow file */
+                       for(ptr = bufptr; *ptr!=':'; ptr++);
+                       len = ptr - bufptr;
+                       if((len+1) > MAX_STRING_LEN) {
+                               radlog(L_ERR, "HASH:  Username too long in line: %s", buffer);
+                       }
+                       strncpy(username, buffer, len);
+                       username[len] = '\0';
+                       if((new = findHashUser(cache, username)) == NULL) {
+                               radlog(L_ERR, "HASH:  Username %s in shadow but not passwd??", username);
+                               continue;
+                       }
+
+                       /*
+                        * In order to put passwd in correct structure, we have
+                        * to skip any struct that has a passwd already for that
+                        * user
+                        */
+                       cur = new;
+                       while(new && (strcmp(new->pw_name, username)<=0)
+                                               && (new->pw_passwd == NULL)) {
+                               cur = new;
+                               new = new->next;
+                       }
+                       /* Go back one, we passed it in the above loop */
+                       new = cur;
+
+                       /*
+                        * When we get here, we should be at the last duplicate
+                        * user structure in this hash bucket
+                        */
+
+                       /* Put passwords into struct from shadow file */
+                       ptr++;
+                       bufptr = ptr;
+                       while(*ptr!=':')
+                               ptr++;
+                       len = ptr - bufptr;
+
+                       if (len > 0) {
+                               new->pw_passwd = (char *)rad_malloc(len+1);
+                               strncpy(new->pw_passwd, bufptr, len);
+                               new->pw_passwd[len] = '\0';
+                       } else {
+                               new->pw_passwd = NULL;
+                       }
+               }
+       }
+       fclose(shadow);
+#endif
+
+       /* log how many entries we stored from the passwd file */
+       radlog(L_INFO, "HASH:  Stored %d entries from %s", numread, passwd_file);
+
+       /* The remainder of this function caches the /etc/group or equivalent
+        * file, so it's one less thing we have to lookup on disk.  it uses
+        * fgetgrent(), which is quite slow, but the group file is generally
+        * small enough that it won't matter
+        * As a side note, caching the user list per group was a major pain
+        * in the ass, and I won't even need it.  I really hope that somebody
+        * out there needs and appreciates it.
+        */
+
+       if ((group = fopen(group_file, "r")) == NULL) {
+               radlog(L_ERR, "rlm_unix:  Can't open file group file %s: %s",
+                   group_file, strerror(errno));
+               unix_freepwcache(cache);
+               return NULL;
+       }
+       numread = 0;
+
+       /* Get next entry from the group file */
+       while((grp = fgetgrent(group)) != NULL) {
+
+               /* Make new mygroup structure in mem */
+               g_new = (struct mygroup *)rad_malloc(sizeof(struct mygroup));
+               memset(g_new, 0, sizeof(struct mygroup));
+
+               /* copy grp entries to my structure */
+               len = strlen(grp->gr_name);
+               g_new->gr_name = (char *)rad_malloc(len+1);
+               strncpy(g_new->gr_name, grp->gr_name, len);
+               g_new->gr_name[len] = '\0';
+
+               len = strlen(grp->gr_passwd);
+               g_new->gr_passwd= (char *)rad_malloc(len+1);
+               strncpy(g_new->gr_passwd, grp->gr_passwd, len);
+               g_new->gr_passwd[len] = '\0';
+
+               g_new->gr_gid = grp->gr_gid;
+
+               /* Allocate space for user list, as much as I hate doing groups
+                * that way.
+                */
+               for(member = grp->gr_mem; *member!=NULL; member++);
+               len = member - grp->gr_mem;
+               g_new->gr_mem = (char **)rad_malloc((len+1)*sizeof(char **));
+
+               /* Now go back and copy individual users into it */
+               for(member = grp->gr_mem; *member; member++) {
+                       len2 = strlen(*member);
+                       idx = member - grp->gr_mem;
+                       g_new->gr_mem[idx] = (char *)rad_malloc(len2+1);
+                       strncpy(g_new->gr_mem[idx], *member, len2);
+                       g_new->gr_mem[idx][len2] = '\0';
+               }
+               /* Make sure last entry in user list is 0 so we can loop thru it */
+               g_new->gr_mem[len] = 0;
+
+               /* Insert at beginning of list */
+               g_new->next = cache->grphead;
+               cache->grphead = g_new;
+
+               numread++;
+       }
+
+       /* End */
+       fclose(group);
+
+       radlog(L_INFO, "HASH:  Stored %d entries from %s", numread, group_file);
+
+       return cache;
+}
+
+void unix_freepwcache(struct pwcache *cache)
+{
+       int hashindex;
+       struct mypasswd *cur, *next;
+
+       struct mygroup *g_cur, *g_next;
+       char **member;
+
+       for(hashindex=0; hashindex<HASHTABLESIZE; hashindex++) {
+               if(cache->hashtable[hashindex]) {
+                       cur = cache->hashtable[hashindex];
+                       while(cur) {
+                               next = cur->next;
+                               free(cur->pw_name);
+                               if (cur->pw_passwd) free(cur->pw_passwd);
+                               free(cur->pw_gecos);
+                               free(cur);
+                               cur = next;
+                       }
+               }
+       }
+
+       g_cur = cache->grphead;
+
+       while(g_cur) {
+               g_next = g_cur->next;
+
+               /* Free name, name, member list */
+               for(member = g_cur->gr_mem; *member; member++) {
+                       free(*member);
+               }
+               free(g_cur->gr_mem);
+               free(g_cur->gr_name);
+               free(g_cur->gr_passwd);
+               free(g_cur);
+               g_cur = g_next;
+       }
+
+       free(cache);
+}
+
+/*
+ * Looks up user in hashtable.  If user can't be found, returns 0.
+ * Otherwise returns a pointer to the structure for the user
+ */
+static struct mypasswd *findHashUser(struct pwcache *cache, const char *user)
+{
+
+       struct mypasswd *cur;
+       int idx;
+
+       /* first hash the username and get the index into the hashtable */
+       idx = hashUserName(user);
+
+       cur = cache->hashtable[idx];
+
+       while((cur != NULL) && (strcmp(cur->pw_name, user))) {
+               cur = cur->next;
+       }
+
+       if(cur) {
+               DEBUG2("  HASH:  user %s found in hashtable bucket %d", user, idx);
+               return cur;
+       }
+
+       return (struct mypasswd *)0;
+
+}
+
+/* Stores the username sent into the hashtable */
+static int storeHashUser(struct pwcache *cache, struct mypasswd *new, int idx)
+{
+
+       /* store new record at beginning of list */
+       new->next = cache->hashtable[idx];
+       cache->hashtable[idx] = new;
+
+       return 1;
+}
+
+/* Hashes the username sent to it and returns index into hashtable */
+static int hashUserName(const char *s) {
+       unsigned long hash = 0;
+
+       while (*s != '\0') {
+               hash = hash * 7907 + (unsigned char)*s++;
+       }
+
+       return (hash % HASHTABLESIZE);
+}
+
+/*
+ *     Emulate the cistron unix_pass function, but do it using
+ *     our hashtable (iow, make it blaze).
+ * return  0 on success
+ * return -1 on failure
+ * return -2 on error (let caller fall back to old method)
+ */
+int H_unix_pass(struct pwcache *cache, char *name, char *passwd,
+               VALUE_PAIR **reply_items)
+{
+       struct mypasswd *pwd;
+       char *encrypted_pass;
+
+       /*
+        *      Get encrypted password from password file
+        */
+       if ((pwd = findHashUser(cache, name)) == NULL) {
+               /* Default to old way if user isn't hashed */
+               return -2;
+       }
+       encrypted_pass = pwd->pw_passwd;
+
+       /*
+        *      We might have a passwordless account.
+        */
+       if(encrypted_pass == NULL) return 0;
+
+       if(mainconfig.do_usercollide) {
+               while(pwd) {
+                       /*
+                        * Make sure same user still.  If not, return as if
+                        * wrong pass given
+                        */
+                       if(strcmp(name, pwd->pw_name))
+                               return -1;
+
+                       /*
+                        * Could still be null passwd
+                        */
+                       encrypted_pass = pwd->pw_passwd;
+                       if (encrypted_pass == NULL) {
+                               return 0;
+                       }
+
+                       /*
+                        * Check password
+                        */
+                       if(lrad_crypt_check(passwd, encrypted_pass) == 0) {
+                               /*
+                                * Add 'Class' pair here with value of full
+                                * name from passwd
+                                */
+                               if(strlen(pwd->pw_gecos))
+                                       pairadd(reply_items, pairmake("Class", pwd->pw_gecos, T_OP_EQ));
+
+                               return 0;
+                       }
+                       pwd = pwd->next;
+               }
+               /*
+                * If we get here, pwd is null, and no users matched
+                */
+               return -1;
+       } else {
+               /*
+                *      Check encrypted password.
+                */
+               if (lrad_crypt_check(passwd, encrypted_pass))
+                       return -1;
+
+               return 0;
+       }
+}
+
+/*
+ * Emulate groupcmp in files.c, but do it (much) faster
+ * return -2 on error (let caller fall back to old method),
+ * -1 on match fail, or 0 on success
+ */
+int H_groupcmp(struct pwcache *cache, VALUE_PAIR *check, char *username)
+{
+       struct mypasswd *pwd;
+       struct mygroup *cur;
+       char **member;
+
+       /* get the user from the hash */
+       if (!(pwd = findHashUser(cache, username)))
+               return -2;
+
+       /* let's find this group */
+       if(cache->grphead) {
+               cur = cache->grphead;
+               while((cur) && (strcmp(cur->gr_name, (char *)check->strvalue))){
+                       cur = cur->next;
+               }
+               /* found the group, now compare it */
+               if(!cur) {
+                       /* Default to old function if we can't find it */
+                       return -2;
+               } else {
+                       if(pwd->pw_gid == cur->gr_gid) {
+                               DEBUG2("  HASH:  matched user %s in group %s", username, cur->gr_name);
+                               return 0;
+                       } else {
+                               for(member = cur->gr_mem; *member; member++) {
+                                       if (strcmp(*member, pwd->pw_name) == 0) {
+                                               DEBUG2("  HASH:  matched user %s in group %s", username, cur->gr_name);
+                                               return 0;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return -1;
+}
diff --git a/src/modules/rlm_unix/cache.h b/src/modules/rlm_unix/cache.h
new file mode 100644 (file)
index 0000000..56e0c6d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * cache.h   Definitions for structures and functions needed in cache.c
+ *
+ * Version: cache.c  0.99  04-13-1999  jeff@apex.net
+ */
+#ifndef _CACHE_H
+#define _CACHE_H
+
+/* Misc definitions */
+#define BUFSIZE  1024
+#define HASHTABLESIZE 100000
+#endif
+
+/* Structure definitions */
+struct mypasswd {
+       char    *pw_name;       /* user name */
+       char    *pw_passwd;     /* user password */
+       uid_t   pw_uid;         /* user id */
+       gid_t   pw_gid;         /* group id */
+       char    *pw_gecos;      /* full name (used for class attr */
+       struct mypasswd *next;  /* next */
+};
+
+struct mygroup {
+       char    *gr_name;        /* group name */
+       char    *gr_passwd;      /* group password */
+       gid_t   gr_gid;          /* group id */
+       char    **gr_mem;        /* group members */
+       struct mygroup *next;    /* next */
+};
+
+struct pwcache {
+  struct mypasswd *hashtable[HASHTABLESIZE];
+  struct mygroup *grphead;
+};
+
+/* Function prototypes */
+struct pwcache *unix_buildpwcache(const char *passwd_file,
+                                  const char *shadow_file,
+                                  const char *group_file);
+int H_unix_pass(struct pwcache *cache, char *name, char *passwd,
+                VALUE_PAIR **reply_items);
+int H_groupcmp(struct pwcache *cache, VALUE_PAIR *check, char *username);
+void unix_freepwcache(struct pwcache *cache);
diff --git a/src/modules/rlm_unix/compat.c b/src/modules/rlm_unix/compat.c
new file mode 100644 (file)
index 0000000..8d12bca
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * compat.c    Compatibity routines for fgetpwent(), fgetspent(), and fgetgrent()
+ *
+ *             The code in here was borrowed from the cache.c module
+ *             and adapted to be a standalone set of functions.
+ *
+ * Version: $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2001  The FreeRADIUS server project.
+ */
+static const char rcsid[] = "$Id$";
+
+#include       "autoconf.h"
+#include       "libradius.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+#ifdef HAVE_SHADOW_H
+#  include <shadow.h>
+#endif
+
+#include "radiusd.h"
+#include "cache.h"
+#include "compat.h"
+
+
+#ifndef HAVE_FGETPWENT
+
+struct passwd *rad_fgetpwent(FILE *pwhandle) {
+       static struct passwd pwbuf;
+       static char username[MAX_STRING_LEN];
+       static char userpwd[64];
+       static char gecostmp[128];
+       static char homedirtmp[128];
+       static char shelltmp[128];
+       char uidtmp[16];
+       char gidtmp[16];
+       char *ptr, *bufptr;
+       char buffer[BUFSIZE];
+       int len;
+
+
+
+#define RAD_EXTRACT_FIELD(txt_field, tmp_buf) \
+       for(bufptr = ptr; (*ptr != '\0') && (*ptr != '\n') && (*ptr != ':'); ptr++); \
+       len = ptr - bufptr; \
+       if((len+1) > sizeof(tmp_buf)) { \
+               radlog(L_ERR, "rlm_unix:  %s too long in line: %s", (txt_field), buffer); \
+               return rad_fgetpwent(pwhandle); \
+       } \
+       strncpy((tmp_buf), bufptr, len); \
+       (tmp_buf)[len] = '\0';
+
+
+
+       if (pwhandle == NULL)
+               return NULL;
+
+       if (fgets(buffer, BUFSIZE , pwhandle) == (char *)NULL)
+               return NULL;
+
+       memset(&pwbuf, 0, sizeof(struct passwd));
+       memset(username, 0, sizeof(username));
+       memset(userpwd, 0, sizeof(userpwd));
+       memset(gecostmp, 0, sizeof(gecostmp));
+       memset(homedirtmp, 0, sizeof(homedirtmp));
+       memset(shelltmp, 0, sizeof(shelltmp));
+       buffer[BUFSIZE] ='\0';
+
+       /* Get usernames from the password file */
+       ptr = buffer;
+       RAD_EXTRACT_FIELD("Username", username);
+       pwbuf.pw_name = username;
+
+       /* Get (encrypted) password from password file (shadow comes later) */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("Password", userpwd);
+       pwbuf.pw_passwd = userpwd;
+
+       /* Get uid from the password file */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("UID", uidtmp);
+       pwbuf.pw_uid = atoi(uidtmp);
+
+       /* Get gid from the password file */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("GID", gidtmp);
+       pwbuf.pw_gid = atoi(gidtmp);
+
+       /* Get the GECOS (name) field from the password file */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("GECOS", gecostmp);
+       pwbuf.pw_gecos = gecostmp;
+
+       /* Get the home directory from the password file */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("Home dir", homedirtmp);
+       pwbuf.pw_dir = homedirtmp;
+
+       /* Get the shell from the password file */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("Shell", shelltmp);
+       pwbuf.pw_shell = shelltmp;
+
+       return(&pwbuf);
+}
+
+#undef RAD_EXTRACT_FIELD
+
+#endif /* HAVE_FGETPWENT */
+
+
+
+
+#ifndef HAVE_FGETSPENT
+
+shadow_pwd_t *rad_fgetspent(FILE *sphandle) {
+       static shadow_pwd_t spbuf;
+       static char username[MAX_STRING_LEN];
+       static char userpwd[64];
+       char lastchgtmp[16];
+       char mintmp[16];
+       char maxtmp[16];
+       char warntmp[16];
+       char inactmp[16];
+       char expiretmp[16];
+       char *ptr, *bufptr;
+       char buffer[BUFSIZE];
+       int len;
+
+#define RAD_EXTRACT_FIELD(txt_field, tmp_buf) \
+       for(bufptr = ptr; (*ptr != '\0') && (*ptr != '\n') && (*ptr != ':'); ptr++); \
+       len = ptr - bufptr; \
+       if((len+1) > sizeof(tmp_buf)) { \
+               radlog(L_ERR, "rlm_unix:  %s too long in line: %s", (txt_field), buffer); \
+               return rad_fgetspent(sphandle); \
+       } \
+       strncpy((tmp_buf), bufptr, len); \
+       (tmp_buf)[len] = '\0';
+
+
+
+       if (sphandle == NULL)
+               return NULL;
+
+       if (fgets(buffer, BUFSIZE, sphandle) == (char *)NULL)
+               return NULL;
+
+       memset(&spbuf, 0, sizeof(shadow_pwd_t));
+       memset(username, 0, sizeof(username));
+       memset(userpwd, 0, sizeof(userpwd));
+       buffer[BUFSIZE] ='\0';
+
+       /* Get usernames from the shadow file */
+       ptr = buffer;
+       RAD_EXTRACT_FIELD("Username", username);
+       GET_SP_NAME(&spbuf) = username;
+
+       /* Get (encrypted) passwords from the shadow file */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("Password", userpwd);
+       GET_SP_PWD(&spbuf) = userpwd;
+
+       /* Get the 'last change' field from the shadow file */
+#ifdef GET_SP_LSTCHG
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("'Last change'", lastchgtmp);
+       GET_SP_LSTCHG(&spbuf) = atoi(lastchgtmp);
+#endif
+
+       /* Get the 'minimum time between changes' field from the shadow file */
+#ifdef GET_SP_MIN
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("'Min change'", mintmp);
+       GET_SP_MIN(&spbuf) = atoi(mintmp);
+#endif
+
+       /* Get the 'maximum time between changes' field from the shadow file */
+#ifdef GET_SP_MAX
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("'Max change'", maxtmp);
+       GET_SP_MAX(&spbuf) = atoi(maxtmp);
+#endif
+
+       /* Get the 'expire warning time' field from the shadow file */
+#ifdef GET_SP_WARN
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("'Warn time'", warntmp);
+       GET_SP_WARN(&spbuf) = atoi(warntmp);
+#endif
+
+       /* Get the 'account inactivity time' field from the shadow file */
+#ifdef GET_SP_INACT
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("'Inactive time'", inactmp);
+       GET_SP_INACT(&spbuf) = atoi(inactmp);
+#endif
+
+       /* Get the 'expire time' field from the shadow file */
+#ifdef GET_SP_EXPIRE
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("'Expire time'", expiretmp);
+       GET_SP_EXPIRE(&spbuf) = atoi(expiretmp);
+#endif
+       return (&spbuf);
+}
+
+#undef RAD_EXTRACT_FIELD
+
+#endif  /* HAVE_FGETSPENT */
+
+
+
+#ifndef HAVE_FGETGRENT
+
+#define RAD_MAX_GROUP_MEMBERS 500
+
+struct group *rad_fgetgrent(FILE *grhandle) {
+       static struct group grbuf;
+       static char grname[MAX_STRING_LEN];
+       static char grpwd[64];
+       static char *grmem[RAD_MAX_GROUP_MEMBERS];
+       static char grmembuf[2048];
+       char gidtmp[16];
+       char *ptr, *bufptr, *grptr;
+       char buffer[BUFSIZE];
+       int len, gidx;
+
+
+
+#define RAD_EXTRACT_FIELD(txt_field, tmp_buf) \
+       for(bufptr = ptr; (*ptr != '\0') && (*ptr != '\n') && (*ptr != ':'); ptr++); \
+       len = ptr - bufptr; \
+       if((len+1) > sizeof(tmp_buf)) { \
+               radlog(L_ERR, "rlm_unix:  %s too long in line: %s", (txt_field), buffer); \
+               return rad_fgetgrent(grhandle); \
+       } \
+       strncpy((tmp_buf), bufptr, len); \
+       (tmp_buf)[len] = '\0';
+
+
+
+       if (grhandle == NULL)
+               return NULL;
+
+       if (fgets(buffer, BUFSIZE, grhandle) == (char *)NULL)
+               return NULL;
+
+       memset(&grbuf, 0, sizeof(struct group));
+       memset(grname, 0, sizeof(grname));
+       memset(grpwd, 0, sizeof(grpwd));
+       memset(grmem, 0, sizeof(grmem));
+       memset(grmembuf, 0, sizeof(grmembuf));
+       buffer[BUFSIZE] ='\0';
+
+       /* Get the group name */
+       ptr = buffer;
+       RAD_EXTRACT_FIELD("Group name", grname);
+       grbuf.gr_name = grname;
+
+       /* Get the group password */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("Group password", grpwd);
+       grbuf.gr_passwd = grpwd;
+
+       /* Get the group id */
+       if (*ptr != '\0') ptr++;
+       RAD_EXTRACT_FIELD("Group ID", gidtmp);
+       grbuf.gr_gid = atoi(gidtmp);
+
+       /* Collect all of the group members... */
+       gidx = 0;
+       grbuf.gr_mem = grmem;
+       grbuf.gr_mem[gidx] = NULL;
+       grptr = grmembuf;
+       while (*ptr != '\0') {
+               if (*ptr != '\0') ptr++;
+               for(bufptr = ptr; (*ptr != '\0') && (*ptr != '\n') && (*ptr != ','); ptr++);
+               len = ptr - bufptr;
+
+               /* Ignore "NULL" entries... */
+               if (len == 0) continue;
+
+               if((len+1) > (sizeof(grmembuf) - (grptr - grmembuf))) {
+                       radlog(L_ERR, "rlm_unix:  Some entries dropped.  Group members line too long: %s", buffer);
+                       /* Return a partial list */
+                       return (&grbuf);
+               }
+
+               /* Prevent buffer overflows! */
+               if (gidx+1 >= RAD_MAX_GROUP_MEMBERS) {
+                       radlog(L_ERR, "rlm_unix:  Some entries dropped.  Too many group members: %s", buffer);
+                       /* Return a partial list */
+                       return (&grbuf);
+               }
+
+               strncpy(grptr, bufptr, len);
+               grptr[len] = '\0';
+               grbuf.gr_mem[gidx++] = grptr;
+               grbuf.gr_mem[gidx] = NULL;
+               grptr += len + 1;
+
+       }
+       return (&grbuf);
+}
+
+#undef RAD_EXTRACT_FIELD
+
+#endif /* HAVE_FGETGRENT */
diff --git a/src/modules/rlm_unix/compat.h b/src/modules/rlm_unix/compat.h
new file mode 100644 (file)
index 0000000..751149b
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * compat.h   Compability library for systems that don't have some
+ *              of the routines that we would like to use...
+ *
+ * Version: cache.c  0.99  04-13-1999  jeff@apex.net
+ */
+#ifndef _COMPAT_H
+#define _COMPAT_H
+
+#ifdef HAVE_GETSPNAM
+#if defined(M_UNIX)
+
+       typedef struct passwd shadow_pwd_t;
+#define GET_SP_NAME(sp) ((sp)->pw_name)
+#define GET_SP_PWD(sp) ((sp)->pw_passwd)
+
+#else /* M_UNIX */
+
+       typedef struct spwd shadow_pwd_t;
+#define GET_SP_NAME(sp)  ((sp)->sp_namp)
+#define GET_SP_PWD(sp)    ((sp)->sp_pwdp)
+#define GET_SP_LSTCHG(sp) ((sp)->sp_lstchg)
+#define GET_SP_MIN(sp)    ((sp)->sp_min)
+#define GET_SP_MAX(sp)    ((sp)->sp_max)
+#define GET_SP_WARN(sp)   ((sp)->sp_warn)
+#define GET_SP_INACT(sp)  ((sp)->sp_inact)
+#define GET_SP_EXPIRE(sp) ((sp)->sp_expire)
+
+#endif /* M_UNIX */
+
+#else /* HAVE_GETSPNAM */
+
+typedef struct my_shadow_t {
+       char *sp_namp;
+       char *sp_pwdp;
+       long int sp_lstchg;         /* Date of last change.  */
+       long int sp_min;
+       long int sp_max;
+       long int sp_warn;
+       long int sp_inact;
+       long int sp_expire;
+} shadow_pwd_t;
+#define GET_SP_NAME(sp)  ((sp)->sp_namp)
+#define GET_SP_PWD(sp)    ((sp)->sp_pwdp)
+#define GET_SP_LSTCHG(sp) ((sp)->sp_lstchg)
+#define GET_SP_MIN(sp)    ((sp)->sp_min)
+#define GET_SP_MAX(sp)    ((sp)->sp_max)
+#define GET_SP_WARN(sp)   ((sp)->sp_warn)
+#define GET_SP_INACT(sp)  ((sp)->sp_inact)
+#define GET_SP_EXPIRE(sp) ((sp)->sp_expire)
+
+#endif /* HAVE_GETSPNAM */
+
+
+
+
+#ifndef HAVE_FGETPWENT
+extern struct passwd *rad_fgetpwent(FILE *pwhandle);
+static inline struct passwd *fgetpwent(FILE *pw) {
+       return rad_fgetpwent(pw);
+}
+#endif /* HAVE_FGETPWENT */
+
+#ifndef HAVE_FGETSPENT
+extern shadow_pwd_t *rad_fgetspent(FILE *sphandle);
+static inline shadow_pwd_t *fgetspent(FILE *sp) {
+       return rad_fgetspent(sp);
+}
+#endif /* HAVE_FGETSPENT */
+
+#ifndef HAVE_FGETGRENT
+extern struct group *rad_fgetgrent(FILE *grhandle);
+static inline struct group *fgetgrent(FILE *gr) {
+       return rad_fgetgrent(gr);
+}
+#endif /* HAVE_FGETGRENT */
+
+#endif /* _COMPAT_H */
index 38ca9a9..62a75f3 100644 (file)
@@ -1,61 +1,33 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/*
 
-/* Define to 1 if you have the `getspnam' function. */
-#undef HAVE_GETSPNAM
-
-/* Define to 1 if you have the `getusershell' function. */
-#undef HAVE_GETUSERSHELL
-
-/* Define to 1 if you have the <grp.h> header file. */
-#undef HAVE_GRP_H
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#undef HAVE_PWD_H
-
-/* Define to 1 if you have the <shadow.h> header file. */
-#undef HAVE_SHADOW_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
 
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
+*/
 
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
 
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
+/* Do we have shadow support? */
+#undef HAVE_GETSPNAM
 
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
+/* Define if you have the fgetgrent function.  */
+#undef HAVE_FGETGRENT
 
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
+/* Define if you have the fgetpwent function.  */
+#undef HAVE_FGETPWENT
 
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
+/* Define if you have the fgetspent function.  */
+#undef HAVE_FGETSPENT
 
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
+/* Define if you have the getspnam function.  */
+#undef HAVE_GETSPNAM
 
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
+/* Define if you have the getusershell function.  */
+#undef HAVE_GETUSERSHELL
 
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
+/* Define if you have the <crypt.h> header file.  */
+#undef HAVE_CRYPT_H
 
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
+/* Define if you have the <shadow.h> header file.  */
+#undef HAVE_SHADOW_H
index 5a4309c..79ea2e5 100755 (executable)
@@ -1,10 +1,9 @@
 #! /bin/sh
-# From configure.in Revision: 1.6 .
+# From configure.in Revision: 1.4 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.60.
+# Generated by GNU Autoconf 2.59.
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 ## --------------------- ##
@@ -18,35 +17,11 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -55,43 +30,8 @@ else
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""       $as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
 # Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
+$as_unset ENV MAIL MAILPATH
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -105,19 +45,18 @@ do
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
@@ -125,386 +64,157 @@ fi
 
 
 # Name of the executable.
-as_me=`$as_basename -- "$0" ||
+as_me=`$as_basename "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
-  if (eval ":") 2>/dev/null; then
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-
-  if test $as_have_required = yes &&    (eval ":
-(as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
 
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
 
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
 fi
 
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
 
-test \$exitcode = 0) || { (exit 1); exit 1; }
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
 
-(
-  as_lineno_1=\$LINENO
-  as_lineno_2=\$LINENO
-  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
-  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
-  :
-else
-  as_candidate_shells=
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
     as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  case $as_dir in
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
         /*)
-          for as_base in sh bash ksh sh5; do
-            as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
-          done;;
-       esac
-done
-IFS=$as_save_IFS
-
-
-      for as_shell in $as_candidate_shells $SHELL; do
-        # Try only shells that exist, to save several forks.
-        if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-               { ("$as_shell") 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-_ASEOF
-}; then
-  CONFIG_SHELL=$as_shell
-              as_have_required=yes
-              if { "$as_shell" 2> /dev/null <<\_ASEOF
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-:
-(as_func_return () {
-  (exit $1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
-  break
-fi
-
-fi
-
-      done
-
-      if test "x$CONFIG_SHELL" != x; then
-  for as_var in BASH_ENV ENV
-        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-        done
-        export CONFIG_SHELL
-        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
-    if test $as_have_required = no; then
-  echo This script requires a shell more modern than all the
-      echo shells that I found on your system.  Please install a
-      echo modern shell, or manually run the script under such a
-      echo shell if you do have one.
-      { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
-  echo No shell found that supports shell functions.
-  echo Please tell autoconf@gnu.org about your system,
-  echo including any error possibly output before this
-  echo message
-}
-
-
-
+          if ("$as_dir/$as_base" -c '
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
 
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
     sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
       N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
       t loop
-      s/-\n.*//
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
     ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
+  chmod +x $as_me.lineno ||
     { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
   # Exit status is that of the last command.
   exit
 }
 
 
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
     as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
+rm -f conf$$ conf$$.exe conf$$.file
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -513,19 +223,7 @@ else
   as_mkdir_p=false
 fi
 
-# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  as_executable_p="test -x"
-else
-  as_executable_p=:
-fi
-rm -f conf$$.file
+as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -534,27 +232,39 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
 
-exec 7<&0 </dev/null 6>&1
 
 # Name of the host.
 # hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
+exec 6>&1
+
 #
 # Initializations.
 #
 ac_default_prefix=/usr/local
-ac_clean_files=
 ac_config_libobj_dir=.
-LIBOBJS=
 cross_compiling=no
 subdirs=
 MFLAGS=
 MAKEFLAGS=
 SHELL=${CONFIG_SHELL-/bin/sh}
 
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
 # Identity of this package.
 PACKAGE_NAME=
 PACKAGE_TARNAME=
@@ -591,76 +301,17 @@ ac_includes_default="\
 #endif
 #if HAVE_INTTYPES_H
 # include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
 #endif
 #if HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-CPP
-GREP
-EGREP
-unix_ldflags
-unix_cflags
-targetname
-LIBOBJS
-LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP unix_ldflags unix_cflags targetname LIBOBJS LTLIBOBJS'
 ac_subst_files=''
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-CPP'
-
 
 # Initialize some variables set by options.
 ac_init_help=
@@ -687,48 +338,34 @@ x_libraries=NONE
 # and all the variables that are supposed to be based on exec_prefix
 # by default will actually change.
 # Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
 bindir='${exec_prefix}/bin'
 sbindir='${exec_prefix}/sbin'
 libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
+datadir='${prefix}/share'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
 
 ac_prev=
-ac_dashdash=
 for ac_option
 do
   # If the previous option needs an argument, assign it.
   if test -n "$ac_prev"; then
-    eval $ac_prev=\$ac_option
+    eval "$ac_prev=\$ac_option"
     ac_prev=
     continue
   fi
 
-  case $ac_option in
-  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)   ac_optarg=yes ;;
-  esac
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
 
-  case $ac_dashdash$ac_option in
-  --)
-    ac_dashdash=yes ;;
+  case $ac_option in
 
   -bindir | --bindir | --bindi | --bind | --bin | --bi)
     ac_prev=bindir ;;
@@ -750,18 +387,12 @@ do
   --config-cache | -C)
     cache_file=config.cache ;;
 
-  -datadir | --datadir | --datadi | --datad)
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
     ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
     datadir=$ac_optarg ;;
 
-  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
-  | --dataroo | --dataro | --datar)
-    ac_prev=datarootdir ;;
-  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
-  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
-    datarootdir=$ac_optarg ;;
-
   -disable-* | --disable-*)
     ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
@@ -769,17 +400,7 @@ do
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
     ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval enable_$ac_feature=no ;;
-
-  -docdir | --docdir | --docdi | --doc | --do)
-    ac_prev=docdir ;;
-  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
-    docdir=$ac_optarg ;;
-
-  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
-    ac_prev=dvidir ;;
-  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
-    dvidir=$ac_optarg ;;
+    eval "enable_$ac_feature=no" ;;
 
   -enable-* | --enable-*)
     ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
@@ -788,7 +409,11 @@ do
       { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    { (exit 1); exit 1; }; }
     ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval enable_$ac_feature=\$ac_optarg ;;
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -815,12 +440,6 @@ do
   -host=* | --host=* | --hos=* | --ho=*)
     host_alias=$ac_optarg ;;
 
-  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
-    ac_prev=htmldir ;;
-  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
-  | --ht=*)
-    htmldir=$ac_optarg ;;
-
   -includedir | --includedir | --includedi | --included | --include \
   | --includ | --inclu | --incl | --inc)
     ac_prev=includedir ;;
@@ -845,16 +464,13 @@ do
   | --libexe=* | --libex=* | --libe=*)
     libexecdir=$ac_optarg ;;
 
-  -localedir | --localedir | --localedi | --localed | --locale)
-    ac_prev=localedir ;;
-  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
-    localedir=$ac_optarg ;;
-
   -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst | --locals)
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
     ac_prev=localstatedir ;;
   -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
     localstatedir=$ac_optarg ;;
 
   -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -919,16 +535,6 @@ do
   | --progr-tra=* | --program-tr=* | --program-t=*)
     program_transform_name=$ac_optarg ;;
 
-  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
-    ac_prev=pdfdir ;;
-  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
-    pdfdir=$ac_optarg ;;
-
-  -psdir | --psdir | --psdi | --psd | --ps)
-    ac_prev=psdir ;;
-  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
-    psdir=$ac_optarg ;;
-
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
@@ -985,7 +591,11 @@ do
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
     ac_package=`echo $ac_package| sed 's/-/_/g'`
-    eval with_$ac_package=\$ac_optarg ;;
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
 
   -without-* | --without-*)
     ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
@@ -994,7 +604,7 @@ do
       { echo "$as_me: error: invalid package name: $ac_package" >&2
    { (exit 1); exit 1; }; }
     ac_package=`echo $ac_package | sed 's/-/_/g'`
-    eval with_$ac_package=no ;;
+    eval "with_$ac_package=no" ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -1025,7 +635,8 @@ Try \`$0 --help' for more information." >&2
     expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
       { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
    { (exit 1); exit 1; }; }
-    eval $ac_envvar=\$ac_optarg
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
     export $ac_envvar ;;
 
   *)
@@ -1045,19 +656,27 @@ if test -n "$ac_prev"; then
    { (exit 1); exit 1; }; }
 fi
 
-# Be sure to have absolute directory names.
-for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
-               datadir sysconfdir sharedstatedir localstatedir includedir \
-               oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
 do
-  eval ac_val=\$$ac_var
+  eval ac_val=$`echo $ac_var`
   case $ac_val in
-    [\\/$]* | ?:[\\/]* )  continue;;
-    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
   esac
-  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; }
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1084,76 +703,74 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias-
 test "$silent" = yes && exec 6>/dev/null
 
 
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  { echo "$as_me: error: Working directory cannot be determined" >&2
-   { (exit 1); exit 1; }; }
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  { echo "$as_me: error: pwd does not report name of working directory" >&2
-   { (exit 1); exit 1; }; }
-
-
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$0" ||
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
 $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$0" : 'X\(//\)[^/]' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$0" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r "$srcdir/$ac_unique_file"; then
+  if test ! -r $srcdir/$ac_unique_file; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r "$srcdir/$ac_unique_file"; then
-  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
    { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
 fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
-       cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
    { (exit 1); exit 1; }; }
-       pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
-  srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
-  eval ac_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_env_${ac_var}_value=\$${ac_var}
-  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
 
 #
 # Report the --help message.
@@ -1182,6 +799,9 @@ Configuration:
   -n, --no-create         do not create output files
       --srcdir=DIR        find the sources in DIR [configure dir or \`..']
 
+_ACEOF
+
+  cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
@@ -1199,22 +819,15 @@ Fine tuning of the installation directories:
   --bindir=DIR           user executables [EPREFIX/bin]
   --sbindir=DIR          system admin executables [EPREFIX/sbin]
   --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
   --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
   --libdir=DIR           object code libraries [EPREFIX/lib]
   --includedir=DIR       C header files [PREFIX/include]
   --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR          info documentation [DATAROOTDIR/info]
-  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR           man documentation [DATAROOTDIR/man]
-  --docdir=DIR           documentation root [DATAROOTDIR/doc/PACKAGE]
-  --htmldir=DIR          html documentation [DOCDIR]
-  --dvidir=DIR           dvi documentation [DOCDIR]
-  --pdfdir=DIR           pdf documentation [DOCDIR]
-  --psdir=DIR            ps documentation [DOCDIR]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
 _ACEOF
 
   cat <<\_ACEOF
@@ -1230,94 +843,126 @@ Some influential environment variables:
   CFLAGS      C compiler flags
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
   CPP         C preprocessor
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
 _ACEOF
-ac_status=$?
 fi
 
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" || continue
+    test -d $ac_dir || continue
     ac_builddir=.
 
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
+if test "$ac_dir" != .; then
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
 case $srcdir in
-  .)  # We are building in place.
+  .)  # No --srcdir option.  We are building in place.
     ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
 esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
+    fi
+    cd $ac_popdir
   done
 fi
 
-test -n "$ac_init_help" && exit $ac_status
+test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.60
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
-  exit
+  exit 0
 fi
-cat >config.log <<_ACEOF
+exec 5>config.log
+cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
 
 _ACEOF
-exec 5>>config.log
 {
 cat <<_ASUNAME
 ## --------- ##
@@ -1336,7 +981,7 @@ uname -v = `(uname -v) 2>/dev/null || echo unknown`
 /bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
 /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
 /bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
 /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
@@ -1350,7 +995,6 @@ do
   test -z "$as_dir" && as_dir=.
   echo "PATH: $as_dir"
 done
-IFS=$as_save_IFS
 
 } >&5
 
@@ -1372,6 +1016,7 @@ _ACEOF
 ac_configure_args=
 ac_configure_args0=
 ac_configure_args1=
+ac_sep=
 ac_must_keep_next=false
 for ac_pass in 1 2
 do
@@ -1382,7 +1027,7 @@ do
     -q | -quiet | --quiet | --quie | --qui | --qu | --q \
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
-    *\'*)
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
       ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
@@ -1404,7 +1049,9 @@ do
          -* ) ac_must_keep_next=true ;;
        esac
       fi
-      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
       ;;
     esac
   done
@@ -1415,8 +1062,8 @@ $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
 trap 'exit_status=$?
   # Save into config.log some information that might help in debugging.
   {
@@ -1429,34 +1076,20 @@ trap 'exit_status=$?
 _ASBOX
     echo
     # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
+{
   (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
       sed -n \
-       "s/'\''/'\''\\\\'\'''\''/g;
-         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
     *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
-    esac |
-    sort
-)
+    esac;
+}
     echo
 
     cat <<\_ASBOX
@@ -1467,28 +1100,22 @@ _ASBOX
     echo
     for ac_var in $ac_subst_vars
     do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      echo "$ac_var='\''$ac_val'\''"
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
       cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
+## ------------- ##
+## Output files. ##
+## ------------- ##
 _ASBOX
       echo
       for ac_var in $ac_subst_files
       do
-       eval ac_val=\$$ac_var
-       case $ac_val in
-       *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-       esac
-       echo "$ac_var='\''$ac_val'\''"
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
       done | sort
       echo
     fi
@@ -1500,24 +1127,26 @@ _ASBOX
 ## ----------- ##
 _ASBOX
       echo
-      cat confdefs.h
+      sed "/^$/d" confdefs.h | sort
       echo
     fi
     test "$ac_signal" != 0 &&
       echo "$as_me: caught signal $ac_signal"
     echo "$as_me: exit $exit_status"
   } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
-' 0
+     ' 0
 for ac_signal in 1 2 13 15; do
   trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
 done
 ac_signal=0
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
 
 # Predefined preprocessor variables.
 
@@ -1548,17 +1177,14 @@ _ACEOF
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer explicitly selected file to automatically selected ones.
-if test -n "$CONFIG_SITE"; then
-  set x "$CONFIG_SITE"
-elif test "x$prefix" != xNONE; then
-  set x "$prefix/share/config.site" "$prefix/etc/config.site"
-else
-  set x "$ac_default_prefix/share/config.site" \
-       "$ac_default_prefix/etc/config.site"
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
 fi
-shift
-for ac_site_file
-do
+for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
     { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
 echo "$as_me: loading site script $ac_site_file" >&6;}
@@ -1574,8 +1200,8 @@ if test -r "$cache_file"; then
     { echo "$as_me:$LINENO: loading cache $cache_file" >&5
 echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
     esac
   fi
 else
@@ -1587,11 +1213,12 @@ fi
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
   eval ac_old_set=\$ac_cv_env_${ac_var}_set
   eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
   case $ac_old_set,$ac_new_set in
     set,)
       { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
@@ -1616,7 +1243,8 @@ echo "$as_me:   current value: $ac_new_val" >&2;}
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
@@ -1633,6 +1261,12 @@ echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start ov
    { (exit 1); exit 1; }; }
 fi
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 
 
 
@@ -1649,11 +1283,6 @@ fi
 
 
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
@@ -1669,8 +1298,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1683,34 +1312,32 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
 fi
 if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1723,51 +1350,36 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
+  CC=$ac_ct_CC
 else
   CC="$ac_cv_prog_CC"
 fi
 
 if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1780,34 +1392,74 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
   fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
 fi
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1821,7 +1473,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
@@ -1832,7 +1484,6 @@ do
   fi
 done
 done
-IFS=$as_save_IFS
 
 if test $ac_prog_rejected = yes; then
   # We found a bogon in the path, so make sure we never use it.
@@ -1850,23 +1501,22 @@ fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
 fi
 if test -z "$CC"; then
   if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
+  for ac_prog in cl
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1879,38 +1529,36 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
     test -n "$CC" && break
   done
 fi
 if test -z "$CC"; then
   ac_ct_CC=$CC
-  for ac_prog in cl.exe
+  for ac_prog in cl
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -1923,45 +1571,29 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 done
-IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
 fi
 
-
   test -n "$ac_ct_CC" && break
 done
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf@gnu.org." >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
+  CC=$ac_ct_CC
 fi
 
 fi
@@ -1974,35 +1606,21 @@ See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 
 # Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }
@@ -2027,70 +1645,46 @@ ac_clean_files="$ac_clean_files a.out a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-#
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort.  b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
-#
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions.  Remove them first so a
-# subsequent execution test works.
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { (ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link_default") 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
 do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
        ;;
     [ab].out )
        # We found the default executable, but exeext='' is most
        # certainly right.
        break;;
     *.* )
-        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-       then :; else
-          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       fi
-       # We set ac_cv_exeext here because the later test for it is not
-       # safe: cross compilers may not add the suffix if given an `-o'
-       # argument, so we may need to know it at that point already.
-       # Even if this section looks crufty: it has the advantage of
-       # actually working.
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
        break;;
     * )
        break;;
   esac
 done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
@@ -2103,23 +1697,19 @@ See \`config.log' for more details." >&2;}
 fi
 
 ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
 
-# Check that the compiler produces executables we can run.  If not, either
+# Check the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0
 # If not cross compiling, check that we can run a simple program.
 if test "$cross_compiling" != yes; then
   if { ac_try='./$ac_file'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2138,27 +1728,22 @@ See \`config.log' for more details." >&2;}
     fi
   fi
 fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
 
 rm -f a.out a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
+# Check the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
@@ -2169,8 +1754,9 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 for ac_file in conftest.exe conftest conftest.*; do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
          break;;
     * ) break;;
   esac
@@ -2184,14 +1770,14 @@ See \`config.log' for more details." >&2;}
 fi
 
 rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
 if test "${ac_cv_objext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2211,20 +1797,14 @@ main ()
 }
 _ACEOF
 rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
     *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
        break;;
   esac
@@ -2242,12 +1822,12 @@ fi
 
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
 if test "${ac_cv_c_compiler_gnu+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -2270,36 +1850,24 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2308,139 +1876,24 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_compiler_gnu=no
+ac_compiler_gnu=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
 GCC=`test $ac_compiler_gnu = yes && echo yes`
 ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
 if test "${ac_cv_prog_cc_g+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       CFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-        { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_c_werror_flag=$ac_save_c_werror_flag
-        CFLAGS="-g"
-        cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -2456,36 +1909,24 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -2494,20 +1935,12 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+ac_cv_prog_cc_g=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
@@ -2523,12 +1956,12 @@ else
     CFLAGS=
   fi
 fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_prog_cc_c89=no
+  ac_cv_prog_cc_stdc=no
 ac_save_CC=$CC
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -2562,17 +1995,12 @@ static char *f (char * (*g) (char **, int), char **p, ...)
 /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
    function prototypes and stuff, but not '\xHH' hex character constants.
    These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
+   as 'x'.  The following induces an error, until -std1 is added to get
    proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
    array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
+   that's true only with -std1.  */
 int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
 int test (int i, double x);
 struct s1 {int (*f) (int a);};
 struct s2 {int (*f) (double a);};
@@ -2587,136 +2015,262 @@ return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
   return 0;
 }
 _ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
   rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ac_cv_prog_cc_c89=$ac_arg
+  ac_cv_prog_cc_stdc=$ac_arg
+break
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
 fi
-
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
+rm -f conftest.err conftest.$ac_objext
 done
-rm -f conftest.$ac_ext
+rm -f conftest.$ac_ext conftest.$ac_objext
 CC=$ac_save_CC
 
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
-  xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
   *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
 esac
 
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
 #endif
-                    Syntax error
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+       ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
   else
     ac_cpp_err=
   fi
@@ -2732,10 +2286,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
   # Broken: fails on valid input.
 continue
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
+  # OK, works on sane cases.  Now check whether non-existent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -2745,13 +2298,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -2778,7 +2326,6 @@ sed 's/^/| /' conftest.$ac_ext >&5
 ac_preproc_ok=:
 break
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -2796,8 +2343,8 @@ fi
 else
   ac_cv_prog_CPP=$CPP
 fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
@@ -2820,13 +2367,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 #endif
                     Syntax error
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -2851,10 +2393,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
   # Broken: fails on valid input.
 continue
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
+  # OK, works on sane cases.  Now check whether non-existent headers
   # can be detected and how.
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -2864,13 +2405,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -2897,7 +2433,6 @@ sed 's/^/| /' conftest.$ac_ext >&5
 ac_preproc_ok=:
 break
 fi
-
 rm -f conftest.err conftest.$ac_ext
 
 done
@@ -2920,193 +2455,221 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-       echo "$as_me:$LINENO: checking for system password file" >&5
-echo $ECHO_N "checking for system password file... $ECHO_C" >&6; }
+       echo "$as_me:$LINENO: checking for system password file" >&5
+echo $ECHO_N "checking for system password file... $ECHO_C" >&6
        if test -f /etc/passwd; then
-               echo "$as_me:$LINENO: result: /etc/passwd" >&5
-echo "${ECHO_T}/etc/passwd" >&6; }
+               echo "$as_me:$LINENO: result: /etc/passwd" >&5
+echo "${ECHO_T}/etc/passwd" >&6
        else
-               echo "$as_me:$LINENO: result: no /etc/passwd file." >&5
-echo "${ECHO_T}no /etc/passwd file." >&6; }
-                fail=$fail" /etc/passwd"
+               echo "$as_me:$LINENO: result: no /etc/passwd file." >&5
+echo "${ECHO_T}no /etc/passwd file." >&6
+                fail=$fail" /etc/passwd" ,
        fi
 
-               echo "$as_me:$LINENO: checking for system shadow password file" >&5
-echo $ECHO_N "checking for system shadow password file... $ECHO_C" >&6; }
+               echo "$as_me:$LINENO: checking for system shadow password file" >&5
+echo $ECHO_N "checking for system shadow password file... $ECHO_C" >&6
        if test -f /etc/shadow; then
-               echo "$as_me:$LINENO: result: /etc/shadow" >&5
-echo "${ECHO_T}/etc/shadow" >&6; }
+               echo "$as_me:$LINENO: result: /etc/shadow" >&5
+echo "${ECHO_T}/etc/shadow" >&6
        else
-               echo "$as_me:$LINENO: result: no /etc/shadow file." >&5
-echo "${ECHO_T}no /etc/shadow file." >&6; }
+               echo "$as_me:$LINENO: result: no /etc/shadow file." >&5
+echo "${ECHO_T}no /etc/shadow file." >&6
        fi
 
 
-
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
+echo "$as_me:$LINENO: checking for crypt" >&5
+echo $ECHO_N "checking for crypt... $ECHO_C" >&6
+if test "${ac_cv_func_crypt+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in grep ggrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
-    # Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-
-    $ac_path_GREP_found && break 3
-  done
-done
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define crypt to an innocuous variant, in case <limits.h> declares crypt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define crypt innocuous_crypt
 
-done
-IFS=$as_save_IFS
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char crypt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
 
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
 
-fi
+#undef crypt
 
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_crypt) || defined (__stub___crypt)
+choke me
+#else
+char (*f) () = crypt;
+#endif
+#ifdef __cplusplus
+}
+#endif
 
+int
+main ()
+{
+return f != crypt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_crypt=yes
 else
-  ac_cv_path_GREP=$GREP
-fi
-
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+ac_cv_func_crypt=no
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_crypt" >&5
+echo "${ECHO_T}$ac_cv_func_crypt" >&6
+if test $ac_cv_func_crypt = yes; then
+   cryptlocation=libc
 else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
+
+                       #crypt not in libc
+                       echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5
+echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_crypt+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_prog in egrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
-    # Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-    $ac_path_EGREP_found && break 3
-  done
-done
+ac_cv_lib_crypt_crypt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6
+if test $ac_cv_lib_crypt_crypt = yes; then
 
-done
-IFS=$as_save_IFS
+                                       cryptlocation=libcrypt
+                                       unix_ldflags="${unix_ldflags} -lcrypt"
 
 
 fi
 
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
 
-else
-  ac_cv_path_EGREP=$EGREP
+
 fi
 
+       if test x$cryptlocation = x; then
+                fail=$fail" crypt()" ,
+       fi
+
 
-   fi
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
 
 
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
 if test "${ac_cv_header_stdc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3130,36 +2693,24 @@ main ()
 }
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3168,10 +2719,9 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_header_stdc=no
+ac_cv_header_stdc=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
@@ -3227,7 +2777,6 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <ctype.h>
-#include <stdlib.h>
 #if ((' ' & 0x0FF) == 0x020)
 # define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
 # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
@@ -3247,27 +2796,18 @@ main ()
   for (i = 0; i < 256; i++)
     if (XOR (islower (i), ISLOWER (i))
        || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
+      exit(2);
+  exit (0);
 }
 _ACEOF
 rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3280,14 +2820,12 @@ sed 's/^/| /' conftest.$ac_ext >&5
 ( exit $ac_status )
 ac_cv_header_stdc=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
 fi
-
-
 fi
 fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
 if test $ac_cv_header_stdc = yes; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -3310,9 +2848,9 @@ for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
                  inttypes.h stdint.h unistd.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -3326,36 +2864,24 @@ $ac_includes_default
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3364,14 +2890,12 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_Header=no"
+eval "$as_ac_Header=no"
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
@@ -3384,23 +2908,21 @@ done
 
 
 
-
-for ac_header in shadow.h pwd.h grp.h
+for ac_header in crypt.h shadow.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 else
   # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -3411,36 +2933,24 @@ $ac_includes_default
 #include <$ac_header>
 _ACEOF
 rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest.$ac_objext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3449,16 +2959,15 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_header_compiler=no
+ac_header_compiler=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
 
 # Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -3467,13 +2976,8 @@ cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <$ac_header>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -3497,10 +3001,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
   ac_header_preproc=no
 fi
-
 rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
 
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
@@ -3524,19 +3027,25 @@ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\
 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   eval "$as_ac_Header=\$ac_header_preproc"
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 
 fi
 if test `eval echo '${'$as_ac_Header'}'` = yes; then
@@ -3550,13 +3059,12 @@ done
 
 
 
-
-for ac_func in getspnam getusershell getpwnam
+for ac_func in getspnam getusershell
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -3582,59 +3090,53 @@ cat >>conftest.$ac_ext <<_ACEOF
 
 #undef $ac_func
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
+/* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
 extern "C"
+{
 #endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
 char $ac_func ();
 /* The GNU C library defines this for functions which it implements
     to always fail with ENOSYS.  Some functions are actually named
     something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
 #endif
 
 int
 main ()
 {
-return $ac_func ();
+return f != $ac_func;
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3643,15 +3145,13 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_var=no"
+eval "$as_ac_var=no"
 fi
-
-rm -f core conftest.err conftest.$ac_objext \
+rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
 if test `eval echo '${'$as_ac_var'}'` = yes; then
   cat >>confdefs.h <<_ACEOF
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
@@ -3661,20 +3161,8 @@ fi
 done
 
 
-       if test "$ac_cv_func_getpwnam" != "yes"; then
-               { echo "$as_me:$LINENO: result: no getpwnam" >&5
-echo "${ECHO_T}no getpwnam" >&6; }
-                fail=$fail" getpwnam"
-        fi
-
-       if test "$ac_cv_header_pwd_h" != "yes"; then
-               { echo "$as_me:$LINENO: result: no pwd.h" >&5
-echo "${ECHO_T}no pwd.h" >&6; }
-                fail=$fail" pwd.h"
-       fi
-
-       { echo "$as_me:$LINENO: checking for getspnam in -lshadow" >&5
-echo $ECHO_N "checking for getspnam in -lshadow... $ECHO_C" >&6; }
+       echo "$as_me:$LINENO: checking for getspnam in -lshadow" >&5
+echo $ECHO_N "checking for getspnam in -lshadow... $ECHO_C" >&6
 if test "${ac_cv_lib_shadow_getspnam+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
@@ -3687,52 +3175,40 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
+/* Override any gcc2 internal prototype to avoid an error.  */
 #ifdef __cplusplus
 extern "C"
 #endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
 char getspnam ();
 int
 main ()
 {
-return getspnam ();
+getspnam ();
   ;
   return 0;
 }
 _ACEOF
 rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } &&
         { ac_try='test -s conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
@@ -3741,15 +3217,14 @@ else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_shadow_getspnam=no
+ac_cv_lib_shadow_getspnam=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext \
+rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_shadow_getspnam" >&5
-echo "${ECHO_T}$ac_cv_lib_shadow_getspnam" >&6; }
+echo "$as_me:$LINENO: result: $ac_cv_lib_shadow_getspnam" >&5
+echo "${ECHO_T}$ac_cv_lib_shadow_getspnam" >&6
 if test $ac_cv_lib_shadow_getspnam = yes; then
 
                        unix_ldflags="${unix_ldflags} -lshadow"
@@ -3762,8 +3237,112 @@ _ACEOF
 fi
 
 
-       targetname=rlm_unix
 
+
+
+for ac_func in fgetpwent fgetspent fgetgrent
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+       targetname=rlm_unix
 else
        targetname=
        echo \*\*\* module rlm_unix is disabled.
@@ -3786,10 +3365,9 @@ fi
 
 
 
-ac_config_headers="$ac_config_headers config.h"
-
-ac_config_files="$ac_config_files Makefile"
+          ac_config_headers="$ac_config_headers config.h"
 
+          ac_config_files="$ac_config_files Makefile"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -3808,58 +3386,39 @@ _ACEOF
 
 # The following way of writing the cache mishandles newlines in values,
 # but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
+# So, don't put newlines in cache variables' values.
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
-(
-  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
-      esac ;;
-    esac
-  done
-
+{
   (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
       # `set' does not quote correctly, so add quotes (double-quote
       # substitution turns \\\\ into \\, and sed turns \\ into \).
       sed -n \
        "s/'/'\\\\''/g;
          s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;; #(
+      ;;
     *)
       # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
       ;;
-    esac |
-    sort
-) |
+    esac;
+} |
   sed '
-     /^ac_cv_env_/b end
      t clear
-     :clear
+     : clear
      s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
      t end
-     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
-  if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
-      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
     cat confcache >$cache_file
   else
-    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    echo "not updating unwritable cache $cache_file"
   fi
 fi
 rm -f confcache
@@ -3868,18 +3427,32 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
 DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
-  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`echo "$ac_i" | sed "$ac_script"`
-  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
-  #    will be set to the directory where LIBOBJS objects are built.
-  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -3917,35 +3490,11 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
 # Support unset when possible.
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   as_unset=unset
@@ -3954,43 +3503,8 @@ else
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""       $as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
 # Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
+$as_unset ENV MAIL MAILPATH
 PS1='$ '
 PS2='> '
 PS4='+ '
@@ -4004,19 +3518,18 @@ do
   if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
     eval $as_var=C; export $as_var
   else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+    $as_unset $as_var
   fi
 done
 
 # Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
 
 
 # Name of the executable.
-as_me=`$as_basename -- "$0" ||
+as_me=`$as_basename "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
-        X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\/\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-# CDPATH.
-$as_unset CDPATH
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
 
 
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
 
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
   as_lineno_1=$LINENO
   as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
   test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
 
   # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
   # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
   # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
     sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
       N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
       t loop
-      s/-\n.*//
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
     ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
    { (exit 1); exit 1; }; }
 
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
   # Exit status is that of the last command.
   exit
 }
 
 
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
-  case `echo 'x\c'` in
-  *c*) ECHO_T='        ';;     # ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
-  esac;;
-*)
-  ECHO_N='-n';;
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+if expr a : '\(a\)' >/dev/null 2>&1; then
   as_expr=expr
 else
   as_expr=false
 fi
 
 rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
 echo >conf$$.file
 if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
     as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
 elif ln conf$$.file conf$$ 2>/dev/null; then
   as_ln_s=ln
 else
   as_ln_s='cp -p'
 fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
+rm -f conf$$ conf$$.exe conf$$.file
 
 if mkdir -p . 2>/dev/null; then
   as_mkdir_p=:
@@ -4146,19 +3698,7 @@ else
   as_mkdir_p=false
 fi
 
-# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
-# systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  as_executable_p="test -x"
-else
-  as_executable_p=:
-fi
-rm -f conf$$.file
+as_executable_p="test -f"
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -4167,14 +3707,31 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
 exec 6>&1
 
-# Save the log message, to keep $[0] and so on meaningful, and to
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.60.  Invocation command line was
+generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -4182,19 +3739,30 @@ generated by GNU Autoconf 2.60.  Invocation command line was
   CONFIG_COMMANDS = $CONFIG_COMMANDS
   $ $0 $@
 
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
 _ACEOF
 
-cat >>$CONFIG_STATUS <<_ACEOF
 # Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
 
-_ACEOF
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
 
 cat >>$CONFIG_STATUS <<\_ACEOF
+
 ac_cs_usage="\
 \`$as_me' instantiates files from templates according to the
 current configuration.
@@ -4218,20 +3786,18 @@ Configuration headers:
 $config_headers
 
 Report bugs to <bug-autoconf@gnu.org>."
-
 _ACEOF
+
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.60,
-  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
-Copyright (C) 2006 Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
+srcdir=$srcdir
 _ACEOF
 
 cat >>$CONFIG_STATUS <<\_ACEOF
@@ -4242,24 +3808,39 @@ while test $# != 0
 do
   case $1 in
   --*=*)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
     ac_shift=:
     ;;
-  *)
+  -*)
     ac_option=$1
     ac_optarg=$2
     ac_shift=shift
     ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
   esac
 
   case $ac_option in
   # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
-  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    echo "$ac_cs_version"; exit ;;
-  --debug | --debu | --deb | --de | --d | -d )
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
@@ -4269,24 +3850,18 @@ do
     $ac_shift
     CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
     ac_need_defaults=false;;
-  --he | --h)
-    # Conflict between --help and --header
-    { echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; };;
-  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
    { (exit 1); exit 1; }; } ;;
 
-  *) ac_config_targets="$ac_config_targets $1"
-     ac_need_defaults=false ;;
+  *) ac_config_targets="$ac_config_targets $1" ;;
 
   esac
   shift
@@ -4302,43 +3877,29 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 if \$ac_cs_recheck; then
-  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  CONFIG_SHELL=$SHELL
-  export CONFIG_SHELL
-  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-  echo "$ac_log"
-} >&5
 
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
 
-# Handling of arguments.
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
 for ac_config_target in $ac_config_targets
 do
-  case $ac_config_target in
-    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
-    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
    { (exit 1); exit 1; }; };;
   esac
 done
 
-
 # If the user did not use the arguments to specify the items to instantiate,
 # then the envvar interface is used.  Set only those that are not.
 # We use the long form for the default assignment because of an extremely
@@ -4349,362 +3910,294 @@ if $ac_need_defaults; then
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
+# simply because there is no reason to put it here, and in addition,
 # creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
+# Create a temporary directory, and hook for its removal unless debugging.
 $debug ||
 {
-  tmp=
-  trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
   trap '{ (exit 1); exit 1; }' 1 2 13 15
 }
+
 # Create a (secure) tmp directory for tmp files.
 
 {
-  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
   test -n "$tmp" && test -d "$tmp"
 }  ||
 {
-  tmp=./conf$$-$RANDOM
-  (umask 077 && mkdir "$tmp")
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
 } ||
 {
    echo "$me: cannot create a temporary directory in ." >&2
    { (exit 1); exit 1; }
 }
 
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
 #
-# Set up the sed scripts for CONFIG_FILES section.
+# CONFIG_FILES section.
 #
 
 # No need to generate the scripts if there are no CONFIG_FILES.
 # This happens for instance when ./config.status config.h
-if test -n "$CONFIG_FILES"; then
-
-_ACEOF
-
-
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@unix_ldflags@,$unix_ldflags,;t t
+s,@unix_cflags@,$unix_cflags,;t t
+s,@targetname@,$targetname,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
 
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
-  cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CPP!$CPP$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-unix_ldflags!$unix_ldflags$ac_delim
-unix_cflags!$unix_cflags$ac_delim
-targetname!$targetname$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 52; then
-    break
-  elif $ac_last_try; then
-    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
-   { (exit 1); exit 1; }; }
-  else
-    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
   fi
-done
-
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
-  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
-  ac_eof=`expr $ac_eof + 1`
-fi
+fi # test -n "$CONFIG_FILES"
 
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
-_ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
 _ACEOF
-
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[         ]*VPATH[        ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[    ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[      ]*$//
-}'
-fi
-
 cat >>$CONFIG_STATUS <<\_ACEOF
-fi # test -n "$CONFIG_FILES"
-
-
-for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS
-do
-  case $ac_tag in
-  :[FHLC]) ac_mode=$ac_tag; continue;;
-  esac
-  case $ac_mode$ac_tag in
-  :[FHL]*:*);;
-  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
-   { (exit 1); exit 1; }; };;
-  :[FH]-) ac_tag=-:-;;
-  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
-  esac
-  ac_save_IFS=$IFS
-  IFS=:
-  set x $ac_tag
-  IFS=$ac_save_IFS
-  shift
-  ac_file=$1
-  shift
-
-  case $ac_mode in
-  :L) ac_source=$1;;
-  :[FH])
-    ac_file_inputs=
-    for ac_f
-    do
-      case $ac_f in
-      -) ac_f="$tmp/stdin";;
-      *) # Look for the file first in the build tree, then in the source tree
-        # (if the path is not absolute).  The absolute path cannot be DOS-style,
-        # because $ac_f cannot contain `:'.
-        test -f "$ac_f" ||
-          case $ac_f in
-          [\\/$]*) false;;
-          *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
-          esac ||
-          { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
-   { (exit 1); exit 1; }; };;
-      esac
-      ac_file_inputs="$ac_file_inputs $ac_f"
-    done
-
-    # Let's still pretend it is `configure' which instantiates (i.e., don't
-    # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
-    configure_input="Generated from "`IFS=:
-         echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
-    if test x"$ac_file" != x-; then
-      configure_input="$ac_file.  $configure_input"
-      { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    fi
-
-    case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin";;
-    esac
-    ;;
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
   esac
 
-  ac_dir=`$as_dirname -- "$ac_file" ||
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$ac_file" : 'X\(//\)[^/]' \| \
         X"$ac_file" : 'X\(//\)$' \| \
-        X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-  { as_dir="$ac_dir"
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
     as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
 $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
-        X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
 echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\).*/{
-           s//\1/
-           q
-         }
-         s/.*/./; q'`
-      test -d "$as_dir" && break
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
     done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
    { (exit 1); exit 1; }; }; }
+
   ac_builddir=.
 
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
+if test "$ac_dir" != .; then
   ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
 
 case $srcdir in
-  .)  # We are building in place.
+  .)  # No --srcdir option.  We are building in place.
     ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
 esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
 
-  case $ac_mode in
-  :F)
-  #
-  # CONFIG_FILE
-  #
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
 
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
 
-case `sed -n '/datarootdir/ {
-  p
-  q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-  ac_datarootdir_hack='
-  s&@datadir@&$datadir&g
-  s&@docdir@&$docdir&g
-  s&@infodir@&$infodir&g
-  s&@localedir@&$localedir&g
-  s&@mandir@&$mandir&g
-    s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
 _ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
 $extrasub
@@ -4712,136 +4205,251 @@ _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-$ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
-  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
-
-  rm -f "$tmp/stdin"
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([   ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[        ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([   ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case $ac_file in
-  -) cat "$tmp/out"; rm -f "$tmp/out";;
-  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
   esac
- ;;
-  :H)
-  #
-  # CONFIG_HEADER
-  #
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        # Do quote $f, to prevent DOS paths from being IFS'd.
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[      ]*$//' $ac_file_inputs >$tmp/in
+
 _ACEOF
 
-# Transform confdefs.h into a sed script `conftest.defines', that
-# substitutes the proper values into config.h.in to produce config.h.
-rm -f conftest.defines conftest.tail
-# First, append a space to every undef/define line, to ease matching.
-echo 's/$/ /' >conftest.defines
-# Then, protect against being on the right side of a sed subst, or in
-# an unquoted here document, in config.status.  If some macros were
-# called several times there might be several #defines for the same
-# symbol, which is useless.  But do not sort them, since the last
-# AC_DEFINE must be honored.
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
-# NAME is the cpp macro being defined, VALUE is the value it is being given.
-# PARAMS is the parameter list in the macro definition--in most cases, it's
-# just an empty string.
-ac_dA='s,^\\([  #]*\\)[^        ]*\\([  ]*'
-ac_dB='\\)[     (].*,\\1define\\2'
-ac_dC=' '
-ac_dD=' ,'
-
-uniq confdefs.h |
-  sed -n '
-       t rset
-       :rset
-       s/^[     ]*#[    ]*define[       ][      ]*//
-       t ok
-       d
-       :ok
-       s/[\\&,]/\\&/g
-       s/^\('"$ac_word_re"'\)\(([^()]*)\)[      ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
-       s/^\('"$ac_word_re"'\)[  ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
-  ' >>conftest.defines
-
-# Remove the space that was appended to ease matching.
-# Then replace #undef with comments.  This is necessary, for
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
 # example, in the case of _POSIX_SOURCE, which is predefined and required
 # on some systems where configure will not decide to define it.
-# (The regexp can be short, since the line contains either #define or #undef.)
-echo 's/ $//
-s,^[    #]*u.*,/* & */,' >>conftest.defines
-
-# Break up conftest.defines:
-ac_max_sed_lines=50
-
-# First sed command is:         sed -f defines.sed $ac_file_inputs >"$tmp/out1"
-# Second one is:        sed -f defines.sed "$tmp/out1" >"$tmp/out2"
-# Third one will be:    sed -f defines.sed "$tmp/out2" >"$tmp/out1"
-# et cetera.
-ac_in='$ac_file_inputs'
-ac_out='"$tmp/out1"'
-ac_nxt='"$tmp/out2"'
-
-while :
-do
-  # Write a here document:
-    cat >>$CONFIG_STATUS <<_ACEOF
-    # First, check the format of the line:
-    cat >"\$tmp/defines.sed" <<\\CEOF
-/^[     ]*#[    ]*undef[        ][      ]*$ac_word_re[  ]*\$/b def
-/^[     ]*#[    ]*define[       ][      ]*$ac_word_re[(         ]/b def
-b
-:def
+cat >>conftest.undefs <<\_ACEOF
+s,^[    ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
 _ACEOF
-  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[     ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[     ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
   echo 'CEOF
-    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
-  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
-  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
-  grep . conftest.tail >/dev/null || break
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
   rm -f conftest.defines
   mv conftest.tail conftest.defines
 done
-rm -f conftest.defines conftest.tail
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[     ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
 
-echo "ac_result=$ac_in" >>$CONFIG_STATUS
 cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
   if test x"$ac_file" != x-; then
-    echo "/* $configure_input  */" >"$tmp/config.h"
-    cat "$ac_result" >>"$tmp/config.h"
-    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
       { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
 echo "$as_me: $ac_file is unchanged" >&6;}
     else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
       rm -f $ac_file
-      mv "$tmp/config.h" $ac_file
+      mv $tmp/config.h $ac_file
     fi
   else
-    echo "/* $configure_input  */"
-    cat "$ac_result"
+    cat $tmp/config.h
+    rm -f $tmp/config.h
   fi
-  rm -f "$tmp/out12"
- ;;
-
-
-  esac
-
-done # for ac_tag
+done
+_ACEOF
 
+cat >>$CONFIG_STATUS <<\_ACEOF
 
 { (exit 0); exit 0; }
 _ACEOF
index 0e5248f..a57e7a9 100644 (file)
@@ -1,4 +1,3 @@
-AC_PREREQ([2.53])
 AC_INIT(rlm_unix.c)
 AC_REVISION($Revision$)
 AC_DEFUN(modname,[rlm_unix])
@@ -13,7 +12,7 @@ if test x$with_[]modname != xno; then
                AC_MSG_RESULT(/etc/passwd)
        else
                AC_MSG_RESULT(no /etc/passwd file.)
-               [ fail=$fail" /etc/passwd" ]
+               [ fail=$fail" /etc/passwd" ],
        fi
 
        dnl useless?
@@ -24,28 +23,35 @@ if test x$with_[]modname != xno; then
                AC_MSG_RESULT(no /etc/shadow file.)
        fi
 
-       AC_CHECK_HEADERS(shadow.h pwd.h grp.h)
-       AC_CHECK_FUNCS(getspnam getusershell getpwnam)
-
-       if test "$ac_cv_func_getpwnam" != "yes"; then
-               AC_MSG_RESULT(no getpwnam)
-               [ fail=$fail" getpwnam" ]
-        fi
-
-       if test "$ac_cv_header_pwd_h" != "yes"; then
-               AC_MSG_RESULT(no pwd.h)
-               [ fail=$fail" pwd.h" ]
+       AC_CHECK_FUNC(crypt, 
+               [ cryptlocation=libc ],
+               [
+                       #crypt not in libc
+                       AC_CHECK_LIB(crypt, crypt, 
+                               [ 
+                                       cryptlocation=libcrypt 
+                                       unix_ldflags="${unix_ldflags} -lcrypt"
+                               ]
+                       )
+               ]
+       )
+       if test x$cryptlocation = x; then
+               [ fail=$fail" crypt()" ],
        fi
 
-       AC_CHECK_LIB(shadow, getspnam,
-               [
+       AC_CHECK_HEADERS(crypt.h shadow.h)
+       AC_CHECK_FUNCS(getspnam getusershell)
+
+       AC_CHECK_LIB(shadow, getspnam, 
+               [ 
                        unix_ldflags="${unix_ldflags} -lshadow"
-                       AC_DEFINE(HAVE_GETSPNAM)
+                       AC_DEFINE(HAVE_GETSPNAM) 
                ]
        )
 
-       targetname=modname
+       AC_CHECK_FUNCS(fgetpwent fgetspent fgetgrent)
 
+       targetname=modname
 else
        targetname=
        echo \*\*\* module modname is disabled.
@@ -56,7 +62,7 @@ if test x"$fail" != x""; then
                AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
        else
                AC_MSG_WARN([silently not building ]modname[.])
-               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+               AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); 
                targetname=""
        fi
 fi
index 89833f8..1db9607 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Jeff Carneal <jeff@apex.net>
  * Copyright 2000  Alan Curry <pacman@world.std.com>
  */
+static const char rcsid[] = "$Id$";
 
-#include       <freeradius-devel/ident.h>
-RCSID("$Id$")
-
-#include       <freeradius-devel/radiusd.h>
+#include       "autoconf.h"
+#include       "libradius.h"
 
+#include       <stdlib.h>
+#include       <string.h>
 #include       <grp.h>
 #include       <pwd.h>
+#include       <sys/types.h>
 #include       <sys/stat.h>
 
 #include "config.h"
@@ -49,29 +51,147 @@ RCSID("$Id$")
 #  include     <siad.h>
 #endif
 
-#include       <freeradius-devel/modules.h>
-#include       <freeradius-devel/sysutmp.h>
+#include       "radiusd.h"
+#include       "modules.h"
+#include       "sysutmp.h"
+#include       "cache.h"
+#include       "conffile.h"
+#include       "compat.h"
 
 static char trans[64] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 #define ENC(c) trans[c]
 
 struct unix_instance {
+       int cache_passwd;
+       const char *passwd_file;
+       const char *shadow_file;
+       const char *group_file;
        const char *radwtmp;
+       int usegroup;
+       struct pwcache *cache;
+       time_t cache_reload;
+       time_t next_reload;
+       time_t last_reload;
 };
 
-static const CONF_PARSER module_config[] = {
+static CONF_PARSER module_config[] = {
+       /*
+        *      Cache the password by default.
+        */
+       { "cache",    PW_TYPE_BOOLEAN,
+         offsetof(struct unix_instance,cache_passwd), NULL, "no" },
+       { "passwd",   PW_TYPE_STRING_PTR,
+         offsetof(struct unix_instance,passwd_file), NULL,  NULL },
+       { "shadow",   PW_TYPE_STRING_PTR,
+         offsetof(struct unix_instance,shadow_file), NULL,  NULL },
+       { "group",    PW_TYPE_STRING_PTR,
+         offsetof(struct unix_instance,group_file), NULL,   NULL },
        { "radwtmp",  PW_TYPE_STRING_PTR,
          offsetof(struct unix_instance,radwtmp), NULL,   "NULL" },
+       { "usegroup", PW_TYPE_BOOLEAN,
+         offsetof(struct unix_instance,usegroup), NULL,     "no" },
+       { "cache_reload", PW_TYPE_INTEGER,
+         offsetof(struct unix_instance,cache_reload), NULL, "600" },
 
        { NULL, -1, 0, NULL, NULL }             /* end the list */
 };
 
+/*
+ * groupcmp is part of autz. But it uses the data from an auth instance. So
+ * here is where it gets it. By default this will be the first configured
+ * auth instance. That can be changed by putting "usegroup = yes" inside an
+ * auth instance to explicitly bind all Group checks to it.
+ */
+
+/* binds "Group=" to an instance (a particular passwd file) */
+static struct unix_instance *group_inst;
+
+/* Tells if the above binding was explicit (usegroup=yes specified in config
+ * file) or not ("Group=" was bound to the first instance of rlm_unix */
+static int group_inst_explicit;
+
+#ifdef HAVE_GETSPNAM
+#if defined(M_UNIX)
+static inline const char *get_shadow_name(shadow_pwd_t *spwd) {
+       if (spwd == NULL) return NULL;
+       return (spwd->pw_name);
+}
+
+static inline const char *get_shadow_encrypted_pwd(shadow_pwd_t *spwd) {
+       if (spwd == NULL) return NULL;
+       return (spwd->pw_passwd);
+}
+#else /* M_UNIX */
+       static inline const char *get_shadow_name(shadow_pwd_t *spwd) {
+               if (spwd == NULL) return NULL;
+               return (spwd->sp_namp);
+       }
+       static inline const char *get_shadow_encrypted_pwd(shadow_pwd_t *spwd) {
+               if (spwd == NULL) return NULL;
+               return (spwd->sp_pwdp);
+       }
+#endif /* M_UNIX */
+#endif /* HAVE_GETSPNAM */
+
+static struct passwd *fgetpwnam(const char *fname, const char *name) {
+       FILE            *file = fopen(fname, "ro");
+       struct passwd   *pwd = NULL;
+
+       if(file == NULL) return NULL;
+       do {
+               pwd = fgetpwent(file);
+               if(pwd == NULL) {
+                       fclose(file);
+                       return NULL;
+               }
+       } while (strcmp(name, pwd->pw_name) != 0);
+
+       fclose(file);
+       return pwd;
+}
+
+static struct group *fgetgrnam(const char *fname, const char *name) {
+       FILE            *file = fopen(fname, "ro");
+       struct group    *grp = NULL;
+
+       if(file == NULL) return NULL;
+
+       do {
+               grp = fgetgrent(file);
+               if(grp == NULL) {
+                       fclose(file);
+                       return NULL;
+               }
+       } while(strcmp(name, grp->gr_name) != 0);
+       fclose(file);
+       return grp;
+}
+
+#ifdef HAVE_GETSPNAM
+
+static shadow_pwd_t *fgetspnam(const char *fname, const char *name) {
+       FILE            *file = fopen(fname, "ro");
+       shadow_pwd_t    *spwd = NULL;
+
+       if(file == NULL) return NULL;
+       do {
+               spwd = fgetspent(file);
+               if(spwd == NULL) {
+                       fclose(file);
+                       return NULL;
+               }
+       } while(strcmp(name, get_shadow_name(spwd)) != 0);
+       fclose(file);
+       return spwd;
+}
+
+#endif
 
 /*
  *     The Group = handler.
  */
-static int groupcmp(void *instance, UNUSED REQUEST *req, VALUE_PAIR *request,
+static int groupcmp(void *instance, REQUEST *req, VALUE_PAIR *request,
                    VALUE_PAIR *check, VALUE_PAIR *check_pairs,
                    VALUE_PAIR **reply_pairs)
 {
@@ -86,6 +206,11 @@ static int groupcmp(void *instance, UNUSED REQUEST *req, VALUE_PAIR *request,
        check_pairs = check_pairs;
        reply_pairs = reply_pairs;
 
+       if (!group_inst) {
+               radlog(L_ERR, "groupcmp: no group list known.");
+               return 1;
+       }
+
        /*
         *      No user name, doesn't compare.
         */
@@ -96,13 +221,23 @@ static int groupcmp(void *instance, UNUSED REQUEST *req, VALUE_PAIR *request,
                        return -1;
                }
        }
-       username = (char *)vp->vp_strvalue;
+       username = (char *)vp->strvalue;
+
+       if (group_inst->cache &&
+           (retval = H_groupcmp(group_inst->cache, check, username)) != -2)
+               return retval;
 
-       pwd = getpwnam(username);
+       if (group_inst->passwd_file)
+               pwd = fgetpwnam(group_inst->passwd_file, username);
+       else
+               pwd = getpwnam(username);
        if (pwd == NULL)
                return -1;
 
-       grp = getgrnam((char *)check->vp_strvalue);
+       if (group_inst->group_file)
+               grp = fgetgrnam(group_inst->group_file, (char *)check->strvalue);
+       else
+               grp = getgrnam((char *)check->strvalue);
        if (grp == NULL)
                return -1;
 
@@ -118,24 +253,20 @@ static int groupcmp(void *instance, UNUSED REQUEST *req, VALUE_PAIR *request,
 
 
 /*
- *     Detach.
+ *     FIXME:  We really should have an 'init' which makes
+ *     System auth == Unix
  */
-static int unix_detach(void *instance)
+static int unix_init(void)
 {
-#define inst ((struct unix_instance *)instance)
-
-       paircompare_unregister(PW_GROUP, groupcmp);
-#ifdef PW_GROUP_NAME
-       paircompare_unregister(PW_GROUP_NAME, groupcmp);
+       /* FIXME - delay these until a group file has been read so we know
+        * groupcmp can actually do something */
+       paircompare_register(PW_GROUP, PW_USER_NAME, groupcmp, NULL);
+#ifdef PW_GROUP_NAME /* compat */
+       paircompare_register(PW_GROUP_NAME, PW_USER_NAME, groupcmp, NULL);
 #endif
-#undef inst
-       free(instance);
        return 0;
 }
 
-/*
- *     Read the config
- */
 static int unix_instantiate(CONF_SECTION *conf, void **instance)
 {
        struct unix_instance *inst;
@@ -153,70 +284,234 @@ static int unix_instantiate(CONF_SECTION *conf, void **instance)
         *      Parse the configuration, failing if we can't do so.
         */
        if (cf_section_parse(conf, inst, module_config) < 0) {
-               unix_detach(inst);
+               free(inst);
                return -1;
        }
 
-       /* FIXME - delay these until a group file has been read so we know
-        * groupcmp can actually do something */
-       paircompare_register(PW_GROUP, PW_USER_NAME, groupcmp, NULL);
-#ifdef PW_GROUP_NAME /* compat */
-       paircompare_register(PW_GROUP_NAME, PW_USER_NAME, groupcmp, NULL);
-#endif
+       if (inst->cache_passwd) {
+               radlog(L_INFO, "HASH:  Reinitializing hash structures "
+                       "and lists for caching...");
+               if ((inst->cache = unix_buildpwcache(inst->passwd_file,
+                                                    inst->shadow_file,
+                                                    inst->group_file))==NULL)
+                {
+                       radlog(L_ERR, "HASH:  unable to create user "
+                               "hash table.  disable caching and run debugs");
+                       if (inst->passwd_file)
+                               free((char *) inst->passwd_file);
+                       if (inst->shadow_file)
+                               free((char *) inst->shadow_file);
+                       if (inst->group_file)
+                               free((char *) inst->group_file);
+                       if (inst->radwtmp)
+                               free((char *) inst->radwtmp);
+                       free(inst);
+                       return -1;
+               }
+
+               if (inst->cache_reload) {
+                       inst->last_reload = 0;
+                       inst->next_reload = time(NULL) + inst->cache_reload;
+               }
+       } else {
+               inst->cache = NULL;
+       }
 
+       if (inst->usegroup) {
+               if (group_inst_explicit) {
+                       radlog(L_ERR, "Only one group list may be active");
+               } else {
+                       group_inst = inst;
+                       group_inst_explicit = 1;
+               }
+       } else if (!group_inst) {
+               group_inst = inst;
+       }
 #undef inst
 
        return 0;
 }
 
+/*
+ *     Detach.
+ */
+static int unix_detach(void *instance)
+{
+#define inst ((struct unix_instance *)instance)
+       if (group_inst == inst) {
+               group_inst = NULL;
+               group_inst_explicit = 0;
+       }
+       if (inst->passwd_file)
+               free((char *) inst->passwd_file);
+       if (inst->shadow_file)
+               free((char *) inst->shadow_file);
+       if (inst->group_file)
+               free((char *) inst->group_file);
+       if (inst->radwtmp)
+               free((char *) inst->radwtmp);
+       if (inst->cache) {
+               unix_freepwcache(inst->cache);
+       }
+#undef inst
+       free(instance);
+       return 0;
+}
+
+static int unix_destroy(void)
+{
+       paircompare_unregister(PW_GROUP, groupcmp);
+#ifdef PW_GROUP_NAME
+       paircompare_unregister(PW_GROUP_NAME, groupcmp);
+#endif
+       return 0;
+}
+
 
 /*
- *     Pull the users password from where-ever, and add it to
- *     the given vp list.
+ *     Check the users password against the standard UNIX
+ *     password table.
  */
-static int unix_getpw(UNUSED void *instance, REQUEST *request,
-                     VALUE_PAIR **vp_list)
+static int unix_authenticate(void *instance, REQUEST *request)
 {
-       const char      *name;
+#define inst ((struct unix_instance *)instance)
+       char *name, *passwd;
+       struct passwd   *pwd;
        const char      *encrypted_pass;
+       int             ret;
 #ifdef HAVE_GETSPNAM
-       struct spwd     *spwd = NULL;
+       shadow_pwd_t    *spwd = NULL;
 #endif
 #ifdef OSFC2
        struct pr_passwd *pr_pw;
-#else
-       struct passwd   *pwd;
+#endif
+#ifdef OSFSIA
+       char            *info[2];
+       char            *progname = "radius";
+       SIAENTITY       *ent = NULL;
 #endif
 #ifdef HAVE_GETUSERSHELL
        char            *shell;
 #endif
-       VALUE_PAIR      *vp;
+
+       /* See if we should refresh the cache */
+       if (inst->cache && inst->cache_reload
+        && (inst->next_reload < request->timestamp)) {
+               /* Time to refresh, maybe ? */
+               int must_reload = 0;
+               struct stat statbuf;
+
+               DEBUG2("rlm_users : Time to refresh cache.");
+               /* Check if any of the files has changed */
+               if (inst->passwd_file
+                && (stat(inst->passwd_file, &statbuf) != -1)
+                && (statbuf.st_mtime > inst->last_reload)) {
+                       must_reload++;
+               }
+
+               if (inst->shadow_file
+                && (stat(inst->shadow_file, &statbuf) != -1)
+                && (statbuf.st_mtime > inst->last_reload)) {
+                       must_reload++;
+               }
+
+               if (inst->group_file
+                && (stat(inst->group_file, &statbuf) != -1)
+                && (statbuf.st_mtime > inst->last_reload)) {
+                       must_reload++;
+               }
+
+               if (must_reload) {
+                       /* Build a new cache to replace old one */
+                       struct pwcache *oldcache;
+                       struct pwcache *newcache = unix_buildpwcache(
+                                                       inst->passwd_file,
+                                                       inst->shadow_file,
+                                                       inst->group_file);
+
+                       if (newcache) {
+                               oldcache = inst->cache;
+                               inst->cache = newcache;
+                               unix_freepwcache(oldcache);
+
+                               inst->last_reload = time(NULL);
+                       }
+               } else {
+                       DEBUG2("rlm_users : Files were unchanged. Not reloading.");
+               }
+
+               /* Schedule next refresh */
+               inst->next_reload = time(NULL) + inst->cache_reload;
+       }
 
        /*
         *      We can only authenticate user requests which HAVE
         *      a User-Name attribute.
         */
        if (!request->username) {
-               return RLM_MODULE_NOOP;
+               radlog(L_AUTH, "rlm_unix: Attribute \"User-Name\" is required for authentication.");
+               return RLM_MODULE_INVALID;
+       }
+
+       /*
+        *      We can only authenticate user requests which HAVE
+        *      a User-Password attribute.
+        */
+       if (!request->password) {
+               radlog(L_AUTH, "rlm_unix: Attribute \"User-Password\" is required for authentication.");
+               return RLM_MODULE_INVALID;
        }
 
-       name = (char *)request->username->vp_strvalue;
-       encrypted_pass = NULL;
+       /*
+        *  Ensure that we're being passed a plain-text password,
+        *  and not anything else.
+        */
+       if (request->password->attribute != PW_PASSWORD) {
+               radlog(L_AUTH, "rlm_unix: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
+               return RLM_MODULE_INVALID;
+       }
+
+       name = (char *)request->username->strvalue;
+       passwd = (char *)request->password->strvalue;
+
+       if (inst->cache &&
+           (ret = H_unix_pass(inst->cache, name, passwd, &request->reply->vps)) != -2)
+               return (ret == 0) ? RLM_MODULE_OK : RLM_MODULE_REJECT;
+
+#ifdef OSFSIA
+       info[0] = progname;
+       info[1] = NULL;
+       if (sia_ses_init (&ent, 1, info, NULL, name, NULL, 0, NULL) !=
+           SIASUCCESS)
+               return RLM_MODULE_NOTFOUND;
+       if ((ret = sia_ses_authent (NULL, passwd, ent)) != SIASUCCESS) {
+               if (ret & SIASTOP)
+                       sia_ses_release (&ent);
+               return RLM_MODULE_NOTFOUND;
+       }
+       if (sia_ses_estab (NULL, ent) == SIASUCCESS) {
+               sia_ses_release (&ent);
+               return RLM_MODULE_OK;
+       }
 
+       return RLM_MODULE_NOTFOUND;
+#else /* OSFSIA */
 #ifdef OSFC2
        if ((pr_pw = getprpwnam(name)) == NULL)
                return RLM_MODULE_NOTFOUND;
        encrypted_pass = pr_pw->ufld.fd_encrypt;
-
+#else /* OSFC2 */
        /*
-        *      Check if account is locked.
+        *      Get encrypted password from password file
+        *
+        *      If a password file was explicitly specified, use it,
+        *      otherwise, use the system routines to read the
+        *      system password file
         */
-       if (pr_pw->uflg.fg_lock!=1) {
-               radlog(L_AUTH, "rlm_unix: [%s]: account locked", name);
-               return RLM_MODULE_USERLOCK;
-       }
-#else /* OSFC2 */
-       if ((pwd = getpwnam(name)) == NULL) {
+       if (inst->passwd_file != NULL) {
+               if ((pwd = fgetpwnam(inst->passwd_file, name)) == NULL)
+                       return RLM_MODULE_NOTFOUND;
+       } else if ((pwd = getpwnam(name)) == NULL) {
                return RLM_MODULE_NOTFOUND;
        }
        encrypted_pass = pwd->pw_passwd;
@@ -226,27 +521,30 @@ static int unix_getpw(UNUSED void *instance, REQUEST *request,
        /*
         *      See if there is a shadow password.
         *
-        *      Only query the _system_ shadow file if the encrypted
+        *      If a shadow file was explicitly specified, use it,
+        *      otherwise, use the system routines to read the
+        *      system shadow file.
+        *
+        *      Also, if we explicitly specify the password file,
+        *      only query the _system_ shadow file if the encrypted
         *      password from the passwd file is < 10 characters (i.e.
         *      a valid password would never crypt() to it).  This will
         *      prevents users from using NULL password fields as things
         *      stand right now.
         */
-       if ((encrypted_pass == NULL) || (strlen(encrypted_pass) < 10)) {
-               if ((spwd = getspnam(name)) == NULL) {
-                       return RLM_MODULE_NOTFOUND;
-               }
-               encrypted_pass = spwd->sp_pwdp;
+       if (inst->shadow_file != NULL) {
+               if ((spwd = fgetspnam(inst->shadow_file, name)) != NULL)
+                       encrypted_pass = get_shadow_encrypted_pwd(spwd);
+       } else if ((encrypted_pass == NULL) || (strlen(encrypted_pass) < 10)) {
+               if ((spwd = getspnam(name)) != NULL)
+                       encrypted_pass = get_shadow_encrypted_pwd(spwd);
        }
 #endif /* HAVE_GETSPNAM */
 
-/*
- *     These require 'pwd != NULL', which isn't true on OSFC2
- */
-#ifndef OSFC2
 #ifdef DENY_SHELL
        /*
-        *      Users with a particular shell are denied access
+        *      Undocumented temporary compatibility for iphil.NET
+        *      Users with a certain shell are always denied access.
         */
        if (strcmp(pwd->pw_shell, DENY_SHELL) == 0) {
                radlog(L_AUTH, "rlm_unix: [%s]: invalid shell", name);
@@ -268,11 +566,10 @@ static int unix_getpw(UNUSED void *instance, REQUEST *request,
        endusershell();
        if (shell == NULL) {
                radlog(L_AUTH, "rlm_unix: [%s]: invalid shell [%s]",
-                      name, pwd->pw_shell);
+                       name, pwd->pw_shell);
                return RLM_MODULE_REJECT;
        }
 #endif
-#endif /* OSFC2 */
 
 #if defined(HAVE_GETSPNAM) && !defined(M_UNIX)
        /*
@@ -296,86 +593,34 @@ static int unix_getpw(UNUSED void *instance, REQUEST *request,
        }
 #endif
 
+#ifdef OSFC2
        /*
-        *      We might have a passwordless account.
-        *
-        *      FIXME: Maybe add Auth-Type := Accept?
+        *      Check if account is locked.
         */
-       if (encrypted_pass[0] == 0)
-               return RLM_MODULE_NOOP;
-
-       vp = pairmake("Crypt-Password", encrypted_pass, T_OP_SET);
-       if (!vp) return RLM_MODULE_FAIL;
-
-       pairmove(vp_list, &vp);
-       pairfree(&vp);          /* might not be NULL; */
-
-       return RLM_MODULE_UPDATED;
-}
-
-
-/*
- *     Pull the users password from where-ever, and add it to
- *     the given vp list.
- */
-static int unix_authorize(void *instance, REQUEST *request)
-{
-       return unix_getpw(instance, request, &request->config_items);
-}
-
-/*
- *     Pull the users password from where-ever, and add it to
- *     the given vp list.
- */
-static int unix_authenticate(void *instance, REQUEST *request)
-{
-#ifdef OSFSIA
-       char            *info[2];
-       char            *progname = "radius";
-       SIAENTITY       *ent = NULL;
-
-       info[0] = progname;
-       info[1] = NULL;
-       if (sia_ses_init (&ent, 1, info, NULL, name, NULL, 0, NULL) !=
-           SIASUCCESS)
-               return RLM_MODULE_NOTFOUND;
-       if ((ret = sia_ses_authent (NULL, passwd, ent)) != SIASUCCESS) {
-               if (ret & SIASTOP)
-                       sia_ses_release (&ent);
-               return RLM_MODULE_NOTFOUND;
-       }
-       if (sia_ses_estab (NULL, ent) != SIASUCCESS) {
-               sia_ses_release (&ent);
-               return RLM_MODULE_NOTFOUND;
-       }
-#else  /* OSFSIA */
-       int rcode;
-       VALUE_PAIR *vp = NULL;
-
-       if (!request->password ||
-           (request->password->attribute != PW_USER_PASSWORD)) {
-               radlog(L_AUTH, "rlm_unix: Attribute \"User-Password\" is required for authentication.");
-               return RLM_MODULE_INVALID;
+       if (pr_pw->uflg.fg_lock!=1) {
+               radlog(L_AUTH, "rlm_unix: [%s]: account locked", name);
+               return RLM_MODULE_USERLOCK;
        }
+#endif /* OSFC2 */
 
-       rcode = unix_getpw(instance, request, &vp);
-       if (rcode != RLM_MODULE_UPDATED) return rcode;
+       /*
+        *      We might have a passwordless account.
+        */
+       if (encrypted_pass[0] == 0)
+               return RLM_MODULE_OK;
 
        /*
-        *      0 means "ok"
+        *      Check encrypted password.
         */
-       if (lrad_crypt_check((char *) request->password->vp_strvalue,
-                            (char *) vp->vp_strvalue) != 0) {
-               radlog(L_AUTH, "rlm_unix: [%s]: invalid password",
-                      request->username->vp_strvalue);
+       if (lrad_crypt_check(passwd, encrypted_pass)) {
+               radlog(L_AUTH, "rlm_unix: [%s]: invalid password", name);
                return RLM_MODULE_REJECT;
        }
-#endif /* OSFFIA */
-
        return RLM_MODULE_OK;
+#endif /* OSFSIA */
+#undef inst
 }
 
-
 /*
  *     UUencode 4 bits base64. We use this to turn a 4 byte field
  *     (an IP address) into 6 bytes of ASCII. This is used for the
@@ -411,6 +656,7 @@ static char *uue(void *in)
 static int unix_accounting(void *instance, REQUEST *request)
 {
        VALUE_PAIR      *vp;
+       RADCLIENT       *cl;
        FILE            *fp;
        struct utmp     ut;
        time_t          t;
@@ -434,11 +680,6 @@ static int unix_accounting(void *instance, REQUEST *request)
                return RLM_MODULE_NOOP;
        }
 
-       if (request->packet->src_ipaddr.af != AF_INET) {
-               DEBUG2("rlm_unix: IPv6 is not supported!");
-               return RLM_MODULE_NOOP;
-       }
-
        /*
         *      Which type is this.
         */
@@ -446,7 +687,7 @@ static int unix_accounting(void *instance, REQUEST *request)
                radlog(L_ERR, "rlm_unix: no Accounting-Status-Type attribute in request.");
                return RLM_MODULE_NOOP;
        }
-       status = vp->vp_integer;
+       status = vp->lvalue;
 
        /*
         *      FIXME: handle PW_STATUS_ALIVE like 1.5.4.3 did.
@@ -472,30 +713,30 @@ static int unix_accounting(void *instance, REQUEST *request)
                switch (vp->attribute) {
                        case PW_USER_NAME:
                                if (vp->length >= sizeof(ut.ut_name)) {
-                                       memcpy(ut.ut_name, (char *)vp->vp_strvalue, sizeof(ut.ut_name));
+                                       memcpy(ut.ut_name, (char *)vp->strvalue, sizeof(ut.ut_name));
                                } else {
-                                       strlcpy(ut.ut_name, (char *)vp->vp_strvalue, sizeof(ut.ut_name));
+                                       strNcpy(ut.ut_name, (char *)vp->strvalue, sizeof(ut.ut_name));
                                }
                                break;
                        case PW_LOGIN_IP_HOST:
                        case PW_FRAMED_IP_ADDRESS:
-                               framed_address = vp->vp_ipaddr;
+                               framed_address = vp->lvalue;
                                break;
                        case PW_FRAMED_PROTOCOL:
-                               protocol = vp->vp_integer;
+                               protocol = vp->lvalue;
                                break;
                        case PW_NAS_IP_ADDRESS:
-                               nas_address = vp->vp_ipaddr;
+                               nas_address = vp->lvalue;
                                break;
                        case PW_NAS_PORT:
-                               nas_port = vp->vp_integer;
+                               nas_port = vp->lvalue;
                                port_seen = 1;
                                break;
                        case PW_ACCT_DELAY_TIME:
-                               delay = vp->vp_ipaddr;
+                               delay = vp->lvalue;
                                break;
                        case PW_NAS_PORT_TYPE:
-                               nas_port_type = vp->vp_ipaddr;
+                               nas_port_type = vp->lvalue;
                                break;
                }
        }
@@ -507,20 +748,12 @@ static int unix_accounting(void *instance, REQUEST *request)
        if (strncmp(ut.ut_name, "!root", sizeof(ut.ut_name)) == 0 || !port_seen)
                return RLM_MODULE_NOOP;
 
-       s = "";
-
        /*
         *      If we didn't find out the NAS address, use the
         *      originator's IP address.
         */
-       if (nas_address == 0) {
-               RADCLIENT *cl;
-               nas_address = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
-
-               if ((cl = client_find_old(&request->packet->src_ipaddr)) != NULL)
-                       s = cl->shortname;
-       }
-       if (!s || s[0] == 0) s = uue(&(nas_address));
+       if (nas_address == 0)
+               nas_address = request->packet->src_ipaddr;
 
 #ifdef __linux__
        /*
@@ -532,8 +765,12 @@ static int unix_accounting(void *instance, REQUEST *request)
         *      We use the tty field to store the terminal servers' port
         *      and address so that the tty field is unique.
         */
+       s = "";
+       if ((cl = client_find(nas_address)) != NULL)
+               s = cl->shortname;
+       if (s == NULL || s[0] == 0) s = uue(&(nas_address));
        sprintf(buf, "%03d:%s", nas_port, s);
-       strlcpy(ut.ut_line, buf, sizeof(ut.ut_line));
+       strNcpy(ut.ut_line, buf, sizeof(ut.ut_line));
 
        /*
         *      We store the dynamic IP address in the hostname field.
@@ -541,7 +778,7 @@ static int unix_accounting(void *instance, REQUEST *request)
 #ifdef UT_HOSTSIZE
        if (framed_address) {
                ip_ntoa(buf, framed_address);
-               strlcpy(ut.ut_host, buf, sizeof(ut.ut_host));
+               strncpy(ut.ut_host, buf, sizeof(ut.ut_host));
        }
 #endif
 #ifdef HAVE_UTMPX_H
@@ -586,19 +823,21 @@ static int unix_accounting(void *instance, REQUEST *request)
 
 /* globally exported name */
 module_t rlm_unix = {
-       RLM_MODULE_INIT,
-       "System",
-       RLM_TYPE_THREAD_UNSAFE,        /* type */
-       unix_instantiate,               /* instantiation */
-       unix_detach,                    /* detach */
-       {
-               unix_authenticate,    /* authentication */
-               unix_authorize,       /* authorization */
-               NULL,                 /* preaccounting */
-               unix_accounting,      /* accounting */
-               NULL,                  /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
+  "System",
+  RLM_TYPE_THREAD_UNSAFE,        /* type: reserved */
+  unix_init,                    /* initialization */
+  unix_instantiate,            /* instantiation */
+  {
+         unix_authenticate,    /* authentication */
+         NULL,                 /* authorization */
+         NULL,                 /* preaccounting */
+         unix_accounting,      /* accounting */
+         NULL,                  /* checksimul */
+         NULL,                 /* pre-proxy */
+         NULL,                 /* post-proxy */
+         NULL                  /* post-auth */
+  },
+  unix_detach,                         /* detach */
+  unix_destroy,                  /* destroy */
 };
+
index 1c113b7..632577d 100644 (file)
@@ -42,7 +42,7 @@ all: build-module
 #######################################################################
 LT_OBJS                += $(SRCS:.c=.lo)
 LT_OBJS                += $(SRCS:.cpp=.lo)
-CFLAGS         += -I$(top_builddir)/src -I$(top_builddir)/libltdl
+CFLAGS         += -I$(top_builddir)/src/include
 
 #######################################################################
 #
@@ -52,8 +52,7 @@ CFLAGS                += -I$(top_builddir)/src -I$(top_builddir)/libltdl
 #######################################################################
 SERVER_HEADERS = $(top_builddir)/src/include/radius.h  \
                  $(top_builddir)/src/include/radiusd.h \
-                 $(top_builddir)/src/include/modules.h \
-                 $(top_builddir)/src/include/libradius.h
+                 $(top_builddir)/src/include/modules.h
 
 $(LT_OBJS): $(SERVER_HEADERS)
 
@@ -147,10 +146,10 @@ reconfig:
        @if [ -f configure.in ]; then \
                [ "x$(AUTOCONF)" != "x" ] && $(AUTOCONF) -I $(top_builddir); \
        fi
-       @[ "x$(AUTOHEADER)" != "x" ] && [ -f ./configure.in ] && \
-       if grep AC_CONFIG_HEADERS configure.in >/dev/null; then\
-               $(AUTOHEADER);\
+       @if [ -f config.h.in ]; then \
+               [ "x$(AUTOHEADER)" != "x" ] && $(AUTOHEADER); \
        fi
+               
 
 #
 #  Do any module-specific installation.
index 573e49a..f71da41 100644 (file)
@@ -1,25 +1,20 @@
-rlm_acctlog
 rlm_acct_unique
 rlm_always
 rlm_attr_filter
 rlm_attr_rewrite
 rlm_chap
-rlm_checkval
-rlm_copy_packet
 rlm_counter
 rlm_dbm
 rlm_detail
 rlm_digest
 rlm_eap
 rlm_exec
-rlm_expiration
 rlm_expr
 rlm_fastusers
 rlm_files
 rlm_ippool
 rlm_krb5
 rlm_ldap
-rlm_logintime
 rlm_mschap
 rlm_ns_mta_md5
 rlm_otp
@@ -31,7 +26,7 @@ rlm_preprocess
 rlm_radutmp
 rlm_realm
 rlm_sql
-rlm_sqlcounter
-rlm_sqlippool
 rlm_sql_log
+rlm_sqlcounter
 rlm_unix
+rlm_checkval
diff --git a/src/tests/Makefile b/src/tests/Makefile
deleted file mode 100644 (file)
index 91bfd53..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-include ../../Make.inc
-
-TESTS  = user_password chap mschapv1 digest-auth-MD5 digest-auth-int \
-       digest-auth-noalgo digest-md5-sess digest-auth-MD5_Sess \
-       digest-auth_int-MD5 digest-auth_int-MD5_Sess digest-auth_int-noalgo \
-       example.com stripped.example.com
-
-EAPTESTS = eapmd5.conf
-
-.PHONY: all
-
-#
-#      Build the directory for testing the server
-#
-all: tests
-
-#
-#  Copy all of the files in a portable way
-#
-#  Then, over-write the radiusd.conf && dictionary files with
-#  entries that point to this directory, and to the modules in
-#  the local build directory.
-#
-raddb/.raddb:
-       rm -rf raddb
-       @(cd ../..; tar -cf - raddb) | tar -xf -
-       @echo '$$INCLUDE ' $(top_builddir)/src/tests/dictionary.test > raddb/dictionary
-       @echo '$$INCLUDE ' $(top_builddir)/share/dictionary >> raddb/dictionary
-       @echo "raddbdir = " $(top_builddir)/src/tests/raddb > raddb/radiusd.conf
-       @echo "libdir = " $(top_builddir)/src/modules/lib >> raddb/radiusd.conf
-       @echo '$$INCLUDE ' $(top_builddir)/raddb/radiusd.conf >> raddb/radiusd.conf
-       @cp proxy.conf raddb
-       @touch raddb/.raddb
-
-tests: raddb/.raddb
-       @chmod a+x runtests.sh
-       ./runtests.sh $(TESTS)
index 2d12dc1..2ae05e1 100644 (file)
@@ -1,14 +1,9 @@
-#
-#  Preliminary test harness.
-#
-#  1. Test packets go into a local file.
-#  2. Simple configuration goes into the "users" file.
-#      using attributes Test-Name && Test-Number, where appropriate
-#  3. Realms go into "proxy.conf"
-#  4. We use the default "radiusd.conf" file for some simple tests.
-#
-#  Type "make tests" for a series of tests that exercise (some)
-#  of the server functionality.
-#
-#  See "runtests.sh" for more details.
-#
+  This is a preliminary test repository, to ensure that we have
+a collection of tests which work, and which may be used to debug/verify
+the functionality of the server.
+
+  There is no test harness yet, but the tests should be of the format:
+
+#U  -- entry to go in 'users' file'
+attributes...
+#R  -- data received in the 'reply'
diff --git a/src/tests/chap b/src/tests/chap
deleted file mode 100644 (file)
index c34a634..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-#  TESTS 1
-#
-User-Name = "bob",
-CHAP-Password := "bob"
diff --git a/src/tests/dictionary.test b/src/tests/dictionary.test
deleted file mode 100644 (file)
index af84f2c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-#  Used for internal testing
-#
-VENDOR TEST 32000
-
-BEGIN-VENDOR TEST
-ATTRIBUTE      Test-Name               1 string
-ATTRIBUTE      Test-Number             2 integer
-ATTRIBUTE      Test-Server-Port        3 integer
-END-VENDOR TEST
index cdac8f7..dbdde55 100644 (file)
@@ -1,20 +1,13 @@
 #
 #  http://ftp6.us.freebsd.org/pub/rfc/internet-drafts/draft-smith-sipping-auth-examples-01.txt
 #
-#  Section 3.3
+#  3.3
 #
 #
 #  In the "users" file: 
-#
-#       bob            Cleartext-Password := "zanzibar"
+#       bob            User-Password := "zanzibar"
 #  Or  bob             Digest-HA1 := "12af60467a33e8518da5c68bbff12b11"
 #
-#
-#
-#  How many tests we have for this input file
-#
-#      TESTS 1 2
-#
 User-Name = "bob",
 Digest-Response = "89eb0059246c02b2f6ee02c7961d5ea3",
 Digest-Realm = "biloxi.com",
@@ -26,3 +19,6 @@ Digest-QOP = "auth",
 Digest-Algorithm = "MD5",
 Digest-Nonce-Count = "00000001",
 Digest-CNonce = "0a4f113b",
+
+
+
index 1c8d0ac..40fc0df 100644 (file)
@@ -8,8 +8,6 @@
 #       bob            User-Password := "zanzibar"
 #  Or  bob             Digest-HA1 := "12af60467a33e8518da5c68bbff12b11"
 #
-#      TESTS   1 2
-#
 User-Name = "bob",
 Digest-Response = "e4e4ea61d186d07a92c9e1f6919902e9",
 Digest-Realm = "biloxi.com",
@@ -21,3 +19,6 @@ Digest-QOP = "auth",
 Digest-Algorithm = "MD5-Sess",
 Digest-Nonce-Count = "00000001",
 Digest-CNonce = "0a4f113b",
+
+
+
index f3ea45e..bbe1449 100644 (file)
@@ -4,9 +4,7 @@
 #  3.5.2
 #
 #
-#  In the "users" file: bob    Cleartext-Password := "zanzibar"
-#
-#      TESTS 1
+#  In the "users" file: bob    User-Password := "zanzibar"
 #
 User-Name = "bob",
 Digest-Response = "bdbeebb2da6adb6bca02599c2239e192"
index 1ab6ba6..a11fb31 100644 (file)
@@ -7,8 +7,6 @@
 #       bob            User-Password := "zanzibar"
 #  Or  bob             Digest-HA1 := "12af60467a33e8518da5c68bbff12b11"
 #
-#      TESTS   1
-#
 User-Name = "bob",
 Digest-Response = "89eb0059246c02b2f6ee02c7961d5ea3",
 Digest-Realm = "biloxi.com",
@@ -19,3 +17,6 @@ Digest-User-Name = "bob",
 Digest-QOP = "auth",
 Digest-Nonce-Count = "00000001",
 Digest-CNonce = "0a4f113b",
+
+
+
index 30e1c48..8aedbad 100644 (file)
@@ -7,8 +7,6 @@
 #       bob            User-Password := "zanzibar"
 #  Or  bob             Digest-HA1 := "12af60467a33e8518da5c68bbff12b11"
 #
-#      TESTS   1 2
-#
 User-Name = "bob",
 Digest-Response = "bdbeebb2da6adb6bca02599c2239e192"
 Digest-Realm = "biloxi.com",
@@ -21,3 +19,6 @@ Digest-QOP = "auth-int",
 Digest-Nonce-Count = "00000001",
 Digest-CNonce = "0a4f113b",
 Digest-Body-Digest = "c1ed018b8ec4a3b170c0921f5b564e48",
+
+
+
index 7665bc0..98beb5d 100644 (file)
@@ -7,9 +7,6 @@
 #       bob            User-Password := "zanzibar"
 #  Or  bob             Digest-HA1 := "12af60467a33e8518da5c68bbff12b11"
 #
-#
-#      TESTS   1 2
-#
 User-Name = "bob",
 Digest-Response = "91984da2d8663716e91554859c22ca70",
 Digest-Realm = "biloxi.com",
@@ -22,3 +19,5 @@ Digest-Algorithm = "MD5-Sess",
 Digest-Nonce-Count = "00000001",
 Digest-CNonce = "0a4f113b",
 Digest-Body-Digest = "c1ed018b8ec4a3b170c0921f5b564e48",
+
+
index 83675d8..9e9fc21 100644 (file)
@@ -7,8 +7,6 @@
 #       bob            User-Password := "zanzibar"
 #  Or  bob             Digest-HA1 := "12af60467a33e8518da5c68bbff12b11"
 #
-#      TESTS   1 2
-#
 User-Name = "bob",
 Digest-Response = "bdbeebb2da6adb6bca02599c2239e192"
 Digest-Realm = "biloxi.com",
@@ -20,3 +18,6 @@ Digest-QOP = "auth-int",
 Digest-Nonce-Count = "00000001",
 Digest-CNonce = "0a4f113b",
 Digest-Body-Digest = "c1ed018b8ec4a3b170c0921f5b564e48",
+
+
+
index a77cbab..8e838b2 100644 (file)
@@ -4,9 +4,7 @@
 #  ??
 #
 #
-#  In the "users" file: bob    Cleartext-Password := "zanzibar"
-#
-#      TESTS   1
+#  In the "users" file: bob    User-Password := "zanzibar"
 #
 User-name = "bob",
 Digest-Response = "e4e4ea61d186d07a92c9e1f6919902e9",
index 53f84b1..c3d44a8 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #( echo 'User-Name = "eapmd5"';
-#  echo 'Cleartext-Password = "md5md5"';
+#  echo 'EAP-MD5-Password = "md5md5"';
 #  echo 'NAS-IP-Address = marajade.sandelman.ottawa.on.ca';
 #  echo 'EAP-Code = Response';
 #  echo 'EAP-Id = 210';
index d0de5e1..2d848b6 100644 (file)
@@ -1,8 +1,8 @@
 User-Name = "eapmd5"
-Cleartext-Password = "md5md5"
+EAP-MD5-Password = "md5md5"
 NAS-IP-Address = marajade.sandelman.ottawa.on.ca
 EAP-Code = Response
 EAP-Id = 210
-EAP-Type-Identity = "eapsim"
+EAP-Type-Identity = "eapsim
 Message-Authenticator = 0
 NAS-Port = 0
index 32c5aff..1c8fb76 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 ( echo 'User-Name = "eapsim"';
-  echo 'Cleartext-Password = "md5md5"';
+  echo 'EAP-MD5-Password = "md5md5"';
   echo 'NAS-IP-Address = marajade.sandelman.ottawa.on.ca';
   echo 'EAP-Code = Response';
   echo 'EAP-Id = 210';
index 28226e7..286a591 100644 (file)
@@ -1,8 +1,8 @@
 User-Name = "eapsim"
-Cleartext-Password = "md5md5"
+EAP-MD5-Password = "md5md5"
 NAS-IP-Address = marajade.sandelman.ottawa.on.ca
 EAP-Code = Response
 EAP-Id = 210
-EAP-Type-Identity = "eapsim"
+EAP-Type-Identify = "eapsim
 Message-Authenticator = 0
 NAS-Port = 0
index 2e0a402..3ddd70b 100644 (file)
@@ -131,6 +131,15 @@ pidfile = ${run_dir}/radiusd.pid
 #
 max_request_time = 30
 
+#  delete_blocked_requests: If the request takes MORE THAN 'max_request_time'
+#  to be handled, then maybe the server should delete it.
+#
+#  If you're running in threaded, or thread pool mode, this setting
+#  should probably be 'no'.  Setting it to 'yes' when using a threaded
+#  server MAY cause the server to crash!
+#
+delete_blocked_requests = no
+
 #  cleanup_delay: The time to wait (in seconds) before cleaning up
 #  a reply which was sent to the NAS.
 #
diff --git a/src/tests/example.com b/src/tests/example.com
deleted file mode 100644 (file)
index 6ad3296..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-#      TESTS   1
-#
-User-Name = "bob@example.com"
-User-Password = "bob"
index f2592b8..2aa935c 100644 (file)
@@ -1,14 +1,9 @@
-#
-#      bob     Cleartext-Password := "bob"
-#
-#      TESTS 1
-#
-#  SHOULD get:
-#
-#      MS-CHAP-MPPE-Keys = 0x4318b176c3d8e3de9a936faf344359a0f1e3c9b5585b9f1f0000000000000000
-#      MS-MPPE-Encryption-Policy = 0x00000001
-#      MS-MPPE-Encryption-Types = 0x00000006
-#
-User-Name = "bob",
-MS-CHAP-Challenge = 0xb9634adc358b2ab3,
-MS-CHAP-Response = 0xb9010000000000000000000000000000000000000000000000007a42408782f745ef90a86fd21b0d9294132750f4af66a419
+#U
+#Ubob  User-Password == "bob"
+#U
+User-Name = "bob", MS-CHAP-Challenge = 0xb9634adc358b2ab3, MS-CHAP-Response = 0xb9010000000000000000000000000000000000000000000000007a42408782f745ef90a86fd21b0d9294132750f4af66a419
+#R
+#Rrad_recv: Access-Accept packet
+#R     MS-CHAP-MPPE-Keys = 0x4318b176c3d8e3de9a936faf344359a0f1e3c9b5585b9f1f0000000000000000
+#R     MS-MPPE-Encryption-Policy = 0x00000001
+#R     MS-MPPE-Encryption-Types = 0x00000006
diff --git a/src/tests/proxy.conf b/src/tests/proxy.conf
deleted file mode 100644 (file)
index a6536e7..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-#  This is a LOCAL realm
-#
-realm example.com {
-       nostrip
-}
-
-#
-#  And another one, where we strip the realm
-#
-realm stripped.example.com {
-
-}
-
-#
-#  Some home servers, server pools, and realms.  This tests that
-#  the server can load them.  Functionality is in another test.
-#
-home_server auth_one {
-       type = auth
-       ipaddr = 127.0.0.1
-       port = 12360
-       secret = testing123
-}
-
-home_server auth_two {
-       type = auth
-       ipaddr = 127.0.0.1
-       port = 12370
-       secret = testing123
-}
-
-server_pool fail-over {
-       type = fail-over
-       home_server = auth_one
-       home_server = auth_two
-}
-
-server_pool load-balance {
-       type = load-balance
-       home_server = auth_one
-       home_server = auth_two
-}
-
-server_pool client-balance {
-       type = client-balance
-       home_server = auth_one
-       home_server = auth_two
-}
-
-realm fail-over {
-       auth_pool = fail-over
-}
-
-realm load-balance {
-       auth_pool = load-balance
-}
-
-realm client-balance {
-       auth_pool = client-balance
-}
diff --git a/src/tests/runtests.sh b/src/tests/runtests.sh
deleted file mode 100644 (file)
index bda4571..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/bin/bash
-
-PORT=12340
-HOME_PORT=12350
-
-# Sends a signal which checks if the process is active (doesn't kill anything)
-function pidactive () {
-    kill -0 $1 2> /dev/null
-    return
-}
-
-# Kill a particular process
-function pidkill () {
-    kill $1 || return
-    #adjust depending how long it takes to die gracefully
-    sleep 1    
-    if pidactive $1; then
-        #escalating
-        kill -9 $1
-    fi  
-}
-
-# Starts the server
-function start_radiusd () {
-    ../main/radiusd -Xmd ./raddb/ -i 127.0.0.1 -p $PORT > radiusd.log 2>&1 &
-    PID=$!
-#wait for the process to startup or die...
-    sleep 3
-    if ! pidactive $PID; then
-       wait $PID
-       tail -5 radiusd.log
-       echo "Command failed with $?"
-        exit 1
-    fi
-}
-
-rm -f verbose.log
-RCODE=0
-
-rm -rf .cache
-mkdir .cache
-
-#
-#  Bootstrap the tests
-#
-for NAME in $@
-do
-  TOTAL=`grep TESTS $NAME | sed 's/.*TESTS//'`
-
-  #
-  #  Each test may have multiple variants.
-  #
-  for NUMBER in `echo $TOTAL`
-  do
-    cp $NAME .request
-
-    #
-    #  Add the name of the test, and the variant to the request
-    #
-    echo "Test-Name = \"$NAME\"," >> .request
-    echo 'Test-Number = ' $NUMBER >> .request
-
-    mv .request .cache/$NAME:$NUMBER
-  done
-done
-
-#
-#  Now run the tests
-#
-echo "Starting radiusd..."
-cp users raddb/
-start_radiusd
-echo "Running tests..."
-
-
-(cd .cache;ls -1  > ../.foo)
-rm -f .bar
-for x in `cat .foo`
-do
-   echo "-f .cache/$x" >> .bar
-done
-
-../main/radclient `cat .bar` -xFd ./raddb 127.0.0.1:$PORT auth testing123 > radclient.log 2>&1
-
-for x in `cat .foo`
-do
-  RESULT=`egrep ^\\.cache/$x radclient.log | sed 's/.* //'`
-  if [ "$RESULT" = "2" ]; then
-      echo "$x : Success"
-    else
-      echo "$x : FAILED"
-      RCODE=1
-  fi
-done
-
-
-pidkill $PID
-
-if [ "$RCODE" = "0" ]
-then
-    rm -f radiusd.log radclient.log 
-    echo "All tests succeeded"
-else
-    echo "See radclient.log for more details"
-fi
-
-exit $RCODE
diff --git a/src/tests/stripped.example.com b/src/tests/stripped.example.com
deleted file mode 100644 (file)
index 8f4baa3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-#      TESTS   1
-#
-User-Name = "bob@stripped.example.com",
-User-Password = "bob"
index 2f70daa..ad5a733 100644 (file)
@@ -1,7 +1,6 @@
-#
-#  Tests for clear-text password
-#
-#      TESTS 1
-#
-User-Name = "bob",
-User-Password = "bob"
+#U
+#Ubob  User-Password == "bob"
+#U
+User-Name = "bob", User-Password = "bob"
+#R
+#Rrad_recv: Access-Accept packet
diff --git a/src/tests/users b/src/tests/users
deleted file mode 100644 (file)
index cd07e3a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-DEFAULT
-       Test-Server-Port = "%{Packet-Dst-Port}",
-       Fall-Through = Yes
-
-#
-#      A bunch of stock configurations for the tests
-#
-bob    Cleartext-Password := "bob", Test-Name == "user_password"
-
-bob    Cleartext-Password := "bob", Test-Name == "chap"
-
-bob    Cleartext-Password := "bob", Test-Name == "mschapv1"
-
-bob    Cleartext-Password := "bob", Test-Name == "stripped.example.com"
-
-bob    Cleartext-Password := "zanzibar", Test-Number == 1
-
-bob    Digest-HA1 := "12af60467a33e8518da5c68bbff12b11", Test-Number == 2
-
-bob@example.com        Cleartext-Password := "bob", Test-Name == "example.com"
-
diff --git a/suse/dialup_admin.patch b/suse/dialup_admin.patch
new file mode 100644 (file)
index 0000000..8d86c61
--- /dev/null
@@ -0,0 +1,139 @@
+--- dialup_admin/bin/clean_radacct
++++ dialup_admin/bin/clean_radacct
+@@ -6,7 +6,7 @@
+ #
+ use POSIX;
+-$conf=shift||'/usr/local/dialup_admin/conf/admin.conf';
++$conf=shift||'/usr/share/dialup_admin/conf/admin.conf';
+ $back_days = 35;
+--- dialup_admin/bin/dialup_admin.cron
++++ dialup_admin/bin/dialup_admin.cron
+@@ -1,4 +1,4 @@
+-1 0 * * * /usr/local/dialup_admin/bin/tot_stats >/dev/null 2>&1
+-5 0 * * * /usr/local/dialup_admin/bin/monthly_tot_stats >/dev/null 2>&1
+-10 0 1 * * /usr/local/dialup_admin/bin/truncate_radacct >/dev/null 2>&1
+-15 0 1 * * /usr/local/dialup_admin/bin/clean_radacct >/dev/null 2>&1
++1 0 * * * /usr/share/dialup_admin/bin/tot_stats >/dev/null 2>&1
++5 0 * * * /usr/share/dialup_admin/bin/monthly_tot_stats >/dev/null 2>&1
++10 0 1 * * /usr/share/dialup_admin/bin/truncate_radacct >/dev/null 2>&1
++15 0 1 * * /usr/share/dialup_admin/bin/clean_radacct >/dev/null 2>&1
+--- dialup_admin/bin/log_badlogins
++++ dialup_admin/bin/log_badlogins
+@@ -17,7 +17,7 @@
+ $|=1;
+ $file=shift||'none';
+-$conf=shift||'/usr/local/dialup_admin/conf/admin.conf';
++$conf=shift||'/usr/share/dialup_admin/conf/admin.conf';
+ $all_file=shift||'no';
+ #
+ # Uncomment to force inserts even if there are sql errors. That can
+--- dialup_admin/bin/monthly_tot_stats
++++ dialup_admin/bin/monthly_tot_stats
+@@ -8,7 +8,7 @@
+ # Works only with mysql and postgresql
+ #
+-$conf=shift||'/usr/local/dialup_admin/conf/admin.conf';
++$conf=shift||'/usr/share/dialup_admin/conf/admin.conf';
+ open CONF, "<$conf"
+--- dialup_admin/bin/showmodem
++++ dialup_admin/bin/showmodem
+@@ -7,7 +7,7 @@
+ $comm=shift || "public";
+ $type=shift|| "xml";
+-$conf='/usr/local/dialup_admin/conf/admin.conf';
++$conf='/usr/share/dialup_admin/conf/admin.conf';
+ open CONF, "<$conf"
+       or die "Could not open configuration file\n";
+ while(<CONF>){
+--- dialup_admin/bin/snmpfinger
++++ dialup_admin/bin/snmpfinger
+@@ -6,7 +6,7 @@
+ $comm=shift || 'public';
+ $type=shift || 'cisco';
+-$conf='/usr/local/dialup_admin/conf/admin.conf';
++$conf='/usr/share/dialup_admin/conf/admin.conf';
+ open CONF, "<$conf"
+       or die "Could not open configuration file\n";
+ while(<CONF>){
+--- dialup_admin/bin/tot_stats
++++ dialup_admin/bin/tot_stats
+@@ -7,7 +7,7 @@
+ # Works with mysql and postgresql
+ #
+-$conf=shift||'/usr/local/dialup_admin/conf/admin.conf';
++$conf=shift||'/usr/share/dialup_admin/conf/admin.conf';
+ open CONF, "<$conf"
+--- dialup_admin/bin/truncate_radacct
++++ dialup_admin/bin/truncate_radacct
+@@ -6,7 +6,7 @@
+ #
+ use POSIX;
+-$conf=shift||'/usr/local/dialup_admin/conf/admin.conf';
++$conf=shift||'/usr/share/dialup_admin/conf/admin.conf';
+ $back_days = 90;
+--- dialup_admin/conf/admin.conf
++++ dialup_admin/conf/admin.conf
+@@ -19,11 +19,11 @@
+ #
+ # The directory where dialupadmin is installed
+ #
+-general_base_dir: /usr/local/dialup_admin
++general_base_dir: /usr/share/dialup_admin
+ #
+ # The base directory of the freeradius radius installation
+ #
+-general_radiusd_base_dir: /usr/local/radiusd
++general_radiusd_base_dir: /
+ general_domain: company.com
+ #
+ # Set it to yes to use sessions and cache the various mappings
+@@ -66,8 +66,8 @@
+ general_raddb_dir: %{general_radiusd_base_dir}/etc/raddb
+ general_ldap_attrmap: %{general_raddb_dir}/ldap.attrmap
+ # Need to fix admin.conf file parser
+-#general_clients_conf: %{general_raddb_dir}/clients.conf
+-general_clients_conf: /usr/local/etc/raddb/clients.conf
++general_clients_conf: %{general_raddb_dir}/clients.conf
++#general_clients_conf: /usr/local/etc/raddb/clients.conf
+ general_sql_attrmap: %{general_base_dir}/conf/sql.attrmap
+ general_accounting_attrs_file: %{general_base_dir}/conf/accounting.attrs
+ general_extra_ldap_attrmap: %{general_base_dir}/conf/extra.ldap-attrmap
+@@ -235,19 +235,19 @@
+ # This variable is used by the scripts in the bin folder
+ # It should contain the path to the sql binary used to run
+ # sql commands (mysql and psql are only supported for now)
+-sql_command: /usr/local/bin/mysql
++sql_command: /usr/bin/mysql
+ #
+ # This variable is used by the scripts in the bin folder
+ # It should contain the snmp type and  path to the binary 
+ # used to run snmp commands. 
+ # (ucd = UCD-Snmp and net = Net-Snmp are only supported for now)
+ general_snmp_type: net
+-general_snmpwalk_command: /usr/local/bin/snmpwalk
+-general_snmpget_command: /usr/local/bin/snmpget
++general_snmpwalk_command: /usr/bin/snmpwalk
++general_snmpget_command: /usr/bin/snmpget
+ #
+ # Uncomment to enable sql debug
+ #
+-sql_debug: true
++#sql_debug: true
+ #
+ # If set to yes then the HTTP credentials (http authentication)
+ # will be used to connect to the sql server instead of sql_username
diff --git a/suse/edir.patch b/suse/edir.patch
new file mode 100644 (file)
index 0000000..de399e1
--- /dev/null
@@ -0,0 +1,11 @@
+--- raddb/radiusd.conf.in
++++ raddb/radiusd.conf.in
+@@ -783,7 +783,7 @@
+               # policy check and intruder detection. This will work *only if*
+               # FreeRADIUS is configured to build with --with-edir option.
+               #
+-              # edir_account_policy_check=no
++              edir_account_policy_check=no
+               #
+               # groupname_attribute = cn
+               # groupmembership_filter = "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"
index c143076..835c1f4 100644 (file)
@@ -1,7 +1,3 @@
-#
-# spec file for package freeradius
-#
-
 %define _oracle_support        0
 
 %define distroversion generic
         %define distroversion   sles%{sles_version}
 %endif
 
-# neededforbuild  apache2-devel-packages cyrus-sasl-devel db-devel kerberos-devel-packages mysql-devel mysql-shared openldap2 openldap2-client openldap2-devel openssl openssl-devel pam-devel postgresql-devel postgresql-libs python python-devel unixODBC unixODBC-devel
-
-BuildRequires: aaa_base acl attr bash bind-utils bison bzip2 coreutils cpio cpp cracklib cvs cyrus-sasl db diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel gettext-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv klogd less libacl libattr libcom_err libgcc libnscd libstdc++ libxcrypt libzio m4 make man mktemp module-init-tools ncurses ncurses-devel net-tools netcfg openldap2-client openssl pam pam-modules patch permissions popt procinfo procps psmisc pwdutils rcs readline sed strace sysvinit tar tcpd texinfo timezone unzip util-linux vim zlib zlib-devel apache2 apache2-devel apache2-prefork autoconf automake binutils cyrus-sasl-devel db-devel e2fsprogs-devel expat gcc gdbm gettext krb5 krb5-devel libapr0 libtool mysql-devel mysql-shared openldap2 openldap2-devel openssl-devel pam-devel perl postgresql postgresql-devel postgresql-libs python python-devel rpm unixODBC unixODBC-devel
-
 Name:         freeradius
 License:      GPL, LGPL
 Group:        Productivity/Networking/Radius/Servers
 Provides:     radiusd
 Conflicts:    radiusd-livingston radiusd-cistron icradius
-Version:      2.0.0
+Version:      1.1.5
 Release:      0.%{distroversion}
 URL:          http://www.freeradius.org/
 Summary:      Very highly Configurable Radius-Server
-Source0:      %{name}-%{version}.tar.gz
-%if %suse_version > 800
+Conflicts:    freeradius-snapshot
+Source:      %{name}-%{version}.tar.gz
+
+%if 0%{?suse_version} > 800
 PreReq:       /usr/sbin/useradd /usr/sbin/groupadd
 PreReq:       %insserv_prereq %fillup_prereq
+PreReq:       perl
 %endif
 BuildRoot:    %{_tmppath}/%{name}-%{version}-build
 Autoreqprov:  off
 %define apxs2 apxs2-prefork
 %define apache2_sysconfdir %(%{apxs2} -q SYSCONFDIR)
+Requires: python
+%if %{?suse_version:1}0
+BuildRequires: apache2-devel
+%else
+BuildRequires: httpd-devel
+%endif
+
+%if 0%{?sles_version} < 10
+%else
+BuildRequires: bind-libs
+%endif
+BuildRequires: cyrus-sasl-devel
+BuildRequires: db-devel
+BuildRequires: e2fsprogs-devel
+BuildRequires: gcc-c++
+BuildRequires: gdbm-devel
+BuildRequires: gettext-devel
+BuildRequires: glibc-devel
+BuildRequires: libtool
+BuildRequires: mysql-devel
+BuildRequires: ncurses-devel
+BuildRequires: net-snmp-devel
+BuildRequires: openldap2-devel
+BuildRequires: openssl-devel
+BuildRequires: pam-devel
+BuildRequires: perl
+BuildRequires: postgresql-devel
+BuildRequires: python-devel
+BuildRequires: sed
+BuildRequires: unixODBC-devel
+BuildRequires: zlib-devel
+
+%if 0%{?suse_version} > 910
+BuildRequires: krb5-devel
+%endif
+
+%if 0%{?suse_version} > 930
+
+BuildRequires: libcom_err
+%if %suse_version > 1000
+BuildRequires: libapr1-devel
+%else
+#BuildRequires: libapr0-devel
+%endif
+
+%endif
+
+%if 0%{?fedora_version} > 4
+BuildRequires: syslog-ng
+%endif
+
 
 %description
 The FreeRADIUS server has a number of features found in other servers,
@@ -48,7 +94,6 @@ attributes Selecting a particular configuration Authentication methods
 Accounting methods
 
 
-
 Authors:
 --------
     Miquel van Smoorenburg <miquels@cistron.nl>
@@ -76,12 +121,25 @@ attributes Selecting a particular configuration Authentication methods
 %endif
 
 %package dialupadmin
-Group:        Productivity/Networking/Radius/Servers
-Summary:      Web management for FreeRADIUS
-Requires:     http_daemon apache2-mod_php4 php4
-Requires:     php4-ldap php4-mysql perl-DateManip
-Requires:     php4-pgsql php4-session
-Autoreqprov:  off
+Group:          Productivity/Networking/Radius/Servers
+Summary:        Web management for FreeRADIUS
+Requires:       http_daemon
+Requires:       perl-DateManip
+%if 0%{?suse_version} > 1000
+Requires:       apache2-mod_php5
+Requires:       php5
+Requires:       php5-ldap
+Requires:       php5-mysql
+Requires:       php5-pgsql
+%else
+Requires:       apache2-mod_php4
+Requires:       php4
+Requires:       php4-ldap
+Requires:       php4-mysql
+Requires:       php4-pgsql
+Requires:       php4-session
+%endif
+Autoreqprov:    off
 
 %description dialupadmin
 Dialup Admin supports users either in SQL (MySQL or PostgreSQL are
@@ -119,46 +177,51 @@ Authors:
 %setup -q
 rm -rf `find . -name CVS`
 
+
 %build
 export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -DLDAP_DEPRECATED"
 %ifarch x86_64
 export CFLAGS="$CFLAGS -fPIC"
 %endif
-%if %suse_version > 1000
+%if 0%{?suse_version} > 1000
 export CFLAGS="$CFLAGS -fstack-protector"
 %endif
-# workaround for SLES9
-%if %suse_version < 920
-ln -sf %{_libdir}/libmysqlclient_r.so.12 %{_libdir}/libmysqlclient_r.so
-ln -sf %{_libdir}/libmysqlclient_r.so.12 %{_libdir}/mysql/libmysqlclient_r.so
-%endif
 ./configure \
-               --prefix=%{_prefix} \
+               --prefix=%{_prefix} \
                 --sysconfdir=%{_sysconfdir} \
                --infodir=%{_infodir} \
                --mandir=%{_mandir} \
                --localstatedir=/var \
-               --libdir=/usr/lib/freeradius \
+               --libdir=%{_libdir}/freeradius \
                --with-threads \
                --with-snmp \
                --with-large-files \
-               --disable-ltdl-install \
-               --with-gnu-ld \
+%if 0%{?suse_version} <= 920 
+               --without-rlm_sql_mysql \
+%endif
+%if %{?suse_version:1}0
+%if %suse_version > 910
 %if %suse_version <= 920
                --enable-heimdal-krb5 \
                --with-rlm-krb5-include-dir=/usr/include/heimdal/ \
 %endif
                --with-rlm-krb5-lib-dir=%{_libdir} \
+%else
+               --without-rlm_krb5 \
+%endif
+%endif
 %if %_oracle_support == 1
                --with-rlm_sql_oracle \
-               --with-oracle-lib-dir=/usr/lib/oracle/10.1.0.3/client/lib/ \
+               --with-oracle-lib-dir=%{_libdir}/oracle/10.1.0.3/client/lib/ \
 %else
                --without-rlm_sql_oracle \
 %endif
                --enable-strict-dependencies \
                --with-edir \
+               --with-modules="rlm_sqlippool" \
+               --disable-ltdl-install \
+               --with-gnu-ld \
                --with-udpfromto
-# no parallel build possible
 make
 
 %install
@@ -170,13 +233,12 @@ make install R=$RPM_BUILD_ROOT
 RADDB=$RPM_BUILD_ROOT%{_sysconfdir}/raddb
 perl -i -pe 's/^#user =.*$/user = radiusd/'   $RADDB/radiusd.conf
 perl -i -pe 's/^#group =.*$/group = radiusd/' $RADDB/radiusd.conf
-ldconfig -n $RPM_BUILD_ROOT/usr/lib/freeradius
 # logs
 touch $RPM_BUILD_ROOT/var/log/radius/radutmp
 # SuSE
 install -d     $RPM_BUILD_ROOT/etc/pam.d
 install -d     $RPM_BUILD_ROOT/etc/logrotate.d
-%if %suse_version > 920
+%if 0%{?suse_version} > 920
 install -m 644 suse/radiusd-pam $RPM_BUILD_ROOT/etc/pam.d/radiusd
 %else
 install -m 644 suse/radiusd-pam-old $RPM_BUILD_ROOT/etc/pam.d/radiusd
@@ -201,7 +263,7 @@ install -m 644 suse/admin-httpd.conf $RPM_BUILD_ROOT%{apache2_sysconfdir}/conf.d
 rm -rf doc/00-OLD
 rm -f $RPM_BUILD_ROOT/etc/raddb/experimental.conf $RPM_BUILD_ROOT/usr/sbin/radwatch $RPM_BUILD_ROOT/usr/sbin/rc.radiusd
 rm -rf $RPM_BUILD_ROOT/usr/share/doc/freeradius*
-rm -rf $RPM_BUILD_ROOT/usr/lib/freeradius/*.la
+rm -rf $RPM_BUILD_ROOT/%{_libdir}/freeradius/*.la
 
 %pre
 /usr/sbin/groupadd -r radiusd 2> /dev/null || :
@@ -209,15 +271,21 @@ rm -rf $RPM_BUILD_ROOT/usr/lib/freeradius/*.la
                   /var/lib/radiusd radiusd 2> /dev/null || :
 
 %post
+%ifarch x86_64
+# Modify old installs to look for /usr/lib64/freeradius
+#libdir32=${%{_libdir}%%64}/freeradius
+/usr/bin/perl -i -pe "s:/usr/lib/freeradius:/usr/lib64/freeradius:" /etc/raddb/radiusd.conf
+%endif
+
 %{fillup_and_insserv -s radiusd START_RADIUSD }
-%if %suse_version > 820
+%if 0%{?suse_version} > 820
 
 %preun
 %stop_on_removal radiusd
 %endif
 
 %postun
-%if %suse_version > 820
+%if 0%{?suse_version} > 820
 %restart_on_update radiusd
 %endif
 %{insserv_cleanup}
@@ -265,7 +333,6 @@ rm -rf $RPM_BUILD_ROOT
 %attr(640,-,radiusd) %config(noreplace) /etc/raddb/sql.conf
 %attr(640,-,radiusd) %config(noreplace) /etc/raddb/users
 %config(noreplace) /etc/raddb/otp.conf
-%attr(640,-,radiusd) /etc/raddb/otppasswd.sample
 %attr(640,-,radiusd) %config(noreplace) /etc/raddb/certs
 %attr(640,-,radiusd) %config(noreplace) /etc/raddb/eap.conf
 %attr(640,-,radiusd) /etc/raddb/example.pl
@@ -277,8 +344,8 @@ rm -rf $RPM_BUILD_ROOT
 /usr/sbin/checkrad
 /usr/sbin/radiusd
 # shared libs
-%attr(755,root,root) %dir /usr/lib/freeradius
-%attr(755,root,root) /usr/lib/freeradius/*.so*
+%attr(755,root,root) %dir %{_libdir}/freeradius
+%attr(755,root,root) %{_libdir}/freeradius/*.so*
 # man-pages
 %doc %{_mandir}/man1/*
 %doc %{_mandir}/man5/*
@@ -294,8 +361,8 @@ rm -rf $RPM_BUILD_ROOT
 %if %_oracle_support == 1
 %files oracle
 %defattr(-,root,root)
-%attr(755,root,root) %dir /usr/lib/freeradius
-%attr(755,root,root) /usr/lib/freeradius/rlm_sql_oracle*.so*
+%attr(755,root,root) %dir %{_libdir}/freeradius
+%attr(755,root,root) %{_libdir}/freeradius/rlm_sql_oracle*.so*
 %endif
 
 %files dialupadmin
@@ -315,5 +382,5 @@ rm -rf $RPM_BUILD_ROOT
 
 %files devel
 %defattr(-,root,root)
-/usr/lib/freeradius/*.a
-#%attr(644,root,root) /usr/lib/freeradius/*.la
+%{_libdir}/freeradius/*.a
+#%attr(644,root,root) %{_libdir}/freeradius/*.la
diff --git a/suse/lib64.patch b/suse/lib64.patch
new file mode 100644 (file)
index 0000000..f5103ab
--- /dev/null
@@ -0,0 +1,44 @@
+--- src/modules/rlm_eap/libeap/Makefile
++++ src/modules/rlm_eap/libeap/Makefile
+@@ -40,7 +40,7 @@
+ $(TARGET).la: $(DYNAMIC_OBJS)
+       $(LIBTOOL) --mode=link $(CC) -release $(RADIUSD_VERSION) \
+-      -module $(LINK_MODE) $(CFLAGS) -o $@ -rpath $(libdir) $^ 
++      -module $(LINK_MODE) $(CFLAGS) -o $@ -rpath $(libdir) -L/lib64 -L/usr/lib64 $^ 
+ static: $(TARGET).a
+--- src/modules/rlm_sql/drivers/rules.mak
++++ src/modules/rlm_sql/drivers/rules.mak
+@@ -93,7 +93,7 @@
+ $(TARGET).la: $(DYNAMIC_OBJS)
+       $(LIBTOOL) --mode=link $(CC) -release $(RADIUSD_VERSION) \
+       -module $(LINK_MODE) $(CFLAGS) \
+-      $(RLM_SQL_CFLAGS) -o $@ -rpath $(libdir) $^ $(RLM_SQL_LIBS)
++      $(RLM_SQL_CFLAGS) -o $@ -rpath $(libdir) $^ -L/lib64 -L/usr/lib64 $(RLM_SQL_LIBS)
+ #######################################################################
+ #
+--- src/modules/rlm_dbm/Makefile.in
++++ src/modules/rlm_dbm/Makefile.in
+@@ -3,7 +3,7 @@
+ HEADERS     =
+ RLM_UTILS   = @dbm_utils@
+ RLM_CFLAGS  = @dbm_cflags@
+-RLM_LIBS    = @dbm_ldflags@
++RLM_LIBS    = -lgdbm -lgdbm_compat
+ RLM_INSTALL = @dbm_install@
+ include ../rules.mak
+--- src/modules/rules.mak.orig 2005-09-20 06:36:41.000000000 +0200
++++ src/modules/rules.mak      2005-09-20 06:36:56.000000000 +0200
+@@ -97,7 +97,7 @@ endif
+ $(TARGET).la: $(DYNAMIC_OBJS)
+       $(LIBTOOL) --mode=link $(CC) -release $(RADIUSD_VERSION) \
+       -module $(LINK_MODE) $(LDFLAGS) $(RLM_LDFLAGS) \
+-      -o $@ -rpath $(libdir) $^ $(RLM_LIBS) $(LIBS)
++      -o $@ -rpath $(libdir) $^ -L/lib64 -L/usr/lib64 $(RLM_LIBS) $(LIBS)
+ #######################################################################
+ #
diff --git a/suse/radiusd-pam-old b/suse/radiusd-pam-old
deleted file mode 100644 (file)
index 7a5349d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#%PAM-1.0
-auth       required    pam_unix2.so nullok
-auth       required    pam_nologin.so
-account    required    pam_unix2.so
-password   required    pam_pwcheck.so nullok use_cracklib
-password   required    pam_unix2.so nullok use_first_pass use_authtok
-session    required    pam_unix2.so none
diff --git a/suse/rcradius-relayd b/suse/rcradius-relayd
deleted file mode 100644 (file)
index 4ebe557..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#! /bin/sh
-# Copyright (c) 2001       SuSE GmbH Nuernberg, Germany.
-#               2002, 2003 SuSE Linux AG, Nuernberg, Germany.
-#
-# Author: Wolfgang Rosenauer, 2000-2003
-#
-# /etc/init.d/radius-relayd
-#
-#   and symbolic its link
-#
-# /usr/bin/rcradius-relayd
-#
-### BEGIN INIT INFO
-# Provides:          radius-relayd
-# Required-Start:    $network $syslog $remotefs
-# Required-Stop:
-# Default-Start:     3 5
-# Default-Stop:      0 1 2 6
-# Short-Description: RADIUS Relay Server
-# Description:       Remote Authentication Dialin User Server Relay Service
-### END INIT INFO
-
-RADIUSD_BIN=/usr/sbin/radrelay
-test -x $RADIUSD_BIN || { echo "$RADIUSD_BIN not installed"; \
-       if [ "$1" = "stop" ]; then exit 0;
-       else exit 5; fi; }
-
-. /etc/rc.status
-
-rc_reset
-case "$1" in
-    start)
-       echo -n "Starting RADIUS Relay daemon "
-       startproc $RADIUSD_BIN -s -n radrelay >/dev/null
-       rc_status -v    
-       ;;
-    stop)
-       echo -n "Shutting down RADIUS Relay daemon "
-       killproc -TERM $RADIUSD_BIN 
-       rc_status -v    
-       ;;
-    try-restart|condrestart)
-       ## If first returns OK call the second, if first or
-       ## second command fails, set echo return value.
-       if test "$1" = "condrestart"; then
-               echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
-       fi
-       $0 status
-       if test $? = 0; then
-               $0 restart
-       else
-               rc_reset        # Not running is not a failure.
-       fi
-       rc_status
-       ;;
-    restart)
-        ## Stop the service and regardless of whether it was
-        ## running or not, start it again.
-       $0 stop
-       $0 start
-       rc_status
-       ;;
-    force-reload)
-        ## Signal the daemon to reload its config. Most daemons
-        ## do this on signal 1 (SIGHUP).
-        ## If it does not support it, restart.
-
-       echo -n "Reload RADIUS Relay daemon "
-        killproc -HUP $RADIUSD_BIN
-        rc_status -v
-       ;;
-    reload)
-        ## Like force-reload, but if daemon does not support
-        ## signalling, do nothing (!)
-
-       echo -n "Reload RADIUS Relay daemon "
-       killproc -HUP $RADIUSD_BIN 
-       rc_status -v
-       ;;
-    status)
-       echo -n "Checking for service radius-relayd "
-       checkproc $RADIUSD_BIN
-       rc_status -v
-       ;;
-    *)
-       echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
-       exit 1
-       ;;
-esac
-rc_exit
index 83e2af0..a22a19d 100644 (file)
@@ -13,7 +13,9 @@
 ### BEGIN INIT INFO
 # Provides:          radiusd
 # Required-Start:    $network $syslog $remotefs
+# Should-Start:      $time postgresql mysql ldap samba krb5kdc
 # Required-Stop:
+# Should-Stop:      $time postgresql mysql ldap
 # Default-Start:     3 5
 # Default-Stop:      0 1 2 6
 # Short-Description: RADIUS-Server
index ae31ac4..4a97631 100644 (file)
--- a/todo/TODO
+++ b/todo/TODO
@@ -4,6 +4,9 @@ o scan ALL modules, so that they use consistent names for structures
   call rlm_foo_detach() if anything goes wrong, instead of just free()'ing
   'inst'.  The cf_parse_section().. code may have malloc'd memory, and
   that needs to be free'd, too.
+o Add a 'listen' directive, ala Apache, so that we can listen
+  on multiple ports. Hmm... if we do that, we should allow multiple
+  virtual servers, too.
 o Stop unloading modules on HUP so that we can have persistant
   handles/socketc/etc from module_init().  Alan D. and Alan C. had a good
   plan for when to load/reload modules on the list recently...I say
@@ -26,6 +29,9 @@ o Manual pages for the daemon, utilities and conffiles (some done)
 o Fix all FIXME's in the source.
 o better SNMP statistics support, for the auth/acct servers, and for
   each client.
+o fix the proxy receive code, so that we don't have to look through ALL
+  of the requests to find the matching proxy.  This might be hard to do..
+  It would also involve thread locking issues.
 
 WAIT UNTIL NEXT RELEASE:
 o UPDATE accounting requests aren't handled as in 1.5.4.3 for wtmp
@@ -33,6 +39,9 @@ o UPDATE accounting requests aren't handled as in 1.5.4.3 for wtmp
 o New module: rlm_fastradwtmp. with a radutmp-style active session
   database to guarantee wtmp records are always written in matching
   pairs. Because radlast is slow.
+o New module: rlm_attrmap. assigns a single attribute based on a
+  username, with ed-friendly/awk-friendly config file. Because the
+  users file is too complicated.
 o replace the module_t method table with a set of register_* functions
   (so different instances of the same module can offer different
   methods)
@@ -43,6 +52,7 @@ o switch all timers from time() to gettimeofday() so processing is
 o SNMP support for querying users who are on-line.
 o New module: rlm_nsupdate (dyndns). Because dynamic addresses are
   cruel.
+o New module: rlm_perl.
 
 WILL NOT DO:
 o module initialization AFTER forking, not before.
@@ -56,10 +66,6 @@ o there should be a way that radius itself could
        --- This work is for an external process to do ---
 
 DONE:
-o IPv6
-o proxy receive rbtree stuff
-o rlm_perl
-o "listen" directive
 o fix radwho to read modules{radutmp{filename = }}
 o Add 'initialize' list in modules, so explicitely give initialization order.
 o merge OSF/OSFIA patches from Cistron.