Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Nadezhda Ivanova
OpenLDAP
Commits
b7fb7518
Commit
b7fb7518
authored
Aug 19, 1998
by
Kurt Zeilenga
Browse files
Merged in ACL changes.
parent
4b0c2f65
Changes
8
Hide whitespace changes
Inline
Side-by-side
libraries/libldap/regex.c
View file @
b7fb7518
#include
"portable.h"
#if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
#include
"regex.h"
#include
"
compat_
regex.h"
/*
* regex - Regular expression pattern matching and replacement
...
...
@@ -20,9 +20,8 @@
* see Henry Spencer's regexp routines, or GNU Emacs pattern
* matching module.
*
* Modification history:
*
Vendor
Modification history:
*
* $Log: regex.c,v $
* Revision 1.12 1996/04/25 16:20:59 mcs
* make re_exec() match "" with ".*" and similar patterns
* hopefully this change doesn't break anything else!
...
...
servers/slapd/acl.c
View file @
b7fb7518
...
...
@@ -11,6 +11,7 @@
#else
#include
"regex.h"
#endif
#include
"slap.h"
extern
Attribute
*
attr_find
();
...
...
@@ -25,8 +26,12 @@ int access_allowed();
struct
acl
*
acl_get_applicable
();
static
int
regex_matches
();
#ifdef USEREGEX
static
string_expand
(
char
*
newbuf
,
int
bufsiz
,
char
*
pattern
,
char
*
match
,
regmatch_t
*
matches
);
#endif
extern
pthread_mutex_t
regex_mutex
;
extern
Entry
*
be_dn2entry
(
Backend
*
be
,
char
*
bdn
,
char
**
matched
);
/*
* access_allowed - check whether dn is allowed the requested access
...
...
@@ -39,6 +44,7 @@ extern pthread_mutex_t regex_mutex;
* 1 access allowed
*/
int
access_allowed
(
Backend
*
be
,
...
...
@@ -53,13 +59,47 @@ access_allowed(
{
int
rc
;
struct
acl
*
a
;
char
*
edn
;
#ifdef USEREGEX
regmatch_t
matches
[
MAXREMATCHES
];
int
i
;
int
n
;
#endif
if
(
be
==
NULL
)
{
return
(
0
);
}
a
=
acl_get_applicable
(
be
,
op
,
e
,
attr
);
rc
=
acl_access_allowed
(
a
,
be
,
conn
,
e
,
val
,
op
,
access
);
edn
=
dn_normalize_case
(
strdup
(
e
->
e_dn
)
);
Debug
(
LDAP_DEBUG_ACL
,
"
\n
=> access_allowed: entry (%s) attr (%s)
\n
"
,
e
->
e_dn
,
attr
,
0
);
/* the lastmod attributes are ignored by ACL checking */
if
(
strcasecmp
(
attr
,
"modifiersname"
)
==
0
||
strcasecmp
(
attr
,
"modifytimestamp"
)
==
0
||
strcasecmp
(
attr
,
"creatorsname"
)
==
0
||
strcasecmp
(
attr
,
"createtimestamp"
)
==
0
)
{
Debug
(
LDAP_DEBUG_ACL
,
"LASTMOD attribute: %s access allowed
\n
"
,
attr
,
0
,
0
);
return
(
1
);
}
#ifdef USEREGEX
a
=
acl_get_applicable
(
be
,
op
,
e
,
attr
,
edn
,
MAXREMATCHES
,
matches
);
if
(
a
)
{
for
(
i
=
0
;
i
<
MAXREMATCHES
&&
matches
[
i
].
rm_so
>-
1
;
i
++
)
{
Debug
(
LDAP_DEBUG_ARGS
,
"=> match[%d]: %d %d "
,
i
,
matches
[
i
].
rm_so
,
matches
[
i
].
rm_eo
);
for
(
n
=
matches
[
i
].
rm_so
;
n
<
matches
[
i
].
rm_eo
;
n
++
)
Debug
(
LDAP_DEBUG_ARGS
,
"%c"
,
edn
[
n
],
0
,
0
);
Debug
(
LDAP_DEBUG_ARGS
,
"
\n
"
,
0
,
0
,
0
);
}
}
rc
=
acl_access_allowed
(
a
,
be
,
conn
,
e
,
val
,
op
,
access
,
edn
,
matches
);
#else
a
=
acl_get_applicable
(
be
,
op
,
e
,
attr
,
edn
);
rc
=
acl_access_allowed
(
a
,
be
,
conn
,
e
,
val
,
op
,
access
,
edn
);
#endif
free
(
edn
);
return
(
rc
);
}
...
...
@@ -70,20 +110,32 @@ access_allowed(
* acl_access_allowed().
*/
#ifdef USEREGEX
struct
acl
*
acl_get_applicable
(
Backend
*
be
,
Operation
*
op
,
Entry
*
e
,
char
*
attr
char
*
attr
,
char
*
edn
,
int
nmatch
,
regmatch_t
matches
[]
)
#else
struct
acl
*
acl_get_applicable
(
Backend
*
be
,
Operation
*
op
,
Entry
*
e
,
char
*
attr
,
char
*
edn
)
#endif
{
int
i
;
struct
acl
*
a
;
char
*
edn
;
Debug
(
LDAP_DEBUG_ACL
,
"=> acl_get: entry (%s) attr (%s)
\n
"
,
e
->
e_dn
,
attr
,
0
);
Debug
(
LDAP_DEBUG_ACL
,
"
\n
=> acl_get: entry (%s) attr (%s)
\n
"
,
e
->
e_dn
,
attr
,
0
);
if
(
be_isroot
(
be
,
op
->
o_dn
)
)
{
Debug
(
LDAP_DEBUG_ACL
,
...
...
@@ -92,58 +144,78 @@ acl_get_applicable(
return
(
NULL
);
}
Debug
(
LDAP_DEBUG_ARGS
,
"=> acl_get: edn %s
\n
"
,
edn
,
0
,
0
);
/* check for a backend-specific acl that matches the entry */
for
(
i
=
1
,
a
=
be
->
be_acl
;
a
!=
NULL
;
a
=
a
->
acl_next
,
i
++
)
{
#ifdef USEREGEX
if
(
a
->
acl_dnpat
!=
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"=> dnpat: [%d] %s nsub: %d
\n
"
,
i
,
a
->
acl_dnpat
,
a
->
acl_dnre
.
re_nsub
);
if
(
regexec
(
&
a
->
acl_dnre
,
edn
,
nmatch
,
matches
,
0
))
continue
;
else
Debug
(
LDAP_DEBUG_TRACE
,
"=> acl_get:[%d] backend ACL match
\n
"
,
i
,
0
,
0
);
}
#else
if
(
a
->
acl_dnpat
!=
NULL
)
{
edn
=
dn_normalize_case
(
strdup
(
e
->
e_dn
)
);
if
(
!
regex_matches
(
a
->
acl_dnpat
,
edn
)
)
{
free
(
edn
);
if
(
!
regex_matches
(
a
->
acl_dnpat
,
edn
)
)
continue
;
}
free
(
edn
);
}
#endif
if
(
a
->
acl_filter
!=
NULL
)
{
if
(
test_filter
(
NULL
,
NULL
,
NULL
,
e
,
a
->
acl_filter
)
!=
0
)
{
if
(
test_filter
(
NULL
,
NULL
,
NULL
,
e
,
a
->
acl_filter
)
!=
0
)
{
continue
;
}
}
if
(
attr
==
NULL
||
a
->
acl_attrs
==
NULL
||
charray_inlist
(
a
->
acl_attrs
,
attr
)
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl_get: backend acl #%d
\n
"
,
i
,
e
->
e_dn
,
attr
);
Debug
(
LDAP_DEBUG_ARGS
,
"=> acl_get: [%d] check attr %s
\n
"
,
i
,
attr
,
0
);
if
(
attr
==
NULL
||
a
->
acl_attrs
==
NULL
||
charray_inlist
(
a
->
acl_attrs
,
attr
)
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl_get: [%d] backend acl %s attr: %s
\n
"
,
i
,
e
->
e_dn
,
attr
);
return
(
a
);
}
#ifdef USEREGEX
matches
[
0
].
rm_so
=
matches
[
0
].
rm_eo
=
-
1
;
#endif
}
/* check for a global acl that matches the entry */
for
(
i
=
1
,
a
=
global_acl
;
a
!=
NULL
;
a
=
a
->
acl_next
,
i
++
)
{
#ifdef USEREGEX
if
(
a
->
acl_dnpat
!=
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"=> dnpat: [%d] %s nsub: %d
\n
"
,
i
,
a
->
acl_dnpat
,
a
->
acl_dnre
.
re_nsub
);
if
(
regexec
(
&
a
->
acl_dnre
,
edn
,
nmatch
,
matches
,
0
))
continue
;
else
Debug
(
LDAP_DEBUG_TRACE
,
"=> acl_get: [%d] global ACL match
\n
"
,
i
,
0
,
0
);
}
#else
if
(
a
->
acl_dnpat
!=
NULL
)
{
edn
=
dn_normalize_case
(
strdup
(
e
->
e_dn
)
);
if
(
!
regex_matches
(
a
->
acl_dnpat
,
edn
)
)
{
free
(
edn
);
if
(
!
regex_matches
(
a
->
acl_dnpat
,
edn
)
)
continue
;
}
free
(
edn
);
}
#endif
if
(
a
->
acl_filter
!=
NULL
)
{
if
(
test_filter
(
NULL
,
NULL
,
NULL
,
e
,
a
->
acl_filter
)
!=
0
)
{
if
(
test_filter
(
NULL
,
NULL
,
NULL
,
e
,
a
->
acl_filter
)
!=
0
)
{
continue
;
}
}
if
(
attr
==
NULL
||
a
->
acl_attrs
==
NULL
||
charray_inlist
(
a
->
acl_attrs
,
attr
)
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl_get: global acl
#%d
\n
"
,
i
,
e
->
e_dn
,
attr
);
Debug
(
LDAP_DEBUG_ARGS
,
"=> acl_get: [%d] check attr
\n
"
,
i
,
0
,
0
);
if
(
attr
==
NULL
||
a
->
acl_attrs
==
NULL
||
charray_inlist
(
a
->
acl_attrs
,
attr
)
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl_get:
[%d]
global acl
%s attr: %s
\n
"
,
i
,
e
->
e_dn
,
attr
);
free
(
edn
);
return
(
a
);
}
#ifdef USEREGEX
matches
[
0
].
rm_so
=
matches
[
0
].
rm_eo
=
-
1
;
#endif
}
Debug
(
LDAP_DEBUG_ACL
,
"<= acl_get: no match
\n
"
,
0
,
0
,
0
);
return
(
NULL
);
}
/*
* acl_access_allowed - check whether the given acl allows dn the
* requested access to entry e, attribute attr, value val. if val
...
...
@@ -153,6 +225,7 @@ acl_get_applicable(
* 1 access allowed
*/
#ifdef USEREGEX
int
acl_access_allowed
(
struct
acl
*
a
,
...
...
@@ -161,19 +234,36 @@ acl_access_allowed(
Entry
*
e
,
struct
berval
*
val
,
Operation
*
op
,
int
access
int
access
,
char
*
edn
,
regmatch_t
matches
[]
)
#else
int
acl_access_allowed
(
struct
acl
*
a
,
Backend
*
be
,
Connection
*
conn
,
Entry
*
e
,
struct
berval
*
val
,
Operation
*
op
,
int
access
,
char
*
edn
)
#endif
{
int
i
;
char
*
edn
,
*
odn
;
char
*
odn
;
struct
access
*
b
;
Attribute
*
at
;
struct
berval
bv
;
int
default_access
;
Debug
(
LDAP_DEBUG_ACL
,
"=> acl: %s access to value
\"
%s
\"
by
\"
%s
\"\n
"
,
access2str
(
access
),
val
?
val
->
bv_val
:
"any"
,
op
->
o_dn
?
op
->
o_dn
:
""
);
Debug
(
LDAP_DEBUG_ACL
,
"
\n
=> acl: %s access to entry
\"
%s
\"
attr:
\"
%s
\"\n
"
,
access2str
(
access
),
e
->
e_dn
,
e
->
e_attrs
);
Debug
(
LDAP_DEBUG_ACL
,
"
\n
=> acl: %s access to value
\"
%s
\"
by
\"
%s
\"\n
"
,
access2str
(
access
),
val
?
val
->
bv_val
:
"any"
,
op
->
o_dn
?
op
->
o_dn
:
""
);
if
(
be_isroot
(
be
,
op
->
o_dn
)
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: granted to database root
\n
"
,
...
...
@@ -181,8 +271,8 @@ acl_access_allowed(
return
(
1
);
}
default_access
=
be
->
be_dfltaccess
?
be
->
be_dfltaccess
:
global_default_access
;
default_access
=
be
->
be_dfltaccess
?
be
->
be_dfltaccess
:
global_default_access
;
if
(
a
==
NULL
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: %s by default (no matching to)
\n
"
,
...
...
@@ -198,69 +288,84 @@ acl_access_allowed(
}
for
(
i
=
1
,
b
=
a
->
acl_access
;
b
!=
NULL
;
b
=
b
->
a_next
,
i
++
)
{
if
(
b
->
a_dnpat
!=
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"<= check a_dnpat: %s
\n
"
,
b
->
a_dnpat
,
0
,
0
);
/*
* if access applies to the entry itself, and the
* user is bound as somebody in the same namespace as
* the entry, OR the given dn matches the dn pattern
*/
if
(
strcasecmp
(
b
->
a_dnpat
,
"self"
)
==
0
&&
op
->
o_dn
!=
NULL
&&
*
(
op
->
o_dn
)
&&
e
->
e_dn
!=
NULL
)
{
edn
=
dn_normalize_case
(
strdup
(
e
->
e_dn
)
);
if
(
strcasecmp
(
b
->
a_dnpat
,
"self"
)
==
0
&&
op
->
o_dn
!=
NULL
&&
*
(
op
->
o_dn
)
&&
e
->
e_dn
!=
NULL
)
{
if
(
strcasecmp
(
edn
,
op
->
o_dn
)
==
0
)
{
free
(
edn
);
if
(
odn
)
free
(
odn
);
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: matched by clause #%d access %s
\n
"
,
i
,
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
?
"granted"
:
"denied"
,
0
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
if
(
odn
)
free
(
odn
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
}
free
(
edn
);
}
else
{
if
(
regex_matches
(
b
->
a_dnpat
,
odn
)
)
{
if
(
odn
)
free
(
odn
);
#ifdef USEREGEX
if
(
regex_matches
(
b
->
a_dnpat
,
odn
,
edn
,
matches
)
)
#else
if
(
regex_matches
(
b
->
a_dnpat
,
odn
)
)
#endif
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: matched by clause #%d access %s
\n
"
,
i
,
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
?
"granted"
:
"denied"
,
0
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
if
(
odn
)
free
(
odn
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
}
}
}
if
(
b
->
a_addrpat
!=
NULL
)
{
if
(
regex_matches
(
b
->
a_addrpat
,
conn
->
c_addr
)
)
{
if
(
odn
)
free
(
odn
);
Debug
(
LDAP_DEBUG_ARGS
,
"<= check a_addrpat: %s
\n
"
,
b
->
a_addrpat
,
0
,
0
);
#ifdef USEREGEX
if
(
regex_matches
(
b
->
a_addrpat
,
conn
->
c_addr
,
edn
,
matches
)
)
#else
if
(
regex_matches
(
b
->
a_addrpat
,
conn
->
c_addr
)
)
#endif
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: matched by clause #%d access %s
\n
"
,
i
,
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
?
"granted"
:
"denied"
,
0
);
if
(
odn
)
free
(
odn
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
}
}
if
(
b
->
a_domainpat
!=
NULL
)
{
if
(
regex_matches
(
b
->
a_domainpat
,
conn
->
c_domain
)
)
{
if
(
odn
)
free
(
odn
);
Debug
(
LDAP_DEBUG_ARGS
,
"<= check a_domainpat: %s
\n
"
,
b
->
a_domainpat
,
0
,
0
);
#ifdef USEREGEX
if
(
regex_matches
(
b
->
a_domainpat
,
conn
->
c_domain
,
edn
,
matches
)
)
#else
if
(
regex_matches
(
b
->
a_domainpat
,
conn
->
c_domain
)
)
#endif
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: matched by clause #%d access %s
\n
"
,
i
,
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
?
"granted"
:
"denied"
,
0
);
if
(
odn
)
free
(
odn
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
}
}
if
(
b
->
a_dnattr
!=
NULL
&&
op
->
o_dn
!=
NULL
)
{
Debug
(
LDAP_DEBUG_ARGS
,
"<= check a_dnattr: %s
\n
"
,
b
->
a_dnattr
,
0
,
0
);
/* see if asker is listed in dnattr */
if
(
(
at
=
attr_find
(
e
->
e_attrs
,
b
->
a_dnattr
))
!=
NULL
&&
value_find
(
at
->
a_vals
,
&
bv
,
at
->
a_syntax
,
3
)
==
0
)
if
(
(
at
=
attr_find
(
e
->
e_attrs
,
b
->
a_dnattr
))
!=
NULL
&&
value_find
(
at
->
a_vals
,
&
bv
,
at
->
a_syntax
,
3
)
==
0
)
{
if
(
(
b
->
a_access
&
ACL_SELF
)
&&
(
val
==
NULL
||
value_cmp
(
&
bv
,
val
,
at
->
a_syntax
,
if
(
(
b
->
a_access
&
ACL_SELF
)
&&
(
val
==
NULL
||
value_cmp
(
&
bv
,
val
,
at
->
a_syntax
,
2
))
)
{
continue
;
}
...
...
@@ -275,8 +380,7 @@ acl_access_allowed(
}
/* asker not listed in dnattr - check for self access */
if
(
!
(
b
->
a_access
&
ACL_SELF
)
||
val
==
NULL
||
value_cmp
(
&
bv
,
val
,
at
->
a_syntax
,
2
)
!=
0
)
{
if
(
!
(
b
->
a_access
&
ACL_SELF
)
||
val
==
NULL
||
value_cmp
(
&
bv
,
val
,
at
->
a_syntax
,
2
)
!=
0
)
{
continue
;
}
...
...
@@ -288,6 +392,30 @@ acl_access_allowed(
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
}
#ifdef ACLGROUP
if
(
b
->
a_group
!=
NULL
&&
op
->
o_dn
!=
NULL
)
{
char
buf
[
512
];
/* b->a_group is an unexpanded entry name, expanded it should be an
* entry with objectclass group* and we test to see if odn is one of
* the values in the attribute uniquegroup
* */
Debug
(
LDAP_DEBUG_ARGS
,
"<= check a_group: %s
\n
"
,
b
->
a_group
,
0
,
0
);
Debug
(
LDAP_DEBUG_ARGS
,
"<= check a_group: odn: %s
\n
"
,
odn
,
0
,
0
);
/* see if asker is listed in dnattr */
string_expand
(
buf
,
512
,
b
->
a_group
,
edn
,
matches
);
if
(
be_group
(
be
,
buf
,
odn
)
==
0
)
{
Debug
(
LDAP_DEBUG_ACL
,
"<= acl: matched by clause #%d (group) access granted
\n
"
,
i
,
0
,
0
);
if
(
odn
)
free
(
odn
);
return
(
(
b
->
a_access
&
~
ACL_SELF
)
>=
access
);
}
}
#endif
}
if
(
odn
)
free
(
odn
);
...
...
@@ -316,14 +444,32 @@ acl_check_mods(
{
int
i
;
struct
acl
*
a
;
char
*
edn
;
edn
=
dn_normalize_case
(
strdup
(
e
->
e_dn
)
);
for
(
;
mods
!=
NULL
;
mods
=
mods
->
mod_next
)
{
#ifdef USEREGEX
regmatch_t
matches
[
MAXREMATCHES
];
#endif
/* the lastmod attributes are ignored by ACL checking */
if
(
strcasecmp
(
mods
->
mod_type
,
"modifiersname"
)
==
0
||
strcasecmp
(
mods
->
mod_type
,
"modifytimestamp"
)
==
0
)
{
continue
;
strcasecmp
(
mods
->
mod_type
,
"modifytimestamp"
)
==
0
||
strcasecmp
(
mods
->
mod_type
,
"creatorsname"
)
==
0
||
strcasecmp
(
mods
->
mod_type
,
"createtimestamp"
)
==
0
)
{
Debug
(
LDAP_DEBUG_ACL
,
"LASTMOD attribute: %s access allowed
\n
"
,
mods
->
mod_type
,
0
,
0
);
continue
;
}
a
=
acl_get_applicable
(
be
,
op
,
e
,
mods
->
mod_type
);
#ifdef USEREGEX
a
=
acl_get_applicable
(
be
,
op
,
e
,
mods
->
mod_type
,
edn
,
MAXREMATCHES
,
matches
);
#else
a
=
acl_get_applicable
(
be
,
op
,
e
,
mods
->
mod_type
,
edn
);
#endif
switch
(
mods
->
mod_op
&
~
LDAP_MOD_BVALUES
)
{
case
LDAP_MOD_REPLACE
:
...
...
@@ -332,8 +478,15 @@ acl_check_mods(
break
;
}
for
(
i
=
0
;
mods
->
mod_bvalues
[
i
]
!=
NULL
;
i
++
)
{
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
mods
->
mod_bvalues
[
i
],
op
,
ACL_WRITE
)
)
{
#ifdef USEREGEX
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
mods
->
mod_bvalues
[
i
],
op
,
ACL_WRITE
,
edn
,
matches
)
)
#else
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
mods
->
mod_bvalues
[
i
],
op
,
ACL_WRITE
,
edn
)
)
#endif
{
free
(
edn
);
return
(
LDAP_INSUFFICIENT_ACCESS
);
}
}
...
...
@@ -341,15 +494,29 @@ acl_check_mods(
case
LDAP_MOD_DELETE
:
if
(
mods
->
mod_bvalues
==
NULL
)
{
#ifdef USEREGEX
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
NULL
,
op
,
ACL_WRITE
)
)
{
NULL
,
op
,
ACL_WRITE
,
edn
,
matches
)
)
#else
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
NULL
,
op
,
ACL_WRITE
,
edn
)
)
#endif
{
free
(
edn
);
return
(
LDAP_INSUFFICIENT_ACCESS
);
}
break
;
}
for
(
i
=
0
;
mods
->
mod_bvalues
[
i
]
!=
NULL
;
i
++
)
{
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
mods
->
mod_bvalues
[
i
],
op
,
ACL_WRITE
)
)
{
#ifdef USEREGEX
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
mods
->
mod_bvalues
[
i
],
op
,
ACL_WRITE
,
edn
,
matches
)
)
#else
if
(
!
acl_access_allowed
(
a
,
be
,
conn
,
e
,
mods
->
mod_bvalues
[
i
],
op
,
ACL_WRITE
,
edn
)
)
#endif
{
free
(
edn
);
return
(
LDAP_INSUFFICIENT_ACCESS
);
}
}
...
...
@@ -357,9 +524,95 @@ acl_check_mods(
}
}
free
(
edn
);
return
(
LDAP_SUCCESS
);
}
#ifdef USEREGEX
static
string_expand
(
char
*
newbuf
,
int
bufsiz
,
char
*
pat
,
char
*
match
,
regmatch_t
*
matches
)
{
int
size
;
char
*
sp
;
char
*
dp
;
int
flag
;
size
=
0
;
newbuf
[
0
]
=
'\0'
;
flag
=
0
;
for
(
dp
=
newbuf
,
sp
=
pat
;
size
<
512
&&
*
sp
;
sp
++
)
{
/* did we previously see a $ */
if
(
flag
)
{
if
(
*
sp
==
'$'
)
{
*
dp
++
=
'$'
;
size
++
;
}
else
if
(
*
sp
>=
'0'
&&
*
sp
<=
'9'
)
{
int
n
;
int
i
;
char
*
ep
;
int
l
;
n
=
*
sp
-
'0'
;
*
dp
=
'\0'
;
i
=
matches
[
n
].
rm_so
;
l
=
matches
[
n
].
rm_eo
;
for
(
;
size
<
512
&&
i
<
l
;
size
++
,
i
++
)
{
*
dp
++
=
match
[
i
];
size
++
;
}
*
dp
=
'\0'
;
}
flag
=
0
;
}
else
{
if
(
*
sp
==
'$'
)
flag
=
1
;
else
{
*
dp
++
=
*
sp
;
size
++
;
}
}
}
*
dp
=
'\0'
;
Debug
(
LDAP_DEBUG_TRACE
,
"=> string_expand: pattern: %s
\n
"
,
pat
,
0
,
0
);
Debug
(
LDAP_DEBUG_TRACE
,
"=> string_expand: expanded: %s
\n
"
,
newbuf
,
0
,
0
);
}
static
int
regex_matches
(
char
*
pat
,
/* pattern to expand and match against */
char
*
str
,
/* string to match against pattern */
char
*
buf
,
/* buffer with $N expansion variables */
regmatch_t
matches
[]
/* offsets in buffer for $N expansion variables */
)
{
regex_t
re
;
char
newbuf
[
512
];
int
rc
;
string_expand
(
newbuf
,
512
,
pat
,
buf
,
matches
);
if
((
rc
=
regcomp
(
&
re
,
newbuf
,
REG_EXTENDED
|
REG_ICASE
)))
{
char
error
[
512
];
regerror
(
rc
,
&
re
,
error
,
sizeof
(
error
));
Debug
(
LDAP_DEBUG_ANY
,
"compile(
\"
%s
\"
,
\"
%s
\"
) failed %s
\n
"
,
pat
,
str
,
error
);
return
(
0
);
}
rc
=
regexec
(
&
re
,
str
,
0
,
NULL
,
0
);
regfree
(
&
re
);