2007-02-22 01:54:40 +00:00
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
/*
Partitions ldb module
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2006
2007-01-07 19:11:27 +00:00
Copyright ( C ) Stefan Metzmacher < metze @ samba . org > 2007
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
* NOTICE : this module is NOT released under the GNU LGPL license as
* other ldb code . This module is release under the GNU GPL v2 or
* later license .
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
* Name : ldb
*
* Component : ldb partitions module
*
* Description : Implement LDAP partitions
*
* Author : Andrew Bartlett
2007-01-07 19:11:27 +00:00
* Author : Stefan Metzmacher
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
*/
# include "includes.h"
2007-05-05 18:50:56 +00:00
# include "ldb/include/ldb_includes.h"
2007-01-07 19:11:27 +00:00
# include "dsdb/samdb/samdb.h"
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
struct partition_private_data {
2007-01-15 17:53:53 +00:00
struct dsdb_control_current_partition * * partitions ;
2006-07-29 01:13:53 +00:00
struct ldb_dn * * replicate ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
} ;
2006-07-22 16:56:33 +00:00
struct partition_context {
2006-07-17 22:36:04 +00:00
struct ldb_module * module ;
2007-01-11 09:38:21 +00:00
struct ldb_handle * handle ;
2006-07-17 22:36:04 +00:00
struct ldb_request * orig_req ;
2006-07-29 01:13:53 +00:00
struct ldb_request * * down_req ;
int num_requests ;
int finished_requests ;
2006-07-17 22:36:04 +00:00
} ;
2007-01-11 09:38:21 +00:00
static struct partition_context * partition_init_handle ( struct ldb_request * req , struct ldb_module * module )
2006-07-17 22:36:04 +00:00
{
2006-07-22 16:56:33 +00:00
struct partition_context * ac ;
struct ldb_handle * h ;
2006-07-17 22:36:04 +00:00
2006-07-22 16:56:33 +00:00
h = talloc_zero ( req , struct ldb_handle ) ;
2006-07-17 22:36:04 +00:00
if ( h = = NULL ) {
2006-08-13 07:33:57 +00:00
ldb_set_errstring ( module - > ldb , " Out of Memory " ) ;
2006-07-17 22:36:04 +00:00
return NULL ;
}
h - > module = module ;
2006-07-22 16:56:33 +00:00
ac = talloc_zero ( h , struct partition_context ) ;
2006-07-17 22:36:04 +00:00
if ( ac = = NULL ) {
2006-08-13 07:33:57 +00:00
ldb_set_errstring ( module - > ldb , " Out of Memory " ) ;
2006-07-17 22:36:04 +00:00
talloc_free ( h ) ;
return NULL ;
}
2007-01-11 09:38:21 +00:00
h - > private_data = ac ;
2006-07-17 22:36:04 +00:00
ac - > module = module ;
2007-01-11 09:38:21 +00:00
ac - > handle = h ;
2006-07-17 22:36:04 +00:00
ac - > orig_req = req ;
2007-01-11 09:38:21 +00:00
req - > handle = h ;
return ac ;
2006-07-17 22:36:04 +00:00
}
2007-01-17 13:46:16 +00:00
static struct ldb_module * make_module_for_next_request ( TALLOC_CTX * mem_ctx ,
struct ldb_context * ldb ,
struct ldb_module * module )
2006-07-10 11:24:46 +00:00
{
struct ldb_module * current ;
static const struct ldb_module_ops ops ; /* zero */
current = talloc_zero ( mem_ctx , struct ldb_module ) ;
if ( current = = NULL ) {
return module ;
}
current - > ldb = ldb ;
current - > ops = & ops ;
current - > prev = NULL ;
current - > next = module ;
return current ;
}
2007-01-17 13:46:16 +00:00
static struct dsdb_control_current_partition * find_partition ( struct partition_private_data * data ,
struct ldb_dn * dn )
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
{
int i ;
2007-01-17 13:46:16 +00:00
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
/* Look at base DN */
/* Figure out which partition it is under */
/* Skip the lot if 'data' isn't here yet (initialistion) */
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
2006-11-23 22:06:07 +00:00
if ( ldb_dn_compare_base ( data - > partitions [ i ] - > dn , dn ) = = 0 ) {
2007-01-17 13:46:16 +00:00
return data - > partitions [ i ] ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
}
2007-01-17 13:46:16 +00:00
return NULL ;
} ;
static struct ldb_module * find_backend ( struct ldb_module * module , struct ldb_request * req , struct ldb_dn * dn )
{
struct dsdb_control_current_partition * partition ;
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
/* Skip the lot if 'data' isn't here yet (initialistion) */
if ( ! data ) {
return module ;
}
partition = find_partition ( data , dn ) ;
if ( ! partition ) {
return module ;
}
return make_module_for_next_request ( req , module - > ldb , partition - > module ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
} ;
2006-07-29 01:13:53 +00:00
/*
fire the caller ' s callback for every entry , but only send ' done ' once .
*/
static int partition_search_callback ( struct ldb_context * ldb , void * context , struct ldb_reply * ares )
{
struct partition_context * ac ;
if ( ! context | | ! ares ) {
2006-08-13 07:33:57 +00:00
ldb_set_errstring ( ldb , " partition_search_callback: NULL Context or Result in 'search' callback " ) ;
2006-07-29 01:13:53 +00:00
goto error ;
}
ac = talloc_get_type ( context , struct partition_context ) ;
if ( ares - > type = = LDB_REPLY_ENTRY ) {
return ac - > orig_req - > callback ( ldb , ac - > orig_req - > context , ares ) ;
} else {
ac - > finished_requests + + ;
if ( ac - > finished_requests = = ac - > num_requests ) {
return ac - > orig_req - > callback ( ldb , ac - > orig_req - > context , ares ) ;
} else {
talloc_free ( ares ) ;
return LDB_SUCCESS ;
}
}
error :
talloc_free ( ares ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
/*
only fire the ' last ' callback , and only for START - TLS for now
*/
static int partition_other_callback ( struct ldb_context * ldb , void * context , struct ldb_reply * ares )
{
struct partition_context * ac ;
2006-07-29 01:52:15 +00:00
if ( ! context ) {
2006-08-13 07:33:57 +00:00
ldb_set_errstring ( ldb , " partition_other_callback: NULL Context in 'other' callback " ) ;
2006-07-29 01:13:53 +00:00
goto error ;
}
ac = talloc_get_type ( context , struct partition_context ) ;
2006-07-29 02:00:33 +00:00
if ( ! ac - > orig_req - > callback ) {
talloc_free ( ares ) ;
return LDB_SUCCESS ;
}
2006-07-29 01:52:15 +00:00
if ( ! ares
| | ( ares - > type = = LDB_REPLY_EXTENDED
& & strcmp ( ares - > response - > oid , LDB_EXTENDED_START_TLS_OID ) ) ) {
2006-07-29 01:13:53 +00:00
ac - > finished_requests + + ;
if ( ac - > finished_requests = = ac - > num_requests ) {
return ac - > orig_req - > callback ( ldb , ac - > orig_req - > context , ares ) ;
}
talloc_free ( ares ) ;
return LDB_SUCCESS ;
}
2006-08-13 07:33:57 +00:00
ldb_set_errstring ( ldb , " partition_other_callback: Unknown reply type, only supports START_TLS " ) ;
2006-07-29 01:13:53 +00:00
error :
talloc_free ( ares ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-03-13 00:59:06 +00:00
static int partition_send_request ( struct partition_context * ac , struct ldb_control * remove_control ,
struct dsdb_control_current_partition * partition )
2006-07-17 22:36:04 +00:00
{
int ret ;
2007-01-17 16:55:37 +00:00
struct ldb_module * backend ;
2006-09-14 03:15:30 +00:00
struct ldb_request * req ;
2007-03-13 00:59:06 +00:00
struct ldb_control * * saved_controls ;
2007-01-17 16:55:37 +00:00
if ( partition ) {
backend = make_module_for_next_request ( ac , ac - > module - > ldb , partition - > module ) ;
} else {
backend = ac - > module ;
}
2006-07-29 01:13:53 +00:00
ac - > down_req = talloc_realloc ( ac , ac - > down_req ,
struct ldb_request * , ac - > num_requests + 1 ) ;
if ( ! ac - > down_req ) {
2007-02-22 01:54:40 +00:00
ldb_oom ( ac - > module - > ldb ) ;
2006-07-17 22:36:04 +00:00
return LDB_ERR_OPERATIONS_ERROR ;
}
2006-09-14 03:15:30 +00:00
req = ac - > down_req [ ac - > num_requests ] = talloc ( ac , struct ldb_request ) ;
if ( req = = NULL ) {
2007-02-22 01:54:40 +00:00
ldb_oom ( ac - > module - > ldb ) ;
2006-07-17 22:36:04 +00:00
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-02-22 01:54:40 +00:00
* req = * ac - > orig_req ; /* copy the request */
2007-03-13 00:59:06 +00:00
if ( req - > controls ) {
2007-02-22 01:54:40 +00:00
req - > controls
= talloc_memdup ( req ,
ac - > orig_req - > controls , talloc_get_size ( ac - > orig_req - > controls ) ) ;
if ( req - > controls = = NULL ) {
ldb_oom ( ac - > module - > ldb ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
}
2006-09-14 03:15:30 +00:00
if ( req - > operation = = LDB_SEARCH ) {
/* If the search is for 'more' than this partition,
* then change the basedn , so a remote LDAP server
* doesn ' t object */
2007-01-17 16:55:37 +00:00
if ( partition ) {
if ( ldb_dn_compare_base ( partition - > dn , req - > op . search . base ) ! = 0 ) {
req - > op . search . base = partition - > dn ;
}
} else {
req - > op . search . base = NULL ;
2006-09-14 03:15:30 +00:00
}
req - > callback = partition_search_callback ;
req - > context = ac ;
2006-07-29 01:13:53 +00:00
} else {
2006-09-14 03:15:30 +00:00
req - > callback = partition_other_callback ;
req - > context = ac ;
2006-07-29 01:13:53 +00:00
}
2007-03-13 00:59:06 +00:00
/* Remove a control, so we don't confuse a backend server */
if ( remove_control & & ! save_controls ( remove_control , req , & saved_controls ) ) {
ldb_oom ( ac - > module - > ldb ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-01-17 16:55:37 +00:00
if ( partition ) {
ret = ldb_request_add_control ( req , DSDB_CONTROL_CURRENT_PARTITION_OID , false , partition ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
2006-07-17 22:36:04 +00:00
/* Spray off search requests to all backends */
2007-01-17 16:55:37 +00:00
ret = ldb_next_request ( backend , req ) ;
2006-07-17 22:36:04 +00:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2007-01-17 16:55:37 +00:00
2006-07-29 01:13:53 +00:00
ac - > num_requests + + ;
2006-07-17 22:36:04 +00:00
return LDB_SUCCESS ;
}
2006-07-29 01:13:53 +00:00
/* Send a request down to all the partitions */
static int partition_send_all ( struct ldb_module * module ,
2007-03-13 00:59:06 +00:00
struct partition_context * ac ,
struct ldb_control * remove_control ,
struct ldb_request * req )
2006-07-29 01:13:53 +00:00
{
int i ;
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
2007-03-13 00:59:06 +00:00
int ret = partition_send_request ( ac , remove_control , NULL ) ;
2006-07-29 01:13:53 +00:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
2007-03-13 00:59:06 +00:00
ret = partition_send_request ( ac , remove_control , data - > partitions [ i ] ) ;
2006-07-29 01:13:53 +00:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
return LDB_SUCCESS ;
}
/* Figure out which backend a request needs to be aimed at. Some
* requests must be replicated to all backends */
2006-11-22 00:59:34 +00:00
static int partition_replicate ( struct ldb_module * module , struct ldb_request * req , struct ldb_dn * dn )
2006-07-29 01:13:53 +00:00
{
2007-01-17 16:11:46 +00:00
unsigned i ;
int ret ;
2007-01-17 14:19:06 +00:00
struct dsdb_control_current_partition * partition ;
2006-07-29 01:13:53 +00:00
struct ldb_module * backend ;
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
2007-03-13 00:59:06 +00:00
if ( req - > operation ! = LDB_SEARCH ) {
/* Is this a special DN, we need to replicate to every backend? */
for ( i = 0 ; data - > replicate & & data - > replicate [ i ] ; i + + ) {
if ( ldb_dn_compare ( data - > replicate [ i ] ,
dn ) = = 0 ) {
struct partition_context * ac ;
ac = partition_init_handle ( req , module ) ;
if ( ! ac ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
return partition_send_all ( module , ac , NULL , req ) ;
2006-07-29 01:13:53 +00:00
}
}
}
2007-01-17 14:19:06 +00:00
/* Otherwise, we need to find the partition to fire it to */
/* Find partition */
partition = find_partition ( data , dn ) ;
if ( ! partition ) {
/*
* if we haven ' t found a matching partition
* pass the request to the main ldb
*
* TODO : we should maybe return an error here
* if it ' s not a special dn
*/
return ldb_next_request ( module , req ) ;
}
backend = make_module_for_next_request ( req , module - > ldb , partition - > module ) ;
if ( ! backend ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2006-07-29 01:13:53 +00:00
2007-01-17 16:11:46 +00:00
ret = ldb_request_add_control ( req , DSDB_CONTROL_CURRENT_PARTITION_OID , false , partition ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2006-07-29 01:13:53 +00:00
/* issue request */
return ldb_next_request ( backend , req ) ;
}
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
/* search */
static int partition_search ( struct ldb_module * module , struct ldb_request * req )
{
/* Find backend */
2006-07-17 22:36:04 +00:00
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
/* issue request */
/* (later) consider if we should be searching multiple
* partitions ( for ' invisible ' partition behaviour */
2007-02-22 01:54:40 +00:00
struct ldb_control * search_control = ldb_request_get_control ( req , LDB_CONTROL_SEARCH_OPTIONS_OID ) ;
struct ldb_search_options_control * search_options = NULL ;
if ( search_control ) {
search_options = talloc_get_type ( search_control - > data , struct ldb_search_options_control ) ;
}
if ( search_options & & ( search_options - > search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT ) ) {
2006-07-17 22:36:04 +00:00
int ret , i ;
2006-07-22 16:56:33 +00:00
struct partition_context * ac ;
2007-03-13 00:59:06 +00:00
struct ldb_control * remove_control = NULL ;
if ( ( search_options - > search_options & ~ LDB_SEARCH_OPTION_PHANTOM_ROOT ) = = 0 ) {
/* We have processed this flag, so we are done with this control now */
remove_control = search_control ;
}
2007-01-11 09:38:21 +00:00
ac = partition_init_handle ( req , module ) ;
if ( ! ac ) {
2006-07-17 22:36:04 +00:00
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-01-11 09:38:21 +00:00
2006-09-14 03:15:30 +00:00
/* Search from the base DN */
2006-11-22 00:59:34 +00:00
if ( ! req - > op . search . base | | ldb_dn_is_null ( req - > op . search . base ) ) {
2007-03-13 00:59:06 +00:00
return partition_send_all ( module , ac , remove_control , req ) ;
2006-09-14 03:15:30 +00:00
}
2006-07-17 22:36:04 +00:00
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
/* Find all partitions under the search base */
2006-11-23 22:06:07 +00:00
if ( ldb_dn_compare_base ( req - > op . search . base , data - > partitions [ i ] - > dn ) = = 0 ) {
2007-03-13 00:59:06 +00:00
ret = partition_send_request ( ac , remove_control , data - > partitions [ i ] ) ;
2006-07-17 22:36:04 +00:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
}
2006-09-14 03:15:30 +00:00
/* Perhaps we didn't match any partitions. Try the main partition, only */
2006-07-29 01:13:53 +00:00
if ( ac - > num_requests = = 0 ) {
2007-01-11 09:38:21 +00:00
talloc_free ( ac ) ;
2006-09-14 03:15:30 +00:00
return ldb_next_request ( module , req ) ;
2006-07-17 22:36:04 +00:00
}
return LDB_SUCCESS ;
} else {
2007-03-13 00:59:06 +00:00
/* Handle this like all other requests */
return partition_replicate ( module , req , req - > op . search . base ) ;
2006-07-17 22:36:04 +00:00
}
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* add */
static int partition_add ( struct ldb_module * module , struct ldb_request * req )
{
2006-07-29 01:13:53 +00:00
return partition_replicate ( module , req , req - > op . add . message - > dn ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* modify */
static int partition_modify ( struct ldb_module * module , struct ldb_request * req )
{
2006-07-29 01:13:53 +00:00
return partition_replicate ( module , req , req - > op . mod . message - > dn ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* delete */
static int partition_delete ( struct ldb_module * module , struct ldb_request * req )
{
2006-07-29 01:13:53 +00:00
return partition_replicate ( module , req , req - > op . del . dn ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* rename */
static int partition_rename ( struct ldb_module * module , struct ldb_request * req )
{
/* Find backend */
struct ldb_module * backend = find_backend ( module , req , req - > op . rename . olddn ) ;
struct ldb_module * backend2 = find_backend ( module , req , req - > op . rename . newdn ) ;
if ( backend - > next ! = backend2 - > next ) {
return LDB_ERR_AFFECTS_MULTIPLE_DSAS ;
}
2006-07-29 01:13:53 +00:00
return partition_replicate ( module , req , req - > op . rename . olddn ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* start a transaction */
static int partition_start_trans ( struct ldb_module * module )
{
2006-07-10 11:24:46 +00:00
int i , ret ;
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
/* Look at base DN */
/* Figure out which partition it is under */
/* Skip the lot if 'data' isn't here yet (initialistion) */
ret = ldb_next_start_trans ( module ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
struct ldb_module * next = make_module_for_next_request ( module , module - > ldb , data - > partitions [ i ] - > module ) ;
ret = ldb_next_start_trans ( next ) ;
talloc_free ( next ) ;
if ( ret ! = LDB_SUCCESS ) {
/* Back it out, if it fails on one */
for ( i - - ; i > = 0 ; i - - ) {
next = make_module_for_next_request ( module , module - > ldb , data - > partitions [ i ] - > module ) ;
ldb_next_del_trans ( next ) ;
talloc_free ( next ) ;
}
return ret ;
}
}
return LDB_SUCCESS ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* end a transaction */
static int partition_end_trans ( struct ldb_module * module )
{
2006-07-10 11:24:46 +00:00
int i , ret , ret2 = LDB_SUCCESS ;
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
ret = ldb_next_end_trans ( module ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
/* Look at base DN */
/* Figure out which partition it is under */
/* Skip the lot if 'data' isn't here yet (initialistion) */
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
struct ldb_module * next = make_module_for_next_request ( module , module - > ldb , data - > partitions [ i ] - > module ) ;
ret = ldb_next_end_trans ( next ) ;
talloc_free ( next ) ;
if ( ret ! = LDB_SUCCESS ) {
ret2 = ret ;
}
}
if ( ret ! = LDB_SUCCESS ) {
/* Back it out, if it fails on one */
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
struct ldb_module * next = make_module_for_next_request ( module , module - > ldb , data - > partitions [ i ] - > module ) ;
ldb_next_del_trans ( next ) ;
talloc_free ( next ) ;
}
}
return ret ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
/* delete a transaction */
static int partition_del_trans ( struct ldb_module * module )
{
2006-07-10 11:24:46 +00:00
int i , ret , ret2 = LDB_SUCCESS ;
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
2006-07-11 02:04:43 +00:00
ret = ldb_next_del_trans ( module ) ;
if ( ret ! = LDB_SUCCESS ) {
ret2 = ret ;
}
2006-07-10 11:24:46 +00:00
/* Look at base DN */
/* Figure out which partition it is under */
/* Skip the lot if 'data' isn't here yet (initialistion) */
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
struct ldb_module * next = make_module_for_next_request ( module , module - > ldb , data - > partitions [ i ] - > module ) ;
ret = ldb_next_del_trans ( next ) ;
talloc_free ( next ) ;
if ( ret ! = LDB_SUCCESS ) {
ret2 = ret ;
}
}
return ret2 ;
}
static int partition_sequence_number ( struct ldb_module * module , struct ldb_request * req )
{
int i , ret ;
uint64_t seq_number = 0 ;
2006-09-21 06:44:12 +00:00
uint64_t timestamp_sequence = 0 ;
uint64_t timestamp = 0 ;
2006-07-10 11:24:46 +00:00
struct partition_private_data * data = talloc_get_type ( module - > private_data ,
struct partition_private_data ) ;
2006-07-11 02:04:43 +00:00
2006-09-21 06:44:12 +00:00
switch ( req - > op . seq_num . type ) {
case LDB_SEQ_NEXT :
case LDB_SEQ_HIGHEST_SEQ :
ret = ldb_next_request ( module , req ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
if ( req - > op . seq_num . flags & LDB_SEQ_TIMESTAMP_SEQUENCE ) {
timestamp_sequence = req - > op . seq_num . seq_num ;
} else {
seq_number = seq_number + req - > op . seq_num . seq_num ;
}
/* Look at base DN */
/* Figure out which partition it is under */
/* Skip the lot if 'data' isn't here yet (initialistion) */
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
struct ldb_module * next = make_module_for_next_request ( req , module - > ldb , data - > partitions [ i ] - > module ) ;
ret = ldb_next_request ( next , req ) ;
talloc_free ( next ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
if ( req - > op . seq_num . flags & LDB_SEQ_TIMESTAMP_SEQUENCE ) {
timestamp_sequence = MAX ( timestamp_sequence , req - > op . seq_num . seq_num ) ;
} else {
seq_number = seq_number + req - > op . seq_num . seq_num ;
}
}
/* fall though */
case LDB_SEQ_HIGHEST_TIMESTAMP :
{
struct ldb_request * date_req = talloc ( req , struct ldb_request ) ;
if ( ! date_req ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
* date_req = * req ;
date_req - > op . seq_num . flags = LDB_SEQ_HIGHEST_TIMESTAMP ;
ret = ldb_next_request ( module , date_req ) ;
2006-07-10 11:24:46 +00:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
2006-09-21 06:44:12 +00:00
timestamp = date_req - > op . seq_num . seq_num ;
/* Look at base DN */
/* Figure out which partition it is under */
/* Skip the lot if 'data' isn't here yet (initialistion) */
for ( i = 0 ; data & & data - > partitions & & data - > partitions [ i ] ; i + + ) {
struct ldb_module * next = make_module_for_next_request ( req , module - > ldb , data - > partitions [ i ] - > module ) ;
ret = ldb_next_request ( next , date_req ) ;
talloc_free ( next ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
timestamp = MAX ( timestamp , date_req - > op . seq_num . seq_num ) ;
}
break ;
}
}
switch ( req - > op . seq_num . flags ) {
case LDB_SEQ_NEXT :
case LDB_SEQ_HIGHEST_SEQ :
req - > op . seq_num . flags = 0 ;
/* Has someone above set a timebase sequence? */
if ( timestamp_sequence ) {
req - > op . seq_num . seq_num = ( ( ( unsigned long long ) timestamp < < 24 ) | ( seq_number & 0xFFFFFF ) ) ;
} else {
req - > op . seq_num . seq_num = seq_number ;
}
if ( timestamp_sequence > req - > op . seq_num . seq_num ) {
req - > op . seq_num . seq_num = timestamp_sequence ;
req - > op . seq_num . flags | = LDB_SEQ_TIMESTAMP_SEQUENCE ;
}
req - > op . seq_num . flags | = LDB_SEQ_GLOBAL_SEQUENCE ;
break ;
case LDB_SEQ_HIGHEST_TIMESTAMP :
req - > op . seq_num . seq_num = timestamp ;
break ;
}
switch ( req - > op . seq_num . flags ) {
case LDB_SEQ_NEXT :
req - > op . seq_num . seq_num + + ;
2006-07-10 11:24:46 +00:00
}
return LDB_SUCCESS ;
}
2007-01-07 19:11:27 +00:00
static int partition_extended_replicated_objects ( struct ldb_module * module , struct ldb_request * req )
{
struct dsdb_extended_replicated_objects * ext ;
ext = talloc_get_type ( req - > op . extended . data , struct dsdb_extended_replicated_objects ) ;
if ( ! ext ) {
2007-01-13 11:37:13 +00:00
ldb_debug ( module - > ldb , LDB_DEBUG_FATAL , " partition_extended_replicated_objects: invalid extended data \n " ) ;
return LDB_ERR_PROTOCOL_ERROR ;
}
if ( ext - > version ! = DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION ) {
ldb_debug ( module - > ldb , LDB_DEBUG_FATAL , " partition_extended_replicated_objects: extended data invalid version [%u != %u] \n " ,
ext - > version , DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION ) ;
return LDB_ERR_PROTOCOL_ERROR ;
2007-01-07 19:11:27 +00:00
}
return partition_replicate ( module , req , ext - > partition_dn ) ;
}
/* extended */
static int partition_extended ( struct ldb_module * module , struct ldb_request * req )
{
struct partition_context * ac ;
if ( strcmp ( req - > op . extended . oid , DSDB_EXTENDED_REPLICATED_OBJECTS_OID ) = = 0 ) {
return partition_extended_replicated_objects ( module , req ) ;
}
/*
* as the extended operation has no dn
* we need to send it to all partitions
*/
2007-01-11 09:38:21 +00:00
ac = partition_init_handle ( req , module ) ;
if ( ! ac ) {
2007-01-07 19:11:27 +00:00
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-03-13 00:59:06 +00:00
return partition_send_all ( module , ac , NULL , req ) ;
2007-01-07 19:11:27 +00:00
}
2006-07-10 11:24:46 +00:00
static int sort_compare ( void * void1 ,
void * void2 , void * opaque )
{
2007-01-15 17:53:53 +00:00
struct dsdb_control_current_partition * * pp1 = void1 ;
struct dsdb_control_current_partition * * pp2 = void2 ;
struct dsdb_control_current_partition * partition1 = talloc_get_type ( * pp1 ,
struct dsdb_control_current_partition ) ;
struct dsdb_control_current_partition * partition2 = talloc_get_type ( * pp2 ,
struct dsdb_control_current_partition ) ;
2006-07-10 11:24:46 +00:00
2006-11-22 00:59:34 +00:00
return ldb_dn_compare ( partition1 - > dn , partition2 - > dn ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
}
2007-04-28 15:18:25 +00:00
static const char * relative_path ( struct ldb_module * module ,
TALLOC_CTX * mem_ctx ,
const char * name )
{
const char * base_url = ldb_get_opaque ( module - > ldb , " ldb_url " ) ;
char * path , * p , * full_name ;
if ( name = = NULL ) {
return NULL ;
}
if ( name [ 0 ] = = 0 | | name [ 0 ] = = ' / ' | | strstr ( name , " :/ " ) ) {
return talloc_strdup ( mem_ctx , name ) ;
}
path = talloc_strdup ( mem_ctx , base_url ) ;
if ( path = = NULL ) {
return NULL ;
}
if ( ( p = strrchr ( path , ' / ' ) ) ! = NULL ) {
p [ 0 ] = ' \0 ' ;
} else {
talloc_free ( path ) ;
return NULL ;
}
full_name = talloc_asprintf ( mem_ctx , " %s/%s " , path , name ) ;
talloc_free ( path ) ;
return full_name ;
}
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
static int partition_init ( struct ldb_module * module )
{
int ret , i ;
TALLOC_CTX * mem_ctx = talloc_new ( module ) ;
2006-08-10 01:51:27 +00:00
static const char * attrs [ ] = { " partition " , " replicateEntries " , " modules " , NULL } ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
struct ldb_result * res ;
struct ldb_message * msg ;
struct ldb_message_element * partition_attributes ;
2006-07-29 01:13:53 +00:00
struct ldb_message_element * replicate_attributes ;
2006-08-10 01:51:27 +00:00
struct ldb_message_element * modules_attributes ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
struct partition_private_data * data ;
if ( ! mem_ctx ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
data = talloc ( mem_ctx , struct partition_private_data ) ;
if ( data = = NULL ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2006-11-22 00:59:34 +00:00
ret = ldb_search ( module - > ldb , ldb_dn_new ( mem_ctx , module - > ldb , " @PARTITION " ) ,
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
LDB_SCOPE_BASE ,
NULL , attrs ,
& res ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( mem_ctx ) ;
return ret ;
}
talloc_steal ( mem_ctx , res ) ;
if ( res - > count = = 0 ) {
talloc_free ( mem_ctx ) ;
return ldb_next_init ( module ) ;
}
if ( res - > count > 1 ) {
talloc_free ( mem_ctx ) ;
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
msg = res - > msgs [ 0 ] ;
partition_attributes = ldb_msg_find_element ( msg , " partition " ) ;
if ( ! partition_attributes ) {
2006-08-13 07:33:57 +00:00
ldb_set_errstring ( module - > ldb , " partition_init: no partitions specified " ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
2007-01-15 17:53:53 +00:00
data - > partitions = talloc_array ( data , struct dsdb_control_current_partition * , partition_attributes - > num_values + 1 ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
if ( ! data - > partitions ) {
talloc_free ( mem_ctx ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
for ( i = 0 ; i < partition_attributes - > num_values ; i + + ) {
char * base = talloc_strdup ( data - > partitions , ( char * ) partition_attributes - > values [ i ] . data ) ;
char * p = strchr ( base , ' : ' ) ;
if ( ! p ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" invalid form for partition record (missing ':'): %s " , base ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
p [ 0 ] = ' \0 ' ;
p + + ;
if ( ! p [ 0 ] ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" invalid form for partition record (missing backend database): %s " , base ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
2007-01-15 17:53:53 +00:00
data - > partitions [ i ] = talloc ( data - > partitions , struct dsdb_control_current_partition ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
if ( ! data - > partitions [ i ] ) {
talloc_free ( mem_ctx ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-01-16 10:57:55 +00:00
data - > partitions [ i ] - > version = DSDB_CONTROL_CURRENT_PARTITION_VERSION ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
2006-11-22 00:59:34 +00:00
data - > partitions [ i ] - > dn = ldb_dn_new ( data - > partitions [ i ] , module - > ldb , base ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
if ( ! data - > partitions [ i ] - > dn ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: invalid DN in partition record: %s " , base ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
2007-04-28 15:18:25 +00:00
data - > partitions [ i ] - > backend = relative_path ( module ,
data - > partitions [ i ] ,
p ) ;
2006-07-12 04:59:41 +00:00
ret = ldb_connect_backend ( module - > ldb , data - > partitions [ i ] - > backend , NULL , & data - > partitions [ i ] - > module ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
if ( ret ! = LDB_SUCCESS ) {
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return ret ;
}
2006-07-10 11:24:46 +00:00
}
data - > partitions [ i ] = NULL ;
2006-07-11 02:04:43 +00:00
/* sort these into order, most to least specific */
2006-07-10 11:24:46 +00:00
ldb_qsort ( data - > partitions , partition_attributes - > num_values , sizeof ( * data - > partitions ) ,
module - > ldb , sort_compare ) ;
for ( i = 0 ; data - > partitions [ i ] ; i + + ) {
struct ldb_request * req ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
req = talloc_zero ( mem_ctx , struct ldb_request ) ;
if ( req = = NULL ) {
ldb_debug ( module - > ldb , LDB_DEBUG_ERROR , " partition: Out of memory! \n " ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return LDB_ERR_OPERATIONS_ERROR ;
}
req - > operation = LDB_REQ_REGISTER_PARTITION ;
req - > op . reg_partition . dn = data - > partitions [ i ] - > dn ;
ret = ldb_request ( module - > ldb , req ) ;
if ( ret ! = LDB_SUCCESS ) {
ldb_debug ( module - > ldb , LDB_DEBUG_ERROR , " partition: Unable to register partition with rootdse! \n " ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
return LDB_ERR_OTHER ;
}
talloc_free ( req ) ;
}
2006-07-29 01:13:53 +00:00
replicate_attributes = ldb_msg_find_element ( msg , " replicateEntries " ) ;
if ( ! replicate_attributes ) {
data - > replicate = NULL ;
} else {
data - > replicate = talloc_array ( data , struct ldb_dn * , replicate_attributes - > num_values + 1 ) ;
if ( ! data - > replicate ) {
talloc_free ( mem_ctx ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
for ( i = 0 ; i < replicate_attributes - > num_values ; i + + ) {
2006-11-22 00:59:34 +00:00
data - > replicate [ i ] = ldb_dn_new ( data - > replicate , module - > ldb , ( const char * ) replicate_attributes - > values [ i ] . data ) ;
if ( ! ldb_dn_validate ( data - > replicate [ i ] ) ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" invalid DN in partition replicate record: %s " ,
replicate_attributes - > values [ i ] . data ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
2006-07-29 01:13:53 +00:00
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
}
data - > replicate [ i ] = NULL ;
}
2006-08-22 10:05:20 +00:00
/* Make the private data available to any searches the modules may trigger in initialisation */
module - > private_data = data ;
talloc_steal ( module , data ) ;
2006-08-10 01:51:27 +00:00
modules_attributes = ldb_msg_find_element ( msg , " modules " ) ;
if ( modules_attributes ) {
for ( i = 0 ; i < modules_attributes - > num_values ; i + + ) {
struct ldb_dn * base_dn ;
int partition_idx ;
2007-01-15 17:53:53 +00:00
struct dsdb_control_current_partition * partition = NULL ;
2006-08-10 01:51:27 +00:00
const char * * modules = NULL ;
char * base = talloc_strdup ( data - > partitions , ( char * ) modules_attributes - > values [ i ] . data ) ;
char * p = strchr ( base , ' : ' ) ;
if ( ! p ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" invalid form for partition module record (missing ':'): %s " , base ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
p [ 0 ] = ' \0 ' ;
p + + ;
if ( ! p [ 0 ] ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" invalid form for partition module record (missing backend database): %s " , base ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
modules = ldb_modules_list_from_string ( module - > ldb , mem_ctx ,
p ) ;
2006-11-22 00:59:34 +00:00
base_dn = ldb_dn_new ( mem_ctx , module - > ldb , base ) ;
if ( ! ldb_dn_validate ( base_dn ) ) {
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
for ( partition_idx = 0 ; data - > partitions [ partition_idx ] ; partition_idx + + ) {
2006-11-23 22:06:07 +00:00
if ( ldb_dn_compare ( data - > partitions [ partition_idx ] - > dn , base_dn ) = = 0 ) {
2006-08-10 01:51:27 +00:00
partition = data - > partitions [ partition_idx ] ;
break ;
}
}
if ( ! partition ) {
2006-08-13 07:33:57 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" invalid form for partition module record (no such partition): %s " , base ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
return LDB_ERR_CONSTRAINT_VIOLATION ;
}
ret = ldb_load_modules_list ( module - > ldb , modules , partition - > module , & partition - > module ) ;
if ( ret ! = LDB_SUCCESS ) {
2006-09-14 03:15:30 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" loading backend for %s failed: %s " ,
base , ldb_errstring ( module - > ldb ) ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
return ret ;
}
ret = ldb_init_module_chain ( module - > ldb , partition - > module ) ;
if ( ret ! = LDB_SUCCESS ) {
2006-09-14 03:15:30 +00:00
ldb_asprintf_errstring ( module - > ldb ,
" partition_init: "
" initialising backend for %s failed: %s " ,
base , ldb_errstring ( module - > ldb ) ) ;
2006-08-10 01:51:27 +00:00
talloc_free ( mem_ctx ) ;
return ret ;
}
}
}
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
talloc_free ( mem_ctx ) ;
return ldb_next_init ( module ) ;
}
2006-07-22 16:56:33 +00:00
static int partition_wait_none ( struct ldb_handle * handle ) {
struct partition_context * ac ;
2006-07-17 22:36:04 +00:00
int ret ;
int i ;
if ( ! handle | | ! handle - > private_data ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
if ( handle - > state = = LDB_ASYNC_DONE ) {
return handle - > status ;
}
handle - > state = LDB_ASYNC_PENDING ;
handle - > status = LDB_SUCCESS ;
2006-07-22 16:56:33 +00:00
ac = talloc_get_type ( handle - > private_data , struct partition_context ) ;
2006-07-17 22:36:04 +00:00
2006-07-29 01:13:53 +00:00
for ( i = 0 ; i < ac - > num_requests ; i + + ) {
ret = ldb_wait ( ac - > down_req [ i ] - > handle , LDB_WAIT_NONE ) ;
2006-07-17 22:36:04 +00:00
if ( ret ! = LDB_SUCCESS ) {
handle - > status = ret ;
goto done ;
}
2006-07-29 01:13:53 +00:00
if ( ac - > down_req [ i ] - > handle - > status ! = LDB_SUCCESS ) {
handle - > status = ac - > down_req [ i ] - > handle - > status ;
2006-07-17 22:36:04 +00:00
goto done ;
}
2006-07-29 01:13:53 +00:00
if ( ac - > down_req [ i ] - > handle - > state ! = LDB_ASYNC_DONE ) {
2006-07-17 22:36:04 +00:00
return LDB_SUCCESS ;
}
}
ret = LDB_SUCCESS ;
done :
handle - > state = LDB_ASYNC_DONE ;
return ret ;
}
2006-07-22 16:56:33 +00:00
static int partition_wait_all ( struct ldb_handle * handle ) {
2006-07-17 22:36:04 +00:00
int ret ;
while ( handle - > state ! = LDB_ASYNC_DONE ) {
2006-07-22 16:56:33 +00:00
ret = partition_wait_none ( handle ) ;
2006-07-17 22:36:04 +00:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
return handle - > status ;
}
2006-07-22 16:56:33 +00:00
static int partition_wait ( struct ldb_handle * handle , enum ldb_wait_type type )
2006-07-17 22:36:04 +00:00
{
if ( type = = LDB_WAIT_ALL ) {
2006-07-22 16:56:33 +00:00
return partition_wait_all ( handle ) ;
2006-07-17 22:36:04 +00:00
} else {
2006-07-22 16:56:33 +00:00
return partition_wait_none ( handle ) ;
2006-07-17 22:36:04 +00:00
}
}
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
static const struct ldb_module_ops partition_ops = {
. name = " partition " ,
. init_context = partition_init ,
. search = partition_search ,
. add = partition_add ,
. modify = partition_modify ,
. del = partition_delete ,
. rename = partition_rename ,
2007-01-07 19:11:27 +00:00
. extended = partition_extended ,
. sequence_number = partition_sequence_number ,
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
. start_transaction = partition_start_trans ,
. end_transaction = partition_end_trans ,
. del_transaction = partition_del_trans ,
2006-07-22 16:56:33 +00:00
. wait = partition_wait
r16264: Add, but do not yet enable, the partitions module.
This required changes to the rootDSE module, to allow registration of
partitions. In doing so I renamed the 'register' operation to
'register_control' and 'register_partition', which changed a few more
modules.
Due to the behaviour of certain LDAP servers, we create the baseDN
entry in two parts: Firstly, we allow the admin to export a simple
LDIF file to add to their server. Then we perform a modify to add the
remaining attributes.
To delete all users in partitions, we must now search and delete all
objects in the partition, rather than a simple search from the root.
Against LDAP, this might not delete all objects, so we allow this to
fail.
In testing, we found that the 'Domain Controllers' container was
misnamed, and should be 'CN=', rather than 'OU='.
To avoid the Templates being found in default searches, they have been
moved to CN=Templates from CN=Templates,${BASEDN}.
Andrew Bartlett
(This used to be commit b49a4fbb57f10726bd288fdc9fc95c0cbbe9094a)
2006-06-15 18:04:24 +00:00
} ;
int ldb_partition_init ( void )
{
return ldb_register_module ( & partition_ops ) ;
}