2004-09-22 14:16:42 +00:00
/*
Unix SMB / CIFS implementation .
LDAP server SIMPLE LDB implementation
Copyright ( C ) Stefan Metzmacher 2004
2004-10-09 16:38:18 +00:00
Copyright ( C ) Simo Sorce 2004
2004-09-22 14:16:42 +00:00
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 .
*/
# include "includes.h"
2004-11-02 06:52:59 +00:00
# include "ldap_server/ldap_server.h"
2005-11-08 00:11:45 +00:00
# include "lib/ldb/include/ldb_errors.h"
2005-12-28 15:38:36 +00:00
# include "dsdb/samdb/samdb.h"
2004-09-22 14:16:42 +00:00
2004-10-20 23:12:30 +00:00
# define VALID_DN_SYNTAX(dn,i) do {\
if ( ! ( dn ) ) { \
return NT_STATUS_NO_MEMORY ; \
} else if ( ( dn ) - > comp_num < ( i ) ) { \
result = LDAP_INVALID_DN_SYNTAX ; \
2004-10-20 23:25:39 +00:00
errstr = " Invalid DN ( " # i " components needed for ' " # dn " ') " ; \
2004-10-20 23:12:30 +00:00
goto reply ; \
} \
} while ( 0 )
2004-09-28 10:44:44 +00:00
2005-10-31 03:05:26 +00:00
/*
map an error code from ldb to ldap
*/
static int sldb_map_error ( struct ldapsrv_partition * partition , int ldb_ret ,
const char * * errstr )
{
struct ldb_context * samdb = talloc_get_type ( partition - > private ,
struct ldb_context ) ;
* errstr = ldb_errstring ( samdb ) ;
/* its 1:1 for now */
return ldb_ret ;
}
2005-10-07 11:31:45 +00:00
/*
connect to the sam database
*/
NTSTATUS sldb_Init ( struct ldapsrv_partition * partition , struct ldapsrv_connection * conn )
{
TALLOC_CTX * mem_ctx = talloc_new ( partition ) ;
struct ldb_context * ldb ;
ldb = samdb_connect ( mem_ctx , conn - > session_info ) ;
if ( ldb = = NULL ) {
talloc_free ( mem_ctx ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
talloc_steal ( partition , ldb ) ;
partition - > private = ldb ;
talloc_free ( mem_ctx ) ;
return NT_STATUS_OK ;
}
/*
Re - connect to the ldb after a bind ( this does not handle the bind
itself , but just notes the change in credentials )
*/
NTSTATUS sldb_Bind ( struct ldapsrv_partition * partition , struct ldapsrv_connection * conn )
{
struct ldb_context * samdb = partition - > private ;
NTSTATUS status ;
status = sldb_Init ( partition , conn ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
/* don't leak the old LDB */
talloc_free ( samdb ) ;
}
return status ;
}
2004-09-22 14:16:42 +00:00
static NTSTATUS sldb_Search ( struct ldapsrv_partition * partition , struct ldapsrv_call * call ,
2005-10-07 11:31:45 +00:00
struct ldap_SearchRequest * r )
2004-09-22 14:16:42 +00:00
{
2004-10-04 21:02:00 +00:00
void * local_ctx ;
2005-08-18 15:02:01 +00:00
struct ldb_dn * basedn ;
2004-09-22 14:16:42 +00:00
struct ldap_Result * done ;
2004-09-27 08:52:31 +00:00
struct ldap_SearchResEntry * ent ;
struct ldapsrv_reply * ent_r , * done_r ;
2004-10-20 23:12:30 +00:00
int result = LDAP_SUCCESS ;
2005-02-27 11:35:47 +00:00
struct ldb_context * samdb ;
2005-11-08 00:11:45 +00:00
struct ldb_result * res = NULL ;
int i , j , y , ret ;
2005-07-08 05:04:57 +00:00
int success_limit = 1 ;
2004-09-27 08:52:31 +00:00
enum ldb_scope scope = LDB_SCOPE_DEFAULT ;
2004-09-27 13:20:59 +00:00
const char * * attrs = NULL ;
2004-10-20 23:12:30 +00:00
const char * errstr = NULL ;
2005-11-08 00:11:45 +00:00
struct ldb_request lreq ;
2004-09-22 14:16:42 +00:00
2004-10-04 21:02:00 +00:00
local_ctx = talloc_named ( call , 0 , " sldb_Search local memory context " ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( local_ctx ) ;
2004-10-04 21:02:00 +00:00
2005-10-07 12:30:46 +00:00
samdb = talloc_get_type ( partition - > private , struct ldb_context ) ;
2004-09-28 10:44:44 +00:00
2005-08-18 15:02:01 +00:00
basedn = ldb_dn_explode ( local_ctx , r - > basedn ) ;
VALID_DN_SYNTAX ( basedn , 0 ) ;
2004-10-04 21:02:00 +00:00
2005-08-18 15:02:01 +00:00
DEBUG ( 10 , ( " sldb_Search: basedn: [%s] \n " , r - > basedn ) ) ;
2005-06-13 09:10:17 +00:00
DEBUG ( 10 , ( " sldb_Search: filter: [%s] \n " , ldb_filter_from_tree ( call , r - > tree ) ) ) ;
2004-09-27 08:52:31 +00:00
switch ( r - > scope ) {
case LDAP_SEARCH_SCOPE_BASE :
2004-09-27 15:11:42 +00:00
DEBUG ( 10 , ( " sldb_Search: scope: [BASE] \n " ) ) ;
2004-09-27 08:52:31 +00:00
scope = LDB_SCOPE_BASE ;
2005-08-18 15:02:01 +00:00
success_limit = 0 ;
2004-09-27 08:52:31 +00:00
break ;
case LDAP_SEARCH_SCOPE_SINGLE :
2004-09-27 15:11:42 +00:00
DEBUG ( 10 , ( " sldb_Search: scope: [ONE] \n " ) ) ;
2004-09-27 08:52:31 +00:00
scope = LDB_SCOPE_ONELEVEL ;
2005-07-08 05:04:57 +00:00
success_limit = 0 ;
2004-09-27 08:52:31 +00:00
break ;
case LDAP_SEARCH_SCOPE_SUB :
2004-09-27 15:11:42 +00:00
DEBUG ( 10 , ( " sldb_Search: scope: [SUB] \n " ) ) ;
2004-09-27 08:52:31 +00:00
scope = LDB_SCOPE_SUBTREE ;
2005-07-08 05:04:57 +00:00
success_limit = 0 ;
2004-09-27 08:52:31 +00:00
break ;
}
2004-09-27 13:20:59 +00:00
if ( r - > num_attributes > = 1 ) {
2005-01-27 07:08:20 +00:00
attrs = talloc_array ( samdb , const char * , r - > num_attributes + 1 ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( attrs ) ;
2004-09-27 13:20:59 +00:00
for ( i = 0 ; i < r - > num_attributes ; i + + ) {
2004-09-27 15:11:42 +00:00
DEBUG ( 10 , ( " sldb_Search: attrs: [%s] \n " , r - > attributes [ i ] ) ) ;
2004-09-27 13:20:59 +00:00
attrs [ i ] = r - > attributes [ i ] ;
}
attrs [ i ] = NULL ;
}
2005-11-08 00:11:45 +00:00
DEBUG ( 5 , ( " ldb_request dn=%s filter=%s \n " ,
2005-08-18 15:02:01 +00:00
r - > basedn , ldb_filter_from_tree ( call , r - > tree ) ) ) ;
2005-06-15 00:27:51 +00:00
2005-11-08 00:11:45 +00:00
ZERO_STRUCT ( lreq ) ;
lreq . operation = LDB_REQ_SEARCH ;
lreq . op . search . base = basedn ;
lreq . op . search . scope = scope ;
lreq . op . search . tree = r - > tree ;
lreq . op . search . attrs = attrs ;
2004-09-27 08:52:31 +00:00
2005-11-08 00:11:45 +00:00
ret = ldb_request ( samdb , & lreq ) ;
2005-11-29 12:34:03 +00:00
res = talloc_steal ( samdb , lreq . op . search . res ) ;
2004-09-27 08:52:31 +00:00
2005-11-08 00:11:45 +00:00
if ( ret = = LDB_SUCCESS ) {
for ( i = 0 ; i < res - > count ; i + + ) {
ent_r = ldapsrv_init_reply ( call , LDAP_TAG_SearchResultEntry ) ;
NT_STATUS_HAVE_NO_MEMORY ( ent_r ) ;
ent = & ent_r - > msg - > r . SearchResultEntry ;
ent - > dn = ldb_dn_linearize ( ent_r , res - > msgs [ i ] - > dn ) ;
ent - > num_attributes = 0 ;
ent - > attributes = NULL ;
if ( res - > msgs [ i ] - > num_elements = = 0 ) {
goto queue_reply ;
2004-09-27 08:52:31 +00:00
}
2005-11-08 00:11:45 +00:00
ent - > num_attributes = res - > msgs [ i ] - > num_elements ;
ent - > attributes = talloc_array ( ent_r , struct ldb_message_element , ent - > num_attributes ) ;
NT_STATUS_HAVE_NO_MEMORY ( ent - > attributes ) ;
for ( j = 0 ; j < ent - > num_attributes ; j + + ) {
ent - > attributes [ j ] . name = talloc_steal ( ent - > attributes , res - > msgs [ i ] - > elements [ j ] . name ) ;
ent - > attributes [ j ] . num_values = 0 ;
ent - > attributes [ j ] . values = NULL ;
if ( r - > attributesonly & & ( res - > msgs [ i ] - > elements [ j ] . num_values = = 0 ) ) {
continue ;
}
ent - > attributes [ j ] . num_values = res - > msgs [ i ] - > elements [ j ] . num_values ;
ent - > attributes [ j ] . values = talloc_array ( ent - > attributes ,
DATA_BLOB , ent - > attributes [ j ] . num_values ) ;
NT_STATUS_HAVE_NO_MEMORY ( ent - > attributes [ j ] . values ) ;
for ( y = 0 ; y < ent - > attributes [ j ] . num_values ; y + + ) {
ent - > attributes [ j ] . values [ y ] . length = res - > msgs [ i ] - > elements [ j ] . values [ y ] . length ;
ent - > attributes [ j ] . values [ y ] . data = talloc_steal ( ent - > attributes [ j ] . values ,
res - > msgs [ i ] - > elements [ j ] . values [ y ] . data ) ;
}
2004-09-27 08:52:31 +00:00
}
2004-09-27 15:11:42 +00:00
queue_reply :
2005-11-08 00:11:45 +00:00
ldapsrv_queue_reply ( call , ent_r ) ;
}
2004-09-27 08:52:31 +00:00
}
2004-10-20 23:12:30 +00:00
reply :
2004-09-22 14:16:42 +00:00
done_r = ldapsrv_init_reply ( call , LDAP_TAG_SearchResultDone ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( done_r ) ;
2004-09-22 14:16:42 +00:00
2005-11-08 00:11:45 +00:00
if ( ret = = LDB_SUCCESS ) {
if ( res - > count > = success_limit ) {
DEBUG ( 10 , ( " sldb_Search: results: [%d] \n " , res - > count ) ) ;
2004-10-20 23:12:30 +00:00
result = LDAP_SUCCESS ;
errstr = NULL ;
2005-11-08 00:11:45 +00:00
} else if ( res - > count = = 0 ) {
2004-10-20 23:12:30 +00:00
DEBUG ( 10 , ( " sldb_Search: no results \n " ) ) ;
result = LDAP_NO_SUCH_OBJECT ;
2005-02-27 11:35:47 +00:00
errstr = ldb_errstring ( samdb ) ;
2004-10-20 23:12:30 +00:00
}
2005-11-08 00:11:45 +00:00
} else {
DEBUG ( 10 , ( " sldb_Search: error \n " ) ) ;
result = ret ;
errstr = ldb_errstring ( samdb ) ;
2004-09-28 10:44:44 +00:00
}
2005-06-15 00:27:51 +00:00
done = & done_r - > msg - > r . SearchResultDone ;
2004-09-22 14:16:42 +00:00
done - > dn = NULL ;
2004-10-20 23:12:30 +00:00
done - > resultcode = result ;
2005-11-08 00:11:45 +00:00
done - > errormessage = ( errstr ? talloc_strdup ( done_r , errstr ) : NULL ) ;
2004-09-22 14:16:42 +00:00
done - > referral = NULL ;
2004-10-04 21:02:00 +00:00
talloc_free ( local_ctx ) ;
2004-09-28 10:44:44 +00:00
2005-06-19 09:31:34 +00:00
ldapsrv_queue_reply ( call , done_r ) ;
return NT_STATUS_OK ;
2004-09-22 14:16:42 +00:00
}
2004-09-28 10:44:44 +00:00
static NTSTATUS sldb_Add ( struct ldapsrv_partition * partition , struct ldapsrv_call * call ,
2005-10-31 03:05:26 +00:00
struct ldap_AddRequest * r )
2004-09-28 10:44:44 +00:00
{
2004-10-04 21:02:00 +00:00
void * local_ctx ;
2005-08-18 15:02:01 +00:00
struct ldb_dn * dn ;
2004-09-28 10:44:44 +00:00
struct ldap_Result * add_result ;
struct ldapsrv_reply * add_reply ;
int ldb_ret ;
2005-02-27 11:35:47 +00:00
struct ldb_context * samdb ;
2004-12-02 04:51:56 +00:00
struct ldb_message * msg = NULL ;
2004-09-28 10:44:44 +00:00
int result = LDAP_SUCCESS ;
const char * errstr = NULL ;
int i , j ;
2004-10-04 21:02:00 +00:00
local_ctx = talloc_named ( call , 0 , " sldb_Add local memory context " ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( local_ctx ) ;
2004-10-04 21:02:00 +00:00
2005-10-07 12:30:46 +00:00
samdb = talloc_get_type ( partition - > private , struct ldb_context ) ;
2004-10-04 21:02:00 +00:00
2005-08-18 15:02:01 +00:00
dn = ldb_dn_explode ( local_ctx , r - > dn ) ;
2004-10-20 23:25:39 +00:00
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-09-28 10:44:44 +00:00
2005-08-18 15:02:01 +00:00
DEBUG ( 10 , ( " sldb_add: dn: [%s] \n " , r - > dn ) ) ;
2004-09-28 10:44:44 +00:00
2005-01-27 07:08:20 +00:00
msg = talloc ( local_ctx , struct ldb_message ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( msg ) ;
2004-09-28 10:44:44 +00:00
2005-08-18 15:02:01 +00:00
msg - > dn = dn ;
2004-09-28 10:44:44 +00:00
msg - > private_data = NULL ;
msg - > num_elements = 0 ;
msg - > elements = NULL ;
if ( r - > num_attributes > 0 ) {
msg - > num_elements = r - > num_attributes ;
2005-01-27 07:08:20 +00:00
msg - > elements = talloc_array ( msg , struct ldb_message_element , msg - > num_elements ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( msg - > elements ) ;
2004-09-28 10:44:44 +00:00
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
msg - > elements [ i ] . name = discard_const_p ( char , r - > attributes [ i ] . name ) ;
msg - > elements [ i ] . flags = 0 ;
msg - > elements [ i ] . num_values = 0 ;
msg - > elements [ i ] . values = NULL ;
if ( r - > attributes [ i ] . num_values > 0 ) {
msg - > elements [ i ] . num_values = r - > attributes [ i ] . num_values ;
2005-01-27 07:08:20 +00:00
msg - > elements [ i ] . values = talloc_array ( msg , struct ldb_val , msg - > elements [ i ] . num_values ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( msg - > elements [ i ] . values ) ;
2004-09-28 10:44:44 +00:00
for ( j = 0 ; j < msg - > elements [ i ] . num_values ; j + + ) {
if ( ! ( r - > attributes [ i ] . values [ j ] . length > 0 ) ) {
2004-10-20 23:12:30 +00:00
result = LDAP_OTHER ;
errstr = " Empty attribute values are not allowed " ;
goto reply ;
2004-09-28 10:44:44 +00:00
}
msg - > elements [ i ] . values [ j ] . length = r - > attributes [ i ] . values [ j ] . length ;
msg - > elements [ i ] . values [ j ] . data = r - > attributes [ i ] . values [ j ] . data ;
}
} else {
2004-10-20 23:12:30 +00:00
result = LDAP_OTHER ;
errstr = " No attribute values are not allowed " ;
goto reply ;
2004-09-28 10:44:44 +00:00
}
}
} else {
2004-10-20 23:12:30 +00:00
result = LDAP_OTHER ;
errstr = " No attributes are not allowed " ;
goto reply ;
2004-09-28 10:44:44 +00:00
}
2004-10-20 23:12:30 +00:00
reply :
2004-09-28 10:44:44 +00:00
add_reply = ldapsrv_init_reply ( call , LDAP_TAG_AddResponse ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( add_reply ) ;
2004-09-28 10:44:44 +00:00
if ( result = = LDAP_SUCCESS ) {
2005-02-27 11:35:47 +00:00
ldb_ret = ldb_add ( samdb , msg ) ;
2005-10-31 03:05:26 +00:00
result = sldb_map_error ( partition , ldb_ret , & errstr ) ;
2004-09-28 10:44:44 +00:00
}
2005-06-15 00:27:51 +00:00
add_result = & add_reply - > msg - > r . AddResponse ;
2004-10-20 23:12:30 +00:00
add_result - > dn = NULL ;
2004-09-28 10:44:44 +00:00
add_result - > resultcode = result ;
2004-10-20 23:12:30 +00:00
add_result - > errormessage = ( errstr ? talloc_strdup ( add_reply , errstr ) : NULL ) ;
2004-09-28 10:44:44 +00:00
add_result - > referral = NULL ;
2004-10-04 21:02:00 +00:00
talloc_free ( local_ctx ) ;
2004-09-28 10:44:44 +00:00
2005-06-19 09:31:34 +00:00
ldapsrv_queue_reply ( call , add_reply ) ;
return NT_STATUS_OK ;
2004-09-28 10:44:44 +00:00
}
2004-09-27 15:40:12 +00:00
static NTSTATUS sldb_Del ( struct ldapsrv_partition * partition , struct ldapsrv_call * call ,
struct ldap_DelRequest * r )
2004-09-27 14:11:11 +00:00
{
2004-10-04 21:02:00 +00:00
void * local_ctx ;
2005-08-18 15:02:01 +00:00
struct ldb_dn * dn ;
2004-09-28 10:44:44 +00:00
struct ldap_Result * del_result ;
struct ldapsrv_reply * del_reply ;
2004-09-27 14:11:11 +00:00
int ldb_ret ;
2005-02-27 11:35:47 +00:00
struct ldb_context * samdb ;
2004-09-28 10:44:44 +00:00
const char * errstr = NULL ;
int result = LDAP_SUCCESS ;
2004-09-27 14:11:11 +00:00
2004-10-04 21:02:00 +00:00
local_ctx = talloc_named ( call , 0 , " sldb_Del local memory context " ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( local_ctx ) ;
2004-10-04 21:02:00 +00:00
2005-10-07 12:30:46 +00:00
samdb = talloc_get_type ( partition - > private , struct ldb_context ) ;
2004-10-20 23:12:30 +00:00
2005-08-18 15:02:01 +00:00
dn = ldb_dn_explode ( local_ctx , r - > dn ) ;
2004-10-20 23:25:39 +00:00
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-09-28 10:44:44 +00:00
2005-08-18 15:02:01 +00:00
DEBUG ( 10 , ( " sldb_Del: dn: [%s] \n " , r - > dn ) ) ;
2004-09-27 14:11:11 +00:00
2004-10-20 23:12:30 +00:00
reply :
2004-09-28 10:44:44 +00:00
del_reply = ldapsrv_init_reply ( call , LDAP_TAG_DelResponse ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( del_reply ) ;
2004-09-27 14:11:11 +00:00
2004-10-20 23:12:30 +00:00
if ( result = = LDAP_SUCCESS ) {
2005-08-18 15:02:01 +00:00
ldb_ret = ldb_delete ( samdb , dn ) ;
2005-10-31 03:05:26 +00:00
result = sldb_map_error ( partition , ldb_ret , & errstr ) ;
2004-09-27 14:11:11 +00:00
}
2005-06-15 00:27:51 +00:00
del_result = & del_reply - > msg - > r . DelResponse ;
2004-10-20 23:12:30 +00:00
del_result - > dn = NULL ;
2004-09-28 10:44:44 +00:00
del_result - > resultcode = result ;
2004-10-20 23:12:30 +00:00
del_result - > errormessage = ( errstr ? talloc_strdup ( del_reply , errstr ) : NULL ) ;
2004-09-28 10:44:44 +00:00
del_result - > referral = NULL ;
2004-09-27 14:11:11 +00:00
2004-10-04 21:02:00 +00:00
talloc_free ( local_ctx ) ;
2004-09-27 14:11:11 +00:00
2005-06-19 09:31:34 +00:00
ldapsrv_queue_reply ( call , del_reply ) ;
return NT_STATUS_OK ;
2004-09-27 14:11:11 +00:00
}
2004-09-28 11:57:56 +00:00
static NTSTATUS sldb_Modify ( struct ldapsrv_partition * partition , struct ldapsrv_call * call ,
struct ldap_ModifyRequest * r )
{
2004-10-04 21:02:00 +00:00
void * local_ctx ;
2005-08-18 15:02:01 +00:00
struct ldb_dn * dn ;
2004-09-28 11:57:56 +00:00
struct ldap_Result * modify_result ;
struct ldapsrv_reply * modify_reply ;
int ldb_ret ;
2005-02-27 11:35:47 +00:00
struct ldb_context * samdb ;
2004-12-02 04:51:56 +00:00
struct ldb_message * msg = NULL ;
2004-09-28 11:57:56 +00:00
int result = LDAP_SUCCESS ;
const char * errstr = NULL ;
int i , j ;
2004-10-04 21:02:00 +00:00
local_ctx = talloc_named ( call , 0 , " sldb_Modify local memory context " ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( local_ctx ) ;
2004-10-04 21:02:00 +00:00
2005-10-07 12:30:46 +00:00
samdb = talloc_get_type ( partition - > private , struct ldb_context ) ;
2004-10-04 21:02:00 +00:00
2005-08-18 15:02:01 +00:00
dn = ldb_dn_explode ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-09-28 11:57:56 +00:00
2005-08-18 15:02:01 +00:00
DEBUG ( 10 , ( " sldb_modify: dn: [%s] \n " , r - > dn ) ) ;
2004-09-28 11:57:56 +00:00
2005-01-27 07:08:20 +00:00
msg = talloc ( local_ctx , struct ldb_message ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( msg ) ;
2004-09-28 11:57:56 +00:00
2005-08-18 15:02:01 +00:00
msg - > dn = dn ;
2004-09-28 11:57:56 +00:00
msg - > private_data = NULL ;
msg - > num_elements = 0 ;
msg - > elements = NULL ;
if ( r - > num_mods > 0 ) {
msg - > num_elements = r - > num_mods ;
2005-01-27 07:08:20 +00:00
msg - > elements = talloc_array ( msg , struct ldb_message_element , r - > num_mods ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( msg - > elements ) ;
2004-09-28 11:57:56 +00:00
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
msg - > elements [ i ] . name = discard_const_p ( char , r - > mods [ i ] . attrib . name ) ;
msg - > elements [ i ] . num_values = 0 ;
msg - > elements [ i ] . values = NULL ;
switch ( r - > mods [ i ] . type ) {
default :
2004-10-20 23:12:30 +00:00
result = LDAP_PROTOCOL_ERROR ;
errstr = " Invalid LDAP_MODIFY_* type " ;
goto reply ;
2004-09-28 11:57:56 +00:00
case LDAP_MODIFY_ADD :
msg - > elements [ i ] . flags = LDB_FLAG_MOD_ADD ;
break ;
case LDAP_MODIFY_DELETE :
msg - > elements [ i ] . flags = LDB_FLAG_MOD_DELETE ;
break ;
case LDAP_MODIFY_REPLACE :
msg - > elements [ i ] . flags = LDB_FLAG_MOD_REPLACE ;
break ;
}
2004-11-15 11:40:27 +00:00
msg - > elements [ i ] . num_values = r - > mods [ i ] . attrib . num_values ;
if ( msg - > elements [ i ] . num_values > 0 ) {
2005-01-27 07:08:20 +00:00
msg - > elements [ i ] . values = talloc_array ( msg , struct ldb_val , msg - > elements [ i ] . num_values ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( msg - > elements [ i ] . values ) ;
2004-09-28 11:57:56 +00:00
for ( j = 0 ; j < msg - > elements [ i ] . num_values ; j + + ) {
if ( ! ( r - > mods [ i ] . attrib . values [ j ] . length > 0 ) ) {
2004-10-20 23:12:30 +00:00
result = LDAP_OTHER ;
errstr = " Empty attribute values are not allowed " ;
goto reply ;
2004-09-28 11:57:56 +00:00
}
msg - > elements [ i ] . values [ j ] . length = r - > mods [ i ] . attrib . values [ j ] . length ;
msg - > elements [ i ] . values [ j ] . data = r - > mods [ i ] . attrib . values [ j ] . data ;
}
}
}
} else {
2004-10-20 23:12:30 +00:00
result = LDAP_OTHER ;
errstr = " No mods are not allowed " ;
goto reply ;
2004-09-28 11:57:56 +00:00
}
2004-10-20 23:12:30 +00:00
reply :
2004-09-28 11:57:56 +00:00
modify_reply = ldapsrv_init_reply ( call , LDAP_TAG_ModifyResponse ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( modify_reply ) ;
2004-09-28 11:57:56 +00:00
if ( result = = LDAP_SUCCESS ) {
2005-02-27 11:35:47 +00:00
ldb_ret = ldb_modify ( samdb , msg ) ;
2005-10-31 03:05:26 +00:00
result = sldb_map_error ( partition , ldb_ret , & errstr ) ;
2004-09-28 11:57:56 +00:00
}
2004-09-28 12:17:03 +00:00
2005-06-15 00:27:51 +00:00
modify_result = & modify_reply - > msg - > r . AddResponse ;
2004-10-20 23:12:30 +00:00
modify_result - > dn = NULL ;
2004-09-28 11:57:56 +00:00
modify_result - > resultcode = result ;
2004-10-20 23:12:30 +00:00
modify_result - > errormessage = ( errstr ? talloc_strdup ( modify_reply , errstr ) : NULL ) ;
2004-09-28 11:57:56 +00:00
modify_result - > referral = NULL ;
2004-10-04 21:02:00 +00:00
talloc_free ( local_ctx ) ;
2004-09-28 11:57:56 +00:00
2005-06-19 09:31:34 +00:00
ldapsrv_queue_reply ( call , modify_reply ) ;
return NT_STATUS_OK ;
2004-09-28 11:57:56 +00:00
}
2004-09-29 12:20:59 +00:00
static NTSTATUS sldb_Compare ( struct ldapsrv_partition * partition , struct ldapsrv_call * call ,
struct ldap_CompareRequest * r )
{
2004-10-04 21:02:00 +00:00
void * local_ctx ;
2005-08-18 15:02:01 +00:00
struct ldb_dn * dn ;
2004-09-29 12:20:59 +00:00
struct ldap_Result * compare ;
struct ldapsrv_reply * compare_r ;
2004-10-20 23:12:30 +00:00
int result = LDAP_SUCCESS ;
2005-02-27 11:35:47 +00:00
struct ldb_context * samdb ;
2005-11-08 00:11:45 +00:00
struct ldb_result * res = NULL ;
2004-09-29 12:20:59 +00:00
const char * attrs [ 1 ] ;
2004-10-20 23:12:30 +00:00
const char * errstr = NULL ;
2004-12-02 04:51:56 +00:00
const char * filter = NULL ;
2005-11-08 00:11:45 +00:00
int ret ;
2004-09-29 12:20:59 +00:00
2004-10-04 21:02:00 +00:00
local_ctx = talloc_named ( call , 0 , " sldb_Compare local_memory_context " ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( local_ctx ) ;
2004-10-04 21:02:00 +00:00
2005-10-07 12:30:46 +00:00
samdb = talloc_get_type ( partition - > private , struct ldb_context ) ;
2004-09-29 12:20:59 +00:00
2005-08-18 15:02:01 +00:00
dn = ldb_dn_explode ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-10-04 21:02:00 +00:00
2005-08-18 15:02:01 +00:00
DEBUG ( 10 , ( " sldb_Compare: dn: [%s] \n " , r - > dn ) ) ;
2005-07-17 09:20:52 +00:00
filter = talloc_asprintf ( local_ctx , " (%s=%*s) " , r - > attribute ,
( int ) r - > value . length , r - > value . data ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( filter ) ;
2004-10-04 21:02:00 +00:00
2004-09-29 12:20:59 +00:00
DEBUGADD ( 10 , ( " sldb_Compare: attribute: [%s] \n " , filter ) ) ;
attrs [ 0 ] = NULL ;
2004-10-20 23:12:30 +00:00
reply :
2004-09-29 12:20:59 +00:00
compare_r = ldapsrv_init_reply ( call , LDAP_TAG_CompareResponse ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( compare_r ) ;
2004-09-29 12:20:59 +00:00
2004-10-20 23:12:30 +00:00
if ( result = = LDAP_SUCCESS ) {
2005-11-08 00:11:45 +00:00
ret = ldb_search ( samdb , dn , LDB_SCOPE_BASE , filter , attrs , & res ) ;
2005-01-02 07:51:13 +00:00
talloc_steal ( samdb , res ) ;
2005-11-08 00:11:45 +00:00
if ( ret ! = LDB_SUCCESS ) {
result = LDAP_OTHER ;
errstr = ldb_errstring ( samdb ) ;
DEBUG ( 10 , ( " sldb_Compare: error: %s \n " , errstr ) ) ;
} else if ( res - > count = = 0 ) {
2004-10-20 23:12:30 +00:00
DEBUG ( 10 , ( " sldb_Compare: doesn't matched \n " ) ) ;
result = LDAP_COMPARE_FALSE ;
errstr = NULL ;
2005-11-08 00:11:45 +00:00
} else if ( res - > count = = 1 ) {
DEBUG ( 10 , ( " sldb_Compare: matched \n " ) ) ;
result = LDAP_COMPARE_TRUE ;
errstr = NULL ;
} else if ( res - > count > 1 ) {
2004-10-20 23:12:30 +00:00
result = LDAP_OTHER ;
errstr = " too many objects match " ;
2005-11-08 00:11:45 +00:00
DEBUG ( 10 , ( " sldb_Compare: %d results: %s \n " , res - > count , errstr ) ) ;
2004-10-20 23:12:30 +00:00
}
2004-09-29 12:20:59 +00:00
}
2005-06-15 00:27:51 +00:00
compare = & compare_r - > msg - > r . CompareResponse ;
2004-09-29 12:20:59 +00:00
compare - > dn = NULL ;
2004-10-20 23:12:30 +00:00
compare - > resultcode = result ;
compare - > errormessage = ( errstr ? talloc_strdup ( compare_r , errstr ) : NULL ) ;
2004-09-29 12:20:59 +00:00
compare - > referral = NULL ;
2004-10-04 21:02:00 +00:00
talloc_free ( local_ctx ) ;
2004-09-29 12:20:59 +00:00
2005-06-19 09:31:34 +00:00
ldapsrv_queue_reply ( call , compare_r ) ;
return NT_STATUS_OK ;
2004-09-29 12:20:59 +00:00
}
2005-01-10 08:30:44 +00:00
static NTSTATUS sldb_ModifyDN ( struct ldapsrv_partition * partition , struct ldapsrv_call * call , struct ldap_ModifyDNRequest * r )
2004-10-20 23:27:09 +00:00
{
void * local_ctx ;
2005-08-18 15:02:01 +00:00
struct ldb_dn * olddn , * newdn , * newrdn ;
struct ldb_dn * parentdn = NULL ;
2004-10-20 23:27:09 +00:00
struct ldap_Result * modifydn ;
struct ldapsrv_reply * modifydn_r ;
int ldb_ret ;
2005-02-27 11:35:47 +00:00
struct ldb_context * samdb ;
2004-10-20 23:27:09 +00:00
const char * errstr = NULL ;
int result = LDAP_SUCCESS ;
local_ctx = talloc_named ( call , 0 , " sldb_ModifyDN local memory context " ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( local_ctx ) ;
2004-10-20 23:27:09 +00:00
2005-10-07 12:30:46 +00:00
samdb = talloc_get_type ( partition - > private , struct ldb_context ) ;
2004-10-20 23:27:09 +00:00
2005-08-18 15:02:01 +00:00
olddn = ldb_dn_explode ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( olddn , 2 ) ;
2004-10-20 23:27:09 +00:00
2005-08-18 15:02:01 +00:00
newrdn = ldb_dn_explode ( local_ctx , r - > newrdn ) ;
VALID_DN_SYNTAX ( newrdn , 1 ) ;
2004-10-20 23:27:09 +00:00
2005-08-18 15:02:01 +00:00
DEBUG ( 10 , ( " sldb_ModifyDN: olddn: [%s] \n " , r - > dn ) ) ;
DEBUG ( 10 , ( " sldb_ModifyDN: newrdn: [%s] \n " , r - > newrdn ) ) ;
2004-10-20 23:27:09 +00:00
/* we can't handle the rename if we should not remove the old dn */
if ( ! r - > deleteolddn ) {
result = LDAP_UNWILLING_TO_PERFORM ;
errstr = " Old RDN must be deleted " ;
goto reply ;
}
if ( newrdn - > comp_num > 1 ) {
result = LDAP_NAMING_VIOLATION ;
errstr = " Error new RDN invalid " ;
goto reply ;
}
if ( r - > newsuperior ) {
2005-08-18 15:02:01 +00:00
parentdn = ldb_dn_explode ( local_ctx , r - > newsuperior ) ;
VALID_DN_SYNTAX ( parentdn , 0 ) ;
DEBUG ( 10 , ( " sldb_ModifyDN: newsuperior: [%s] \n " , r - > newsuperior ) ) ;
2004-10-20 23:27:09 +00:00
2005-08-18 15:02:01 +00:00
if ( parentdn - > comp_num < 1 ) {
2004-10-20 23:27:09 +00:00
result = LDAP_AFFECTS_MULTIPLE_DSAS ;
errstr = " Error new Superior DN invalid " ;
goto reply ;
}
}
if ( ! parentdn ) {
2005-08-18 15:02:01 +00:00
parentdn = ldb_dn_get_parent ( local_ctx , olddn ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( parentdn ) ;
2004-10-20 23:27:09 +00:00
}
2005-08-18 15:02:01 +00:00
newdn = ldb_dn_make_child ( local_ctx , ldb_dn_get_rdn ( local_ctx , newrdn ) , parentdn ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( newdn ) ;
2004-10-20 23:27:09 +00:00
reply :
modifydn_r = ldapsrv_init_reply ( call , LDAP_TAG_ModifyDNResponse ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( modifydn_r ) ;
2004-10-20 23:27:09 +00:00
if ( result = = LDAP_SUCCESS ) {
2005-08-18 15:02:01 +00:00
ldb_ret = ldb_rename ( samdb , olddn , newdn ) ;
2005-10-31 03:05:26 +00:00
result = sldb_map_error ( partition , ldb_ret , & errstr ) ;
2004-10-20 23:27:09 +00:00
}
2005-06-15 00:27:51 +00:00
modifydn = & modifydn_r - > msg - > r . ModifyDNResponse ;
2004-10-20 23:27:09 +00:00
modifydn - > dn = NULL ;
modifydn - > resultcode = result ;
modifydn - > errormessage = ( errstr ? talloc_strdup ( modifydn_r , errstr ) : NULL ) ;
modifydn - > referral = NULL ;
talloc_free ( local_ctx ) ;
2005-06-19 09:31:34 +00:00
ldapsrv_queue_reply ( call , modifydn_r ) ;
return NT_STATUS_OK ;
2004-10-20 23:27:09 +00:00
}
2004-09-22 14:16:42 +00:00
static const struct ldapsrv_partition_ops sldb_ops = {
2005-10-07 11:31:45 +00:00
. Init = sldb_Init ,
. Bind = sldb_Bind ,
2004-09-27 14:11:11 +00:00
. Search = sldb_Search ,
2004-09-28 10:44:44 +00:00
. Add = sldb_Add ,
2004-09-28 11:57:56 +00:00
. Del = sldb_Del ,
2004-09-29 12:20:59 +00:00
. Modify = sldb_Modify ,
2004-10-20 23:27:09 +00:00
. Compare = sldb_Compare ,
. ModifyDN = sldb_ModifyDN
2004-09-22 14:16:42 +00:00
} ;
const struct ldapsrv_partition_ops * ldapsrv_get_sldb_partition_ops ( void )
{
return & sldb_ops ;
}