Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
O
OpenLDAP
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Christopher Ng
OpenLDAP
Commits
ce847255
Commit
ce847255
authored
16 years ago
by
Quanah Gibson-Mount
Browse files
Options
Downloads
Patches
Plain Diff
Add attribute size and count constraints to slapo-constaint
parent
c89d1e14
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
doc/man/man5/slapo-constraint.5
+11
-1
11 additions, 1 deletion
doc/man/man5/slapo-constraint.5
servers/slapd/overlays/constraint.c
+133
-25
133 additions, 25 deletions
servers/slapd/overlays/constraint.c
with
144 additions
and
26 deletions
doc/man/man5/slapo-constraint.5
+
11
−
1
View file @
ce847255
...
...
@@ -31,7 +31,9 @@ directive.
Specifies the constraint which should apply to the attribute named as
the first parameter.
Two types of constraint are currently supported -
.B regex
.B regex ,
.B size ,
.B count ,
and
.BR uri .
...
...
@@ -45,6 +47,12 @@ type is an LDAP URI. The URI will be evaluated using an internal search.
It must not include a hostname, and it must include a list of attributes
to evaluate.
The
.B size
type can be used to enfore a limit on an attribute length, and the
.B count
type limits the count of an attribute.
Any attempt to add or modify an attribute named as part of the
constraint overlay specification which does not fit the
constraint listed will fail with a
...
...
@@ -54,6 +62,8 @@ LDAP_CONSTRAINT_VIOLATION error.
.RS
.nf
overlay constraint
constraint_attribute jpegPhoto size 131072
constraint_attribute userPassword count 3
constraint_attribute mail regex ^[:alnum:]+@mydomain.com$
constraint_attribute title uri
ldap:///dc=catalog,dc=example,dc=com?title?sub?(objectClass=titleCatalog)
...
...
This diff is collapsed.
Click to expand it.
servers/slapd/overlays/constraint.c
+
133
−
25
View file @
ce847255
...
...
@@ -41,6 +41,8 @@
#define REGEX_STR "regex"
#define URI_STR "uri"
#define SIZE_STR "size"
#define COUNT_STR "count"
/*
* Linked list of attribute constraints which we should enforce.
...
...
@@ -55,6 +57,8 @@ typedef struct constraint {
AttributeDescription
*
ap
;
regex_t
*
re
;
LDAPURLDesc
*
lud
;
size_t
size
;
size_t
count
;
AttributeDescription
**
attrs
;
struct
berval
val
;
/* constraint value */
struct
berval
dn
;
...
...
@@ -129,6 +133,12 @@ constraint_cf_gen( ConfigArgs *c )
}
else
if
(
cp
->
lud
)
{
len
+=
STRLENOF
(
URI_STR
);
tstr
=
URI_STR
;
}
else
if
(
cp
->
size
)
{
len
+=
STRLENOF
(
SIZE_STR
);
tstr
=
SIZE_STR
;
}
else
if
(
cp
->
count
)
{
len
+=
STRLENOF
(
COUNT_STR
);
tstr
=
COUNT_STR
;
}
len
+=
cp
->
val
.
bv_len
;
...
...
@@ -216,7 +226,17 @@ constraint_cf_gen( ConfigArgs *c )
return
(
ARG_BAD_CONF
);
}
ber_str2bv
(
c
->
argv
[
3
],
0
,
1
,
&
ap
.
val
);
}
else
if
(
strcasecmp
(
c
->
argv
[
2
],
URI_STR
)
==
0
)
{
}
else
if
(
strcasecmp
(
c
->
argv
[
2
],
SIZE_STR
)
==
0
)
{
size_t
size
;
if
(
(
size
=
atoi
(
c
->
argv
[
3
])
)
!=
0
)
ap
.
size
=
size
;
}
else
if
(
strcasecmp
(
c
->
argv
[
2
],
COUNT_STR
)
==
0
)
{
size_t
count
;
if
(
(
count
=
atoi
(
c
->
argv
[
3
])
)
!=
0
)
ap
.
count
=
count
;
}
else
if
(
strcasecmp
(
c
->
argv
[
2
],
URI_STR
)
==
0
)
{
int
err
;
err
=
ldap_url_parse
(
c
->
argv
[
3
],
&
ap
.
lud
);
...
...
@@ -281,6 +301,8 @@ constraint_cf_gen( ConfigArgs *c )
a2
->
re
=
ap
.
re
;
a2
->
val
=
ap
.
val
;
a2
->
lud
=
ap
.
lud
;
a2
->
size
=
ap
.
size
;
a2
->
count
=
ap
.
count
;
if
(
a2
->
lud
)
{
ber_str2bv
(
a2
->
lud
->
lud_dn
,
0
,
0
,
&
a2
->
dn
);
ber_str2bv
(
a2
->
lud
->
lud_filter
,
0
,
0
,
&
a2
->
filter
);
...
...
@@ -323,6 +345,9 @@ constraint_violation( constraint *c, struct berval *bv, Operation *op, SlapReply
(
regexec
(
c
->
re
,
bv
->
bv_val
,
0
,
NULL
,
0
)
==
REG_NOMATCH
))
return
1
;
/* regular expression violation */
if
((
c
->
size
)
&&
(
bv
->
bv_len
>
c
->
size
))
return
1
;
/* size violation */
if
(
c
->
lud
)
{
Operation
nop
=
*
op
;
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
...
...
@@ -443,10 +468,21 @@ print_message( struct berval *errtext, AttributeDescription *a )
return
ret
;
}
static
unsigned
constraint_count_attr
(
Entry
*
e
,
AttributeDescription
*
ad
)
{
struct
Attribute
*
a
;
if
((
a
=
attr_find
(
e
->
e_attrs
,
ad
))
!=
NULL
)
return
a
->
a_numvals
;
return
0
;
}
static
int
constraint_add
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
Backend
*
be
=
op
->
o_bd
;
Attribute
*
a
;
constraint
*
c
=
on
->
on_bi
.
bi_private
,
*
cp
;
BerVarray
b
=
NULL
;
...
...
@@ -469,35 +505,45 @@ constraint_add( Operation *op, SlapReply *rs )
if
(
cp
->
ap
!=
a
->
a_desc
)
continue
;
if
((
b
=
a
->
a_vals
)
==
NULL
)
continue
;
for
(
i
=
0
;
b
[
i
].
bv_val
;
i
++
)
{
int
cv
=
constraint_violation
(
cp
,
&
b
[
i
],
op
,
rs
);
if
(
cv
)
{
/* violation */
op
->
o_bd
->
bd_info
=
(
BackendInfo
*
)(
on
->
on_info
);
msg
=
print_message
(
&
rsv
,
a
->
a_desc
);
send_ldap_error
(
op
,
rs
,
LDAP_CONSTRAINT_VIOLATION
,
msg
);
ch_free
(
msg
);
return
(
rs
->
sr_err
);
}
}
Debug
(
LDAP_DEBUG_TRACE
,
"==> constraint_add, "
"a->a_numvals = %d, cp->count = %d
\n
"
,
a
->
a_numvals
,
cp
->
count
,
0
);
if
((
cp
->
count
!=
0
)
&&
(
a
->
a_numvals
>
cp
->
count
))
goto
add_violation
;
for
(
i
=
0
;
b
[
i
].
bv_val
;
i
++
)
if
(
constraint_violation
(
cp
,
&
b
[
i
],
op
,
rs
))
goto
add_violation
;
}
}
/* Default is to just fall through to the normal processing */
return
SLAP_CB_CONTINUE
;
add_violation:
op
->
o_bd
->
bd_info
=
(
BackendInfo
*
)(
on
->
on_info
);
msg
=
print_message
(
&
rsv
,
a
->
a_desc
);
send_ldap_error
(
op
,
rs
,
LDAP_CONSTRAINT_VIOLATION
,
msg
);
ch_free
(
msg
);
return
(
rs
->
sr_err
);
}
static
int
constraint_modify
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
Backend
*
be
=
op
->
o_bd
;
constraint
*
c
=
on
->
on_bi
.
bi_private
,
*
cp
;
Entry
*
target_entry
=
NULL
;
Modifications
*
m
;
BerVarray
b
=
NULL
;
int
i
;
struct
berval
rsv
=
BER_BVC
(
"modify breaks constraint"
);
char
*
msg
;
Debug
(
LDAP_DEBUG_CONFIG
|
LDAP_DEBUG_NONE
,
"constraint_modify()"
,
0
,
0
,
0
);
if
((
m
=
op
->
orm_modlist
)
==
NULL
)
{
op
->
o_bd
->
bd_info
=
(
BackendInfo
*
)(
on
->
on_info
);
send_ldap_error
(
op
,
rs
,
LDAP_INVALID_SYNTAX
,
...
...
@@ -505,34 +551,96 @@ constraint_modify( Operation *op, SlapReply *rs )
return
(
rs
->
sr_err
);
}
/* Do we need to count attributes? */
for
(
cp
=
c
;
cp
;
cp
=
cp
->
ap_next
)
{
if
(
cp
->
count
!=
0
)
{
int
rc
;
op
->
o_bd
=
on
->
on_info
->
oi_origdb
;
rc
=
be_entry_get_rw
(
op
,
&
op
->
o_req_ndn
,
NULL
,
NULL
,
0
,
&
target_entry
);
op
->
o_bd
=
be
;
if
(
rc
!=
0
||
target_entry
==
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"==> constraint_modify rc = %d
\n
"
,
rc
,
0
,
0
);
goto
mod_violation
;
}
break
;
}
}
for
(;
m
;
m
=
m
->
sml_next
)
{
int
ce
=
0
;
/* Get this attribute count, if needed */
if
(
target_entry
)
ce
=
constraint_count_attr
(
target_entry
,
m
->
sml_desc
);
if
(
is_at_operational
(
m
->
sml_desc
->
ad_type
))
continue
;
if
(((
m
->
sml_op
&
LDAP_MOD_OP
)
!=
LDAP_MOD_ADD
)
&&
((
m
->
sml_op
&
LDAP_MOD_OP
)
!=
LDAP_MOD_REPLACE
))
((
m
->
sml_op
&
LDAP_MOD_OP
)
!=
LDAP_MOD_REPLACE
)
&&
((
m
->
sml_op
&
LDAP_MOD_OP
)
!=
LDAP_MOD_DELETE
))
continue
;
/* we only care about ADD and REPLACE modifications */
/* and DELETE are used to track attribute count */
if
(((
b
=
m
->
sml_values
)
==
NULL
)
||
(
b
[
0
].
bv_val
==
NULL
))
continue
;
for
(
cp
=
c
;
cp
;
cp
=
cp
->
ap_next
)
{
if
(
cp
->
ap
!=
m
->
sml_desc
)
continue
;
for
(
i
=
0
;
b
[
i
].
bv_val
;
i
++
)
{
int
cv
=
constraint_violation
(
cp
,
&
b
[
i
],
op
,
rs
);
if
(
cv
)
{
/* violation */
op
->
o_bd
->
bd_info
=
(
BackendInfo
*
)(
on
->
on_info
);
msg
=
print_message
(
&
rsv
,
m
->
sml_desc
);
send_ldap_error
(
op
,
rs
,
LDAP_CONSTRAINT_VIOLATION
,
msg
);
ch_free
(
msg
);
return
(
rs
->
sr_err
);
if
(
cp
->
count
!=
0
)
{
int
ca
;
if
(
m
->
sml_op
==
LDAP_MOD_DELETE
)
ce
=
0
;
for
(
ca
=
0
;
b
[
ca
].
bv_val
;
++
ca
);
Debug
(
LDAP_DEBUG_TRACE
,
"==> constraint_modify ce = %d, "
"ca = %d, cp->count = %d
\n
"
,
ce
,
ca
,
cp
->
count
);
if
(
m
->
sml_op
==
LDAP_MOD_ADD
)
if
(
ca
+
ce
>
cp
->
count
)
goto
mod_violation
;
if
(
m
->
sml_op
==
LDAP_MOD_REPLACE
)
{
if
(
ca
>
cp
->
count
)
goto
mod_violation
;
ce
=
ca
;
}
}
}
/* DELETE are to be ignored beyond this point */
if
((
m
->
sml_op
&
LDAP_MOD_OP
)
==
LDAP_MOD_DELETE
)
continue
;
for
(
i
=
0
;
b
[
i
].
bv_val
;
i
++
)
if
(
constraint_violation
(
cp
,
&
b
[
i
],
op
,
rs
))
goto
mod_violation
;
}
}
if
(
target_entry
)
{
op
->
o_bd
=
on
->
on_info
->
oi_origdb
;
be_entry_release_r
(
op
,
target_entry
);
op
->
o_bd
=
be
;
}
return
SLAP_CB_CONTINUE
;
mod_violation:
/* violation */
if
(
target_entry
)
{
op
->
o_bd
=
on
->
on_info
->
oi_origdb
;
be_entry_release_r
(
op
,
target_entry
);
op
->
o_bd
=
be
;
}
op
->
o_bd
->
bd_info
=
(
BackendInfo
*
)(
on
->
on_info
);
msg
=
print_message
(
&
rsv
,
m
->
sml_desc
);
send_ldap_error
(
op
,
rs
,
LDAP_CONSTRAINT_VIOLATION
,
msg
);
ch_free
(
msg
);
return
(
rs
->
sr_err
);
}
static
int
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment