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
Joe Martin
OpenLDAP
Commits
be8f8f06
Commit
be8f8f06
authored
Sep 18, 2008
by
Quanah Gibson-Mount
Browse files
ITS#5659
parent
a0b415c8
Changes
5
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
be8f8f06
...
...
@@ -46,6 +46,7 @@ OpenLDAP 2.4.12 Engineering
Build Environment
Fixed ODBC library detection (ITS#5602)
Added BDB 4.7 support (ITS#5523)
Added slapo-collect overlay with enhancements(ITS#5659)
Documentation
Added slapd-ldap(5), slapd-meta(5) noundeffilter (ITS#5614)
Fixed slapd-ldap(5), slapd-meta(5), slapo-pcache(5) schema requirements (ITS#5680)
...
...
configure.in
View file @
be8f8f06
...
...
@@ -333,6 +333,7 @@ dnl ----------------------------------------------------------------
dnl SLAPD Overlay Options
Overlays="accesslog \
auditlog \
collect \
constraint \
dds \
dyngroup \
...
...
@@ -358,6 +359,8 @@ OL_ARG_ENABLE(accesslog,[ --enable-accesslog In-Directory Access Logging ov
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(auditlog,[ --enable-auditlog Audit Logging overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(collect,[ --enable-collect Collect overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(constraint,[ --enable-constraint Attribute Constraint overlay],
no, [no yes mod], ol_enable_overlays)
OL_ARG_ENABLE(dds,[ --enable-dds Dynamic Directory Services overlay],
...
...
@@ -2758,6 +2761,18 @@ if test "$ol_enable_auditlog" != no ; then
AC_DEFINE_UNQUOTED(SLAPD_OVER_AUDITLOG,$MFLAG,[define for Audit Logging overlay])
fi
if test "$ol_enable_collect" != no ; then
BUILD_COLLECT=$ol_enable_collect
if test "$ol_enable_collect" = mod ; then
MFLAG=SLAPD_MOD_DYNAMIC
SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS collect.la"
else
MFLAG=SLAPD_MOD_STATIC
SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS collect.o"
fi
AC_DEFINE_UNQUOTED(SLAPD_OVER_COLLECT,$MFLAG,[define for Collect overlay])
fi
if test "$ol_enable_constraint" != no ; then
BUILD_CONSTRAINT=$ol_enable_constraint
if test "$ol_enable_constraint" = mod ; then
...
...
@@ -2995,6 +3010,7 @@ dnl backends
dnl overlays
AC_SUBST(BUILD_ACCESSLOG)
AC_SUBST(BUILD_AUDITLOG)
AC_SUBST(BUILD_COLLECT)
AC_SUBST(BUILD_CONSTRAINT)
AC_SUBST(BUILD_DDS)
AC_SUBST(BUILD_DENYOP)
...
...
include/portable.hin
View file @
be8f8f06
...
...
@@ -957,6 +957,9 @@
/* define for Audit Logging overlay */
#undef SLAPD_OVER_AUDITLOG
/* define for Collect overlay */
#undef SLAPD_OVER_COLLECT
/* define for Attribute Constraint overlay */
#undef SLAPD_OVER_CONSTRAINT
...
...
servers/slapd/overlays/Makefile.in
View file @
be8f8f06
...
...
@@ -22,6 +22,7 @@ SRCS = overlays.c \
dynlist.c
\
memberof.c
\
pcache.c
\
collect.c
\
ppolicy.c
\
refint.c
\
retcode.c
\
...
...
@@ -83,6 +84,9 @@ memberof.la : memberof.lo
pcache.la
:
pcache.lo
$(LTLINK_MOD)
-module
-o
$@
pcache.lo version.lo
$(LINK_LIBS)
collect.la
:
collect.lo
$(LTLINK_MOD)
-module
-o
$@
collect.lo version.lo
$(LINK_LIBS)
ppolicy.la
:
ppolicy.lo
$(LTLINK_MOD)
-module
-o
$@
ppolicy.lo version.lo
$(LINK_LIBS)
$(MODULES_LIBS)
...
...
servers/slapd/overlays/collect.c
View file @
be8f8f06
...
...
@@ -43,14 +43,58 @@
typedef
struct
collect_info
{
struct
collect_info
*
ci_next
;
struct
berval
ci_dn
;
AttributeDescription
*
ci_ad
;
int
ci_ad_num
;
AttributeDescription
*
ci_ad
[];
}
collect_info
;
/*
* inserts a collect_info into on->on_bi.bi_private taking into account
* order. this means longer dn's (i.e. more specific dn's) will be found
* first when searching, allowing some limited overlap of dn's
*/
static
void
insert_ordered
(
slap_overinst
*
on
,
collect_info
*
ci
)
{
collect_info
*
find
=
on
->
on_bi
.
bi_private
;
collect_info
*
prev
=
NULL
;
int
found
=
0
;
while
(
!
found
)
{
if
(
find
==
NULL
)
{
if
(
prev
==
NULL
)
{
/* base case - empty list */
on
->
on_bi
.
bi_private
=
ci
;
ci
->
ci_next
=
NULL
;
}
else
{
/* final case - end of list */
prev
->
ci_next
=
ci
;
ci
->
ci_next
=
NULL
;
}
found
=
1
;
}
else
if
(
find
->
ci_dn
.
bv_len
<=
ci
->
ci_dn
.
bv_len
)
{
/* insert into list here */
if
(
prev
==
NULL
)
{
/* entry is head of list */
ci
->
ci_next
=
on
->
on_bi
.
bi_private
;
on
->
on_bi
.
bi_private
=
ci
;
}
else
{
/* entry is not head of list */
prev
->
ci_next
=
ci
;
ci
->
ci_next
=
find
;
}
found
=
1
;
}
else
{
/* keep looking */
prev
=
find
;
find
=
find
->
ci_next
;
}
}
}
static
int
collect_cf
(
ConfigArgs
*
c
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
c
->
bi
;
int
rc
=
1
;
int
rc
=
1
,
idx
;
switch
(
c
->
op
)
{
case
SLAP_CONFIG_EMIT
:
...
...
@@ -58,14 +102,34 @@ collect_cf( ConfigArgs *c )
collect_info
*
ci
;
for
(
ci
=
on
->
on_bi
.
bi_private
;
ci
;
ci
=
ci
->
ci_next
)
{
struct
berval
bv
;
char
*
ptr
;
int
len
;
bv
.
bv_len
=
ci
->
ci_dn
.
bv_len
+
STRLENOF
(
"
\"\"
"
)
+
ci
->
ci_ad
->
ad_cname
.
bv_len
;
/* calculate the length & malloc memory */
bv
.
bv_len
=
ci
->
ci_dn
.
bv_len
+
STRLENOF
(
"
\"\"
"
);
for
(
idx
=
0
;
idx
<
ci
->
ci_ad_num
;
idx
++
)
{
bv
.
bv_len
+=
ci
->
ci_ad
[
idx
]
->
ad_cname
.
bv_len
;
if
(
idx
<
(
ci
->
ci_ad_num
-
1
))
{
bv
.
bv_len
++
;
}
}
bv
.
bv_val
=
ch_malloc
(
bv
.
bv_len
+
1
);
len
=
snprintf
(
bv
.
bv_val
,
bv
.
bv_len
+
1
,
"
\"
%s
\"
%s"
,
ci
->
ci_dn
.
bv_val
,
ci
->
ci_ad
->
ad_cname
.
bv_val
);
assert
(
len
==
bv
.
bv_len
);
/* copy the value and update len */
len
=
snprintf
(
bv
.
bv_val
,
bv
.
bv_len
+
1
,
"
\"
%s
\"
"
,
ci
->
ci_dn
.
bv_val
);
ptr
=
bv
.
bv_val
+
len
;
for
(
idx
=
0
;
idx
<
ci
->
ci_ad_num
;
idx
++
)
{
ptr
=
lutil_strncopy
(
ptr
,
ci
->
ci_ad
[
idx
]
->
ad_cname
.
bv_val
,
ci
->
ci_ad
[
idx
]
->
ad_cname
.
bv_len
);
if
(
idx
<
(
ci
->
ci_ad_num
-
1
))
{
*
ptr
++
=
','
;
}
}
*
ptr
=
'\0'
;
bv
.
bv_len
=
ptr
-
bv
.
bv_val
;
ber_bvarray_add
(
&
c
->
rvalue_vals
,
&
bv
);
rc
=
0
;
}
...
...
@@ -98,8 +162,21 @@ collect_cf( ConfigArgs *c )
collect_info
*
ci
;
struct
berval
bv
,
dn
;
const
char
*
text
;
AttributeDescription
*
ad
=
NULL
;
int
idx
,
count
=
0
;
char
*
arg
;
/* count delimiters in attribute argument */
arg
=
strtok
(
c
->
argv
[
2
],
","
);
while
(
arg
!=
NULL
)
{
count
++
;
arg
=
strtok
(
NULL
,
","
);
}
/* allocate config info with room for attribute array */
ci
=
ch_malloc
(
sizeof
(
collect_info
)
+
(
sizeof
(
AttributeDescription
*
)
*
(
count
+
1
)));
/* validate and normalize dn */
ber_str2bv
(
c
->
argv
[
1
],
0
,
0
,
&
bv
);
if
(
dnNormalize
(
0
,
NULL
,
NULL
,
&
bv
,
&
dn
,
NULL
)
)
{
snprintf
(
c
->
cr_msg
,
sizeof
(
c
->
cr_msg
),
"%s invalid DN:
\"
%s
\"
"
,
...
...
@@ -108,22 +185,38 @@ collect_cf( ConfigArgs *c )
"%s: %s
\n
"
,
c
->
log
,
c
->
cr_msg
,
0
);
return
ARG_BAD_CONF
;
}
if
(
slap_str2ad
(
c
->
argv
[
2
],
&
ad
,
&
text
)
)
{
snprintf
(
c
->
cr_msg
,
sizeof
(
c
->
cr_msg
),
"%s attribute description unknown:
\"
%s
\"
"
,
c
->
argv
[
0
],
c
->
argv
[
2
]
);
Debug
(
LDAP_DEBUG_CONFIG
|
LDAP_DEBUG_NONE
,
"%s: %s
\n
"
,
c
->
log
,
c
->
cr_msg
,
0
);
return
ARG_BAD_CONF
;
/* load attribute description for attribute list */
arg
=
c
->
argv
[
2
];
for
(
idx
=
0
;
idx
<
count
;
idx
++
)
{
ci
->
ci_ad
[
idx
]
=
NULL
;
if
(
slap_str2ad
(
arg
,
&
ci
->
ci_ad
[
idx
],
&
text
)
)
{
snprintf
(
c
->
cr_msg
,
sizeof
(
c
->
cr_msg
),
"%s attribute description unknown:
\"
%s
\"
"
,
c
->
argv
[
0
],
arg
);
Debug
(
LDAP_DEBUG_CONFIG
|
LDAP_DEBUG_NONE
,
"%s: %s
\n
"
,
c
->
log
,
c
->
cr_msg
,
0
);
return
ARG_BAD_CONF
;
}
while
(
*
arg
!=
'\0'
)
{
arg
++
;
/* skip to end of argument */
}
if
(
idx
<
count
-
1
)
{
arg
++
;
/* skip inner delimiters */
}
}
/* The on->on_bi.bi_private pointer can be used for
* anything this instance of the overlay needs.
*/
ci
=
ch_malloc
(
sizeof
(
collect_info
))
;
ci
->
ci_ad
=
ad
;
ci
->
ci_ad
[
count
]
=
NULL
;
ci
->
ci_ad
_num
=
count
;
ci
->
ci_dn
=
dn
;
ci
->
ci_next
=
on
->
on_bi
.
bi_private
;
on
->
on_bi
.
bi_private
=
ci
;
/* creates list of ci's ordered by dn length */
insert_ordered
(
on
,
ci
);
rc
=
0
;
}
}
...
...
@@ -166,6 +259,48 @@ collect_destroy(
return
0
;
}
static
int
collect_modify
(
Operation
*
op
,
SlapReply
*
rs
)
{
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
collect_info
*
ci
=
on
->
on_bi
.
bi_private
;
Modifications
*
ml
;
char
errMsg
[
100
];
int
rc
,
idx
;
for
(
ml
=
op
->
orm_modlist
;
ml
!=
NULL
;
ml
=
ml
->
sml_next
)
{
for
(;
ci
;
ci
=
ci
->
ci_next
)
{
/* Is this entry an ancestor of this collectinfo ? */
if
(
!
dnIsSuffix
(
&
op
->
o_req_ndn
,
&
ci
->
ci_dn
))
{
/* this collectinfo does not match */
continue
;
}
/* Is this entry the same as the template DN ? */
if
(
dn_match
(
&
op
->
o_req_ndn
,
&
ci
->
ci_dn
))
{
/* all changes in this ci are allowed */
continue
;
}
/* check for collect attributes - disallow modify if present */
for
(
idx
=
0
;
idx
<
ci
->
ci_ad_num
;
idx
++
)
{
if
(
ml
->
sml_desc
==
ci
->
ci_ad
[
idx
])
{
rs
->
sr_err
=
LDAP_UNWILLING_TO_PERFORM
;
snprintf
(
errMsg
,
sizeof
(
errMsg
),
"cannot change virtual attribute '%s'"
,
ci
->
ci_ad
[
idx
]
->
ad_cname
.
bv_val
);
rs
->
sr_text
=
errMsg
;
send_ldap_result
(
op
,
rs
);
return
rs
->
sr_err
;
}
}
}
}
return
SLAP_CB_CONTINUE
;
}
static
int
collect_response
(
Operation
*
op
,
SlapReply
*
rs
)
{
...
...
@@ -181,35 +316,51 @@ collect_response( Operation *op, SlapReply *rs )
op
->
o_bd
->
bd_info
=
(
BackendInfo
*
)
on
->
on_info
;
for
(;
ci
;
ci
=
ci
->
ci_next
)
{
BerVarray
vals
=
NULL
;
int
idx
=
0
;
/* Is this entry an ancestor of this collectinfo ? */
if
(
!
dnIsSuffix
(
&
rs
->
sr_entry
->
e_nname
,
&
ci
->
ci_dn
))
{
/* collectinfo does not match */
continue
;
}
/* Is our configured entry an ancestor of this one? */
if
(
!
dnIsSuffix
(
&
rs
->
sr_entry
->
e_nname
,
&
ci
->
ci_dn
))
/* Is this entry the same as the template DN ? */
if
(
dn_match
(
&
rs
->
sr_entry
->
e_nname
,
&
ci
->
ci_dn
))
{
/* dont apply change to parent */
continue
;
}
/* The current entry may live in a cache, so
* don't modify it directly. Make a copy and
* work with that instead.
*/
if
(
!
(
rs
->
sr_flags
&
REP_ENTRY_MODIFIABLE
))
{
rs
->
sr_entry
=
entry_dup
(
rs
->
sr_entry
);
rs
->
sr_flags
|=
REP_ENTRY_MODIFIABLE
|
REP_ENTRY_MUSTBEFREED
;
}
/* Extract the values of the desired attribute from
* the ancestor entry
*/
rc
=
backend_attribute
(
op
,
NULL
,
&
ci
->
ci_dn
,
ci
->
ci_ad
,
&
vals
,
ACL_READ
);
/* If there are any values, merge them into the
* current entry
*/
if
(
vals
)
{
/* The current entry may live in a cache, so
* don't modify it directly. Make a copy and
* work with that instead.
*/
if
(
!
(
rs
->
sr_flags
&
REP_ENTRY_MODIFIABLE
))
{
rs
->
sr_entry
=
entry_dup
(
rs
->
sr_entry
);
rs
->
sr_flags
|=
REP_ENTRY_MODIFIABLE
|
REP_ENTRY_MUSTBEFREED
;
/* Loop for each attribute in this collectinfo */
for
(
idx
=
0
;
idx
<
ci
->
ci_ad_num
;
idx
++
)
{
BerVarray
vals
=
NULL
;
/* Extract the values of the desired attribute from
* the ancestor entry */
rc
=
backend_attribute
(
op
,
NULL
,
&
ci
->
ci_dn
,
ci
->
ci_ad
[
idx
],
&
vals
,
ACL_READ
);
/* If there are any values, merge them into the
* current search result
*/
if
(
vals
)
{
attr_merge
(
rs
->
sr_entry
,
ci
->
ci_ad
[
idx
],
vals
,
NULL
);
ber_bvarray_free_x
(
vals
,
op
->
o_tmpmemctx
);
}
attr_merge
(
rs
->
sr_entry
,
ci
->
ci_ad
,
vals
,
NULL
);
ber_bvarray_free_x
(
vals
,
op
->
o_tmpmemctx
);
}
}
}
/* Default is to just fall through to the normal processing */
return
SLAP_CB_CONTINUE
;
}
...
...
@@ -221,6 +372,7 @@ int collect_initialize() {
collect
.
on_bi
.
bi_type
=
"collect"
;
collect
.
on_bi
.
bi_db_destroy
=
collect_destroy
;
collect
.
on_bi
.
bi_op_modify
=
collect_modify
;
collect
.
on_response
=
collect_response
;
collect
.
on_bi
.
bi_cf_ocs
=
collectocs
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment