diff --git a/.gitignore b/.gitignore index 5b28946..db8ed86 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /freeradius-server-3.0.0.tar.bz2 /freeradius-server-3.0.1.tar.bz2 /freeradius-server-3.0.2.tar.bz2 +/freeradius-server-3.0.3.tar.bz2 diff --git a/freeradius-case-insensitive-matching.patch b/freeradius-case-insensitive-matching.patch new file mode 100644 index 0000000..290218b --- /dev/null +++ b/freeradius-case-insensitive-matching.patch @@ -0,0 +1,396 @@ +commit dd648b44760b9041d5ea4279e78ee7fb4e5aa13d +Author: Arran Cudbard-Bell +Date: Tue May 13 11:52:21 2014 +0100 + + Fix case insensitive matching in compiled regular expressions + +diff --git a/src/include/map.h b/src/include/map.h +index ed73093..59732a1 100644 +--- a/src/include/map.h ++++ b/src/include/map.h +@@ -155,11 +155,14 @@ typedef struct value_pair_tmpl_t { + + union { + struct { +- value_data_t const *value; //!< actual data +- size_t length; //!< of the vpd data ++ value_data_t const *value; //!< actual data ++ size_t length; //!< of the vpd data + } literal; + xlat_exp_t *xlat; //!< pre-parsed xlat_exp_t +- regex_t *preg; //!< pre-parsed regex_t ++ struct { ++ regex_t *comp; //!< pre-parsed regex_t ++ bool iflag; //!< Case insensitive ++ } preg; + } data; + } value_pair_tmpl_t; + +@@ -170,7 +173,9 @@ typedef struct value_pair_tmpl_t { + #define vpt_tag attribute.tag + + #define vpt_xlat data.xlat +-#define vpt_preg data.preg ++ ++#define vpt_preg data.preg.comp ++#define vpt_iflag data.preg.iflag + + #define vpt_value data.literal.value + #define vpt_length data.literal.length +diff --git a/src/include/parser.h b/src/include/parser.h +index 5126edd..6aa858a 100644 +--- a/src/include/parser.h ++++ b/src/include/parser.h +@@ -73,7 +73,6 @@ struct fr_cond_t { + fr_cond_t *child; + } data; + +- int regex_i; + int negate; + int pass2_fixup; + +diff --git a/src/main/evaluate.c b/src/main/evaluate.c +index 60351c9..c21ed4f 100644 +--- a/src/main/evaluate.c ++++ b/src/main/evaluate.c +@@ -240,16 +240,13 @@ int radius_evaluate_tmpl(REQUEST *request, int modreturn, UNUSED int depth, + } + + +-static int do_regex(REQUEST *request, value_pair_map_t const *map, bool iflag) ++static int do_regex(REQUEST *request, value_pair_map_t const *map) + { + int compare, rcode, ret; +- int cflags = REG_EXTENDED; + regex_t reg, *preg; + char *lhs, *rhs; + regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; + +- if (iflag) cflags |= REG_ICASE; +- + /* + * Expand and then compile it. + */ +@@ -262,7 +259,7 @@ static int do_regex(REQUEST *request, value_pair_map_t const *map, bool iflag) + } + rad_assert(rhs != NULL); + +- compare = regcomp(®, rhs, cflags); ++ compare = regcomp(®, rhs, REG_EXTENDED | (map->src->vpt_iflag ? REG_ICASE : 0)); + if (compare != 0) { + if (debug_flag) { + char errbuf[128]; +@@ -635,7 +632,7 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth + */ + if ((map->src->type == VPT_TYPE_REGEX) || + (map->src->type == VPT_TYPE_REGEX_STRUCT)) { +- return do_regex(request, map, c->regex_i); ++ return do_regex(request, map); + } + #endif + +diff --git a/src/main/modcall.c b/src/main/modcall.c +index 22ab00b..915c370 100644 +--- a/src/main/modcall.c ++++ b/src/main/modcall.c +@@ -2829,7 +2829,7 @@ static bool pass2_regex_compile(CONF_ITEM const *ci, value_pair_tmpl_t *vpt) + talloc_set_destructor(preg, _free_compiled_regex); + if (!preg) return false; + +- rcode = regcomp(preg, vpt->name, REG_EXTENDED); ++ rcode = regcomp(preg, vpt->name, REG_EXTENDED | (vpt->vpt_iflag ? REG_ICASE : 0)); + if (rcode != 0) { + char buffer[256]; + regerror(rcode, preg, buffer, sizeof(buffer)); +diff --git a/src/main/parser.c b/src/main/parser.c +index fcfd16e..738ca7f 100644 +--- a/src/main/parser.c ++++ b/src/main/parser.c +@@ -340,7 +340,8 @@ static ssize_t condition_tokenize_cast(char const *start, DICT_ATTR const **pda, + * @param[out] error the parse error (if any) + * @return length of the string skipped, or when negative, the offset to the offending error + */ +-static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *start, int brace, fr_cond_t **pcond, char const **error, int flags) ++static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *start, int brace, ++ fr_cond_t **pcond, char const **error, int flags) + { + ssize_t slen; + char const *p = start; +@@ -477,7 +478,8 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *st + rad_assert(c->data.vpt->type != VPT_TYPE_REGEX); + + } else { /* it's an operator */ +- int regex; ++ bool regex; ++ bool i_flag = false; + + /* + * The next thing should now be a comparison operator. +@@ -613,7 +615,7 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *st + * Allow /foo/i + */ + if (p[slen] == 'i') { +- c->regex_i = true; ++ i_flag = true; + slen++; + } + +@@ -637,6 +639,10 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *st + return_0("Syntax error"); + } + ++ if (c->data.map->src->type == VPT_TYPE_REGEX) { ++ c->data.map->src->vpt_iflag = i_flag; ++ } ++ + /* + * Could have been a reference to an attribute which is registered later. + * Mark it as being checked in pass2. +@@ -1074,7 +1080,6 @@ done: + rcode = radius_evaluate_map(NULL, 0, 0, c); + TALLOC_FREE(c->data.map); + c->cast = NULL; +- c->regex_i = false; + if (rcode) { + c->type = COND_TYPE_TRUE; + } else { +@@ -1097,7 +1102,6 @@ done: + int rcode; + + rad_assert(c->cast == NULL); +- rad_assert(c->regex_i == false); + + rcode = radius_evaluate_map(NULL, 0, 0, c); + if (rcode) { +diff --git a/src/tests/keywords/if-regex-match b/src/tests/keywords/if-regex-match +index f15e74f..f3e6aa9 100644 +--- a/src/tests/keywords/if-regex-match ++++ b/src/tests/keywords/if-regex-match +@@ -1,16 +1,96 @@ + # PRE: if + # +-# May as well exercise the regular expression engine +-if (User-Name !~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])/) { +- reject ++ ++# Non matching on attribute ref ++if (User-Name !~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])%{Tmp-String-0}/) { ++ update reply { ++ Filter-Id += 'Fail 0' ++ } + } + +-if ("%{User-Name}" !~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])/) { +- reject ++# Matching on xlat expanded value ++if ("%{User-Name}" !~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])%{Tmp-String-0}/) { ++ update reply { ++ Filter-Id += 'Fail 1' ++ } + } + +-if (User-Name =~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])/) { ++# Matching on attribute ref with capture groups ++if (User-Name =~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])%{Tmp-String-0}/) { ++ # Test all the capture groups + update { + reply:User-Name := "%{7}_%{6}_%{5}_%{4}_%{3}_%{2}_%{1}_%{0}" + } + } ++else { ++ update reply { ++ Filter-Id += 'Fail 2' ++ } ++} ++ ++# Checking capture groups are cleared out correctly ++if (User-Name =~ /^([0-9])_%{Tmp-String-0}/) { ++ if ("%{0}%{1}%{2}%{3}%{4}%{5}%{6}%{7}" != '1_1') { ++ update reply { ++ Filter-Id += 'Fail 3' ++ } ++ } ++} ++else { ++ update reply { ++ Filter-Id += 'Fail 3.5' ++ } ++} ++ ++# Checking capture groups are cleared out correctly when there are no matches ++if (User-Name =~ /^.%{Tmp-String-0}/) { ++ if ("%{0}%{1}%{2}%{3}%{4}%{5}%{6}%{7}" != '1') { ++ update reply { ++ Filter-Id += 'Fail 4' ++ } ++ } ++} ++else { ++ update reply { ++ Filter-Id += 'Fail 4.5' ++ } ++} ++ ++# compiled - ref - insensitive ++if (Calling-Station-Id !~ /:roamyroam%{Tmp-String-0}$/i) { ++ update reply { ++ Filter-Id += 'Fail 5' ++ } ++} ++ ++# compiled - expansion - insensitive ++if ("%{Calling-Station-Id}" !~ /:roamyroam%{Tmp-String-0}$/i) { ++ update reply { ++ Filter-Id += 'Fail 6' ++ } ++} ++ ++# compiled - enum - ref - insensitive ++if (Service-Type !~ /^framed-user%{Tmp-String-0}$/i) { ++ update reply { ++ Filter-Id += 'Fail 7' ++ } ++} ++ ++# compiled - enum - expansion - insensitive ++if ("%{Service-Type}" !~ /^framed-user%{Tmp-String-0}$/i) { ++ update reply { ++ Filter-Id += 'Fail 8' ++ } ++} ++ ++# compiled - enum - ref ++if (Service-Type =~ /^framed-user%{Tmp-String-0}$/) { ++ update reply { ++ Filter-Id += 'Fail 9' ++ } ++} ++ ++ ++ ++ +diff --git a/src/tests/keywords/if-regex-match-comp b/src/tests/keywords/if-regex-match-comp +new file mode 100644 +index 0000000..8d68142 +--- /dev/null ++++ b/src/tests/keywords/if-regex-match-comp +@@ -0,0 +1,94 @@ ++# PRE: if ++# ++ ++# Non matching on attribute ref ++if (User-Name !~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])/) { ++ update reply { ++ Filter-Id += 'Fail 0' ++ } ++} ++ ++# Matching on xlat expanded value ++if ("%{User-Name}" !~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])/) { ++ update reply { ++ Filter-Id += 'Fail 1' ++ } ++} ++ ++# Matching on attribute ref with capture groups ++if (User-Name =~ /^([0-9])_([0-9])?_([0-9]*)_([0-9]+)_([^_])_(6)_([7-8])/) { ++ # Test all the capture groups ++ update { ++ reply:User-Name := "%{7}_%{6}_%{5}_%{4}_%{3}_%{2}_%{1}_%{0}" ++ } ++} ++else { ++ update reply { ++ Filter-Id += 'Fail 2' ++ } ++} ++ ++# Checking capture groups are cleared out correctly ++if (User-Name =~ /^([0-9])_/) { ++ if ("%{0}%{1}%{2}%{3}%{4}%{5}%{6}%{7}" != '1_1') { ++ update reply { ++ Filter-Id += 'Fail 3' ++ } ++ } ++} ++else { ++ update reply { ++ Filter-Id += 'Fail 3.5' ++ } ++} ++ ++# Checking capture groups are cleared out correctly when there are no matches ++if (User-Name =~ /^./) { ++ if ("%{0}%{1}%{2}%{3}%{4}%{5}%{6}%{7}" != '1') { ++ update reply { ++ Filter-Id += 'Fail 4' ++ } ++ } ++} ++else { ++ update reply { ++ Filter-Id += 'Fail 4.5' ++ } ++} ++ ++# compiled - ref - insensitive ++if (Calling-Station-Id !~ /:roamyroam$/i) { ++ update reply { ++ Filter-Id += 'Fail 5' ++ } ++} ++ ++# compiled - expansion - insensitive ++if ("%{Calling-Station-Id}" !~ /:roamyroam$/i) { ++ update reply { ++ Filter-Id += 'Fail 6' ++ } ++} ++ ++# compiled - enum - ref - insensitive ++if (Service-Type !~ /^framed-user$/i) { ++ update reply { ++ Filter-Id += 'Fail 7' ++ } ++} ++ ++# compiled - enum - expansion - insensitive ++if ("%{Service-Type}" !~ /^framed-user$/i) { ++ update reply { ++ Filter-Id += 'Fail 8' ++ } ++} ++ ++# compiled - enum - ref ++if (Service-Type =~ /^framed-user$/) { ++ update reply { ++ Filter-Id += 'Fail 9' ++ } ++} ++ ++ +diff --git a/src/tests/keywords/if-regex-match-comp.attrs b/src/tests/keywords/if-regex-match-comp.attrs +new file mode 100644 +index 0000000..ba7188d +--- /dev/null ++++ b/src/tests/keywords/if-regex-match-comp.attrs +@@ -0,0 +1,7 @@ ++User-Name = '1_2_3_4_5_6_7' ++User-Password = 'hello' ++Service-Type := 'Framed-User' ++Calling-Station-ID := '00:11:22:33:44:55:66:ROAMYROAM' ++ ++Response-Packet-Type == Access-Accept ++User-Name == '7_6_5_4_3_2_1_1_2_3_4_5_6_7' +diff --git a/src/tests/keywords/if-regex-match.attrs b/src/tests/keywords/if-regex-match.attrs +index ab03050..ba7188d 100644 +--- a/src/tests/keywords/if-regex-match.attrs ++++ b/src/tests/keywords/if-regex-match.attrs +@@ -1,5 +1,7 @@ + User-Name = '1_2_3_4_5_6_7' + User-Password = 'hello' ++Service-Type := 'Framed-User' ++Calling-Station-ID := '00:11:22:33:44:55:66:ROAMYROAM' + + Response-Packet-Type == Access-Accept + User-Name == '7_6_5_4_3_2_1_1_2_3_4_5_6_7' diff --git a/freeradius-foreach.patch b/freeradius-foreach.patch new file mode 100644 index 0000000..f930397 --- /dev/null +++ b/freeradius-foreach.patch @@ -0,0 +1,107 @@ +commit c0f670c233e9562118648af641d4f8d182350f31 +Author: Arran Cudbard-Bell +Date: Fri May 16 11:38:22 2014 +0100 + + Make the foreach code slightly more sane. Reliably reproduces the issue described by #639 + +diff --git a/src/main/modcall.c b/src/main/modcall.c +index 3dd0828..7a44bf2 100644 +--- a/src/main/modcall.c ++++ b/src/main/modcall.c +@@ -608,9 +608,9 @@ redo: + */ + if (c->type == MOD_FOREACH) { + int i, foreach_depth = -1; +- VALUE_PAIR *vps, **tail, *vp; ++ VALUE_PAIR *vps, *vp; + modcall_stack_entry_t *next = NULL; +- vp_cursor_t cursor; ++ vp_cursor_t cursor, copy; + modgroup *g = mod_callabletogroup(c); + + if (depth >= MODCALL_STACK_MAX) { +@@ -645,31 +645,35 @@ redo: + } + + /* +- * Copy the VPs from the original request. ++ * Copy the VPs from the original request, this ensures deterministic ++ * behaviour if someone decides to add or remove VPs in the set were ++ * iterating over. + */ +- fr_cursor_init(&cursor, &vp); +- /* Prime the cursor. */ +- cursor.found = cursor.current; +- + vps = NULL; +- tail = &vps; + +- while (vp) { +- *tail = paircopyvp(request, vp); +- if (!*tail) break; ++ fr_cursor_init(&cursor, &vp); + +- tail = &((*tail)->next); /* really should be using cursors... */ ++ /* Prime the cursor. */ ++ cursor.found = cursor.current; ++ for (fr_cursor_init(©, &vps); ++ vp; ++ vp = fr_cursor_next_by_da(&cursor, vp->da, g->vpt->attribute.tag)) { ++ VALUE_PAIR *tmp; + +- vp = fr_cursor_next_by_da(&cursor, vp->da, g->vpt->attribute.tag); ++ MEM(tmp = paircopyvp(request, vp)); ++ fr_cursor_insert(©, tmp); + } + +- RDEBUG2("%.*sforeach %s ", depth + 1, modcall_spaces, +- c->name); ++ RDEBUG2("%.*sforeach %s ", depth + 1, modcall_spaces, c->name); ++ + rad_assert(vps != NULL); + +- for (vp = fr_cursor_init(&cursor, &vps); ++ /* ++ * This is the actual body of the foreach loop ++ */ ++ for (vp = fr_cursor_first(©); + vp != NULL; +- vp = fr_cursor_next(&cursor)) { ++ vp = fr_cursor_next(©)) { + #ifndef NDEBUG + if (fr_debug_flag >= 2) { + char buffer[1024]; +@@ -709,7 +713,7 @@ redo: + } + } /* loop over VPs */ + +- talloc_free(vps); ++ pairfree(&vps); + + rad_assert(next != NULL); + result = next->result; + +commit 860f645668b9604c897c4ee1338ecfeb88cdd75a +Author: Arran Cudbard-Bell +Date: Fri May 16 12:32:12 2014 +0100 + + Don't free foreach VPs on break #639 + + Wwe go back up the stack in an orderly way and don't need this hack anymore + +diff --git a/src/main/modcall.c b/src/main/modcall.c +index 7a44bf2..5785643 100644 +--- a/src/main/modcall.c ++++ b/src/main/modcall.c +@@ -732,9 +732,7 @@ redo: + for (i = 8; i >= 0; i--) { + copy_p = request_data_get(request, radius_get_vp, i); + if (copy_p) { +- RDEBUG2("%.*s # break Foreach-Variable-%d", depth + 1, +- modcall_spaces, i); +- pairfree(copy_p); ++ RDEBUG2("%.*s # break Foreach-Variable-%d", depth + 1, modcall_spaces, i); + break; + } + } + diff --git a/freeradius-perl-string-escaping.patch b/freeradius-perl-string-escaping.patch new file mode 100644 index 0000000..1d320e1 --- /dev/null +++ b/freeradius-perl-string-escaping.patch @@ -0,0 +1,28 @@ +commit ff8b26e0cdad5d2579dcf64edbe2fab2b10aecd4 +Author: Alan T. DeKok +Date: Wed May 14 13:32:42 2014 -0400 + + Fix typo. Closes #635 + +diff --git a/src/modules/rlm_perl/rlm_perl.c b/src/modules/rlm_perl/rlm_perl.c +index 65cd971..a45daec 100644 +--- a/src/modules/rlm_perl/rlm_perl.c ++++ b/src/modules/rlm_perl/rlm_perl.c +@@ -617,7 +617,7 @@ static void perl_store_vps(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR *vps, H + for (vp = fr_cursor_first(&cursor); + vp; + vp = fr_cursor_next(&cursor)) { +- if (vp->da->type != PW_TYPE_INVALID) { ++ if (vp->da->type != PW_TYPE_STRING) { + len = vp_prints_value(buffer, sizeof(buffer), vp, 0); + av_push(av, newSVpv(buffer, truncate_len(len, sizeof(buffer)))); + RDEBUG("<-- %s = %s", vp->da->name, buffer); +@@ -634,7 +634,7 @@ static void perl_store_vps(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR *vps, H + */ + } else if (sublist) { + +- if (sublist->da->type != PW_TYPE_INVALID) { ++ if (sublist->da->type != PW_TYPE_STRING) { + len = vp_prints_value(buffer, sizeof(buffer), sublist, 0); + (void)hv_store(rad_hv, name, strlen(name), newSVpv(buffer, truncate_len(len, sizeof(buffer))), 0); + RDEBUG("<-- %s = %s", sublist->da->name, buffer); diff --git a/freeradius-segfault-on-config-parse.patch b/freeradius-segfault-on-config-parse.patch new file mode 100644 index 0000000..73fed57 --- /dev/null +++ b/freeradius-segfault-on-config-parse.patch @@ -0,0 +1,19 @@ +commit f9e2d539599345b03dde495a36d4ec8bd90d78a5 +Author: Alan T. DeKok +Date: Thu May 15 10:31:23 2014 -0400 + + Use the correct data type. Closes #634 + +diff --git a/src/main/mainconfig.c b/src/main/mainconfig.c +index 86757df..4564778 100644 +--- a/src/main/mainconfig.c ++++ b/src/main/mainconfig.c +@@ -83,7 +83,7 @@ static char const *radlog_dest = NULL; + */ + static char const *localstatedir = NULL; + static char const *prefix = NULL; +-static char my_name; ++static char const *my_name = NULL; + static char const *sbindir = NULL; + static char const *run_dir = NULL; + static char *syslog_facility = NULL; diff --git a/freeradius.spec b/freeradius.spec index 6ad9cf3..d97b95b 100644 --- a/freeradius.spec +++ b/freeradius.spec @@ -1,6 +1,6 @@ Summary: High-performance and highly configurable free RADIUS server Name: freeradius -Version: 3.0.2 +Version: 3.0.3 Release: 1%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Daemons @@ -23,6 +23,10 @@ Source104: freeradius-tmpfiles.conf Patch1: freeradius-redhat-config.patch Patch2: freeradius-postgres-sql.patch +Patch3: freeradius-case-insensitive-matching.patch +Patch4: freeradius-perl-string-escaping.patch +Patch5: freeradius-segfault-on-config-parse.patch +Patch6: freeradius-foreach.patch %global docdir %{?_pkgdocdir}%{!?_pkgdocdir:%{_docdir}/%{name}-%{version}} @@ -181,6 +185,10 @@ This plugin provides the unixODBC support for the FreeRADIUS server project. # mistakenly includes the backup files, especially problematic for raddb config files. %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 %build # Force compile/link options, extra security for network facing daemon @@ -202,7 +210,8 @@ This plugin provides the unixODBC support for the FreeRADIUS server project. --without-rlm_sql_iodbc \ --without-rlm_sql_firebird \ --without-rlm_sql_db2 \ - --without-rlm_sql_oracle + --without-rlm_sql_oracle \ + --without-rlm_unbound make @@ -236,6 +245,7 @@ rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/raddb/certs/serial* rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/raddb/certs/dh rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/raddb/certs/random + rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/radeapclient.1 rm -f $RPM_BUILD_ROOT/usr/sbin/rc.radiusd @@ -248,6 +258,8 @@ rm -rf $RPM_BUILD_ROOT/etc/raddb/mods-config/sql/ippool/oracle rm -rf $RPM_BUILD_ROOT/etc/raddb/mods-config/sql/ippool-dhcp/oracle rm -rf $RPM_BUILD_ROOT/etc/raddb/mods-config/sql/main/oracle +rm $RPM_BUILD_ROOT/%{_sysconfdir}/raddb/mods-available/unbound +rm $RPM_BUILD_ROOT/%{_sysconfdir}/raddb/mods-config/unbound/default.conf # remove unsupported config files rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/raddb/experimental.conf @@ -628,7 +640,6 @@ exit 0 %doc %{_mandir}/man1/radzap.1.gz %doc %{_mandir}/man1/smbencrypt.1.gz %doc %{_mandir}/man5/checkrad.5.gz -%doc %{_mandir}/man8/radconf2xml.8.gz %doc %{_mandir}/man8/radcrypt.8.gz %doc %{_mandir}/man8/radsniff.8.gz %doc %{_mandir}/man8/radsqlrelay.8.gz @@ -749,6 +760,20 @@ exit 0 %{_libdir}/freeradius/rlm_sql_unixodbc.so %changelog +* Wed May 14 2014 Nikolai Kondrashov - 3.0.3-1 +- Upgrade to upstream 3.0.3 release. + See upstream ChangeLog for details (in freeradius-doc subpackage). +- Minor configuration parsing change: "Double-escaping of characters in Perl, + and octal characters has been fixed. If your configuration has text like + "\\000", you will need to remove one backslash." +- Additionally includes post-release fixes for: + * case-insensitive matching in compiled regular expressions not working, + * upstream issue #634 "3.0.3 SIGSEGV on config parse", + * upstream issue #635 "3.0.x - rlm_perl - strings are still + escaped when passed to perl from FreeRADIUS", + * upstream issue #639 "foreach may cause ABORT". +- Fixes bugs 1097266 1070447 + * Wed May 7 2014 Nikolai Kondrashov - 3.0.2-1 - Upgrade to upstream 3.0.2 release, configuration compatible with 3.0.1. See upstream ChangeLog for details (in freeradius-doc subpackage) diff --git a/sources b/sources index ebe2c62..227a6ce 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -c6b25a532e65ce6bfef4f422b7240d4d freeradius-server-3.0.2.tar.bz2 +6093be8d2a962035d6b1111789b3447c freeradius-server-3.0.3.tar.bz2