...
 
Commits (2)
......@@ -8,6 +8,7 @@ OpenLDAP 2.4.54 Engineering
Fixed slapd syncrepl to call check_syncprov on fresh consumer (ITS#9345)
Fixed slapd syncrepl to propagate errors from overlay_entry_get_ov (ITS#9355)
Fixed slapd-monitor fix monitor_back_register_database for empty suffix DB (ITS#9353)
Fixed slapo-accesslog normalizer for reqStart (ITS#9358)
Fixed slapo-syncprov contextCSN generation with empty suffix (ITS#9015)
OpenLDAP 2.4.53 (2020/09/07)
......
......@@ -2296,9 +2296,167 @@ accesslog_db_open(
return 0;
}
enum { start = 0 };
static int
check_rdntime_syntax (struct berval *val,
int *parts,
struct berval *fraction)
{
/*
* GeneralizedTime YYYYmmddHH[MM[SS]][(./,)d...](Z|(+/-)HH[MM])
* GeneralizedTime supports leap seconds, UTCTime does not.
*/
static const int ceiling[9] = { 100, 100, 12, 31, 24, 60, 60, 24, 60 };
static const int mdays[2][12] = {
/* non-leap years */
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
/* leap years */
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
char *p, *e;
int part, c, c1, c2, tzoffset, leapyear = 0;
p = val->bv_val;
e = p + val->bv_len;
for (part = start; part < 7 && p < e; part++) {
c1 = *p;
if (!ASCII_DIGIT(c1)) {
break;
}
p++;
if (p == e) {
return LDAP_INVALID_SYNTAX;
}
c = *p++;
if (!ASCII_DIGIT(c)) {
return LDAP_INVALID_SYNTAX;
}
c += c1 * 10 - '0' * 11;
if ((part | 1) == 3) {
--c;
if (c < 0) {
return LDAP_INVALID_SYNTAX;
}
}
if (c >= ceiling[part]) {
if (! (c == 60 && part == 6 && start == 0))
return LDAP_INVALID_SYNTAX;
}
parts[part] = c;
}
if (part < 5 + start) {
return LDAP_INVALID_SYNTAX;
}
for (; part < 9; part++) {
parts[part] = 0;
}
/* leapyear check for the Gregorian calendar (year>1581) */
if (parts[parts[1] == 0 ? 0 : 1] % 4 == 0) {
leapyear = 1;
}
if (parts[3] >= mdays[leapyear][parts[2]]) {
return LDAP_INVALID_SYNTAX;
}
if (start == 0) {
fraction->bv_val = p;
fraction->bv_len = 0;
if (p < e && (*p == '.' || *p == ',')) {
char *end_num;
while (++p < e && ASCII_DIGIT(*p)) {
/* EMPTY */;
}
if (p - fraction->bv_val == 1) {
return LDAP_INVALID_SYNTAX;
}
#if 0 /* don't truncate trailing zeros */
for (end_num = p; end_num[-1] == '0'; --end_num) {
/* EMPTY */;
}
c = end_num - fraction->bv_val;
#else
c = p - fraction->bv_val;
#endif
if (c != 1) fraction->bv_len = c;
}
}
if (p == e) {
/* no time zone */
return start == 0 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
}
tzoffset = *p++;
switch (tzoffset) {
case 'Z':
/* UTC */
break;
default:
return LDAP_INVALID_SYNTAX;
}
return p != e ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
}
static int
rdnTimestampValidate(
Syntax *syntax,
struct berval *in )
{
int parts[9];
struct berval fraction;
return check_rdntime_syntax(in, parts, &fraction);
}
static int
rdnTimestampNormalize(
slap_mask_t usage,
Syntax *syntax,
MatchingRule *mr,
struct berval *val,
struct berval *normalized,
void *ctx )
{
int parts[9], rc;
unsigned int len;
struct berval fraction;
rc = check_rdntime_syntax(val, parts, &fraction);
if (rc != LDAP_SUCCESS) {
return rc;
}
len = STRLENOF("YYYYmmddHHMMSSZ") + fraction.bv_len;
normalized->bv_val = slap_sl_malloc( len + 1, ctx );
if ( BER_BVISNULL( normalized ) ) {
return LBER_ERROR_MEMORY;
}
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02d",
parts[0], parts[1], parts[2] + 1, parts[3] + 1,
parts[4], parts[5], parts[6] );
if ( !BER_BVISEMPTY( &fraction ) ) {
memcpy( normalized->bv_val + STRLENOF("YYYYmmddHHMMSSZ")-1,
fraction.bv_val, fraction.bv_len );
normalized->bv_val[STRLENOF("YYYYmmddHHMMSSZ")-1] = '.';
}
strcpy( normalized->bv_val + len-1, "Z" );
normalized->bv_len = len;
return LDAP_SUCCESS;
}
int accesslog_initialize()
{
int i, rc;
Syntax *rdnTimestampSyntax;
MatchingRule *rdnTimestampMatch;
accesslog.on_bi.bi_type = "accesslog";
accesslog.on_bi.bi_db_init = accesslog_db_init;
......@@ -2365,6 +2523,25 @@ int accesslog_initialize()
#endif
}
/* Inject custom normalizer for reqStart/reqEnd */
rdnTimestampMatch = ch_malloc( sizeof( MatchingRule ));
rdnTimestampSyntax = ch_malloc( sizeof( Syntax ));
*rdnTimestampMatch = *ad_reqStart->ad_type->sat_equality;
rdnTimestampMatch->smr_normalize = rdnTimestampNormalize;
*rdnTimestampSyntax = *ad_reqStart->ad_type->sat_syntax;
rdnTimestampSyntax->ssyn_validate = rdnTimestampValidate;
ad_reqStart->ad_type->sat_equality = rdnTimestampMatch;
ad_reqStart->ad_type->sat_syntax = rdnTimestampSyntax;
rdnTimestampMatch = ch_malloc( sizeof( MatchingRule ));
rdnTimestampSyntax = ch_malloc( sizeof( Syntax ));
*rdnTimestampMatch = *ad_reqStart->ad_type->sat_equality;
rdnTimestampMatch->smr_normalize = rdnTimestampNormalize;
*rdnTimestampSyntax = *ad_reqStart->ad_type->sat_syntax;
rdnTimestampSyntax->ssyn_validate = rdnTimestampValidate;
ad_reqEnd->ad_type->sat_equality = rdnTimestampMatch;
ad_reqEnd->ad_type->sat_syntax = rdnTimestampSyntax;
for ( i=0; locs[i].ot; i++ ) {
int code;
......