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"
2004-10-03 21:17:45 +00:00
# include "ldap_parse.h"
2004-11-16 09:00:52 +00:00
# include "lib/ldb/include/ldb.h"
2005-02-10 07:22:25 +00:00
# include "db_wrap.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
2004-09-22 14:16:42 +00:00
static NTSTATUS sldb_Search ( struct ldapsrv_partition * partition , struct ldapsrv_call * call ,
struct ldap_SearchRequest * r )
{
2004-09-27 13:20:59 +00:00
NTSTATUS status ;
2004-10-04 21:02:00 +00:00
void * local_ctx ;
struct ldap_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-01-02 07:51:13 +00:00
struct ldb_message * * res = NULL ;
2004-12-02 04:51:56 +00:00
int i , j , y , count = 0 ;
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 ;
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
samdb = samdb_connect ( local_ctx ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( samdb ) ;
2004-09-28 10:44:44 +00:00
2004-10-04 21:02:00 +00:00
basedn = ldap_parse_dn ( local_ctx , r - > basedn ) ;
2004-10-20 23:12:30 +00:00
VALID_DN_SYNTAX ( basedn , 0 ) ;
2004-10-04 21:02:00 +00:00
DEBUG ( 10 , ( " sldb_Search: basedn: [%s] \n " , basedn - > dn ) ) ;
2004-09-28 10:44:44 +00:00
DEBUG ( 10 , ( " sldb_Search: filter: [%s] \n " , r - > filter ) ) ;
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 ;
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 ;
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 ;
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-02-27 11:35:47 +00:00
count = ldb_search ( samdb , basedn - > dn , scope , r - > filter , attrs , & res ) ;
2005-01-02 07:51:13 +00:00
talloc_steal ( samdb , res ) ;
2004-09-27 08:52:31 +00:00
for ( i = 0 ; i < count ; i + + ) {
ent_r = ldapsrv_init_reply ( call , LDAP_TAG_SearchResultEntry ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( ent_r ) ;
2004-09-27 08:52:31 +00:00
ent = & ent_r - > msg . r . SearchResultEntry ;
ent - > dn = talloc_steal ( ent_r , res [ i ] - > dn ) ;
2004-09-27 13:20:59 +00:00
ent - > num_attributes = 0 ;
ent - > attributes = NULL ;
if ( res [ i ] - > num_elements = = 0 ) {
2004-09-27 15:11:42 +00:00
goto queue_reply ;
2004-09-27 13:20:59 +00:00
}
2004-09-27 08:52:31 +00:00
ent - > num_attributes = res [ i ] - > num_elements ;
2005-01-27 07:08:20 +00:00
ent - > attributes = talloc_array ( ent_r , struct ldap_attribute , ent - > num_attributes ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( ent - > attributes ) ;
2004-09-27 08:52:31 +00:00
for ( j = 0 ; j < ent - > num_attributes ; j + + ) {
ent - > attributes [ j ] . name = talloc_steal ( ent - > attributes , res [ i ] - > elements [ j ] . name ) ;
2004-09-27 13:20:59 +00:00
ent - > attributes [ j ] . num_values = 0 ;
ent - > attributes [ j ] . values = NULL ;
if ( r - > attributesonly & & ( res [ i ] - > elements [ j ] . num_values = = 0 ) ) {
2004-09-27 08:52:31 +00:00
continue ;
}
ent - > attributes [ j ] . num_values = res [ i ] - > elements [ j ] . num_values ;
2005-01-27 07:08:20 +00:00
ent - > attributes [ j ] . values = talloc_array ( ent - > attributes ,
2004-09-27 08:52:31 +00:00
DATA_BLOB , ent - > attributes [ j ] . num_values ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( ent - > attributes [ j ] . values ) ;
2004-09-27 08:52:31 +00:00
for ( y = 0 ; y < ent - > attributes [ j ] . num_values ; y + + ) {
ent - > attributes [ j ] . values [ y ] . length = res [ i ] - > elements [ j ] . values [ y ] . length ;
ent - > attributes [ j ] . values [ y ] . data = talloc_steal ( ent - > attributes [ j ] . values ,
res [ i ] - > elements [ j ] . values [ y ] . data ) ;
}
}
2004-09-27 15:11:42 +00:00
queue_reply :
2004-09-27 13:20:59 +00:00
status = ldapsrv_queue_reply ( call , ent_r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
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
2004-10-20 23:12:30 +00:00
if ( result = = LDAP_SUCCESS ) {
if ( count > 0 ) {
DEBUG ( 10 , ( " sldb_Search: results: [%d] \n " , count ) ) ;
result = LDAP_SUCCESS ;
errstr = NULL ;
} else if ( count = = 0 ) {
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
} else if ( count = = - 1 ) {
DEBUG ( 10 , ( " sldb_Search: error \n " ) ) ;
result = LDAP_OTHER ;
2005-02-27 11:35:47 +00:00
errstr = ldb_errstring ( samdb ) ;
2004-10-20 23:12:30 +00:00
}
2004-09-28 10:44:44 +00:00
}
2004-09-22 14:16:42 +00:00
done = & done_r - > msg . r . SearchResultDone ;
done - > dn = NULL ;
2004-10-20 23:12:30 +00:00
done - > resultcode = result ;
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
2004-09-27 13:20:59 +00:00
return ldapsrv_queue_reply ( call , done_r ) ;
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 ,
struct ldap_AddRequest * r )
{
2004-10-04 21:02:00 +00:00
void * local_ctx ;
2004-10-20 23:25:39 +00:00
struct ldap_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
samdb = samdb_connect ( local_ctx ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( samdb ) ;
2004-10-04 21:02:00 +00:00
2004-10-20 23:25:39 +00:00
dn = ldap_parse_dn ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-09-28 10:44:44 +00:00
2004-10-20 23:25:39 +00:00
DEBUG ( 10 , ( " sldb_add: dn: [%s] \n " , dn - > 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
2004-10-20 23:25:39 +00:00
msg - > dn = 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 ) ;
2004-09-28 10:44:44 +00:00
if ( ldb_ret = = 0 ) {
result = LDAP_SUCCESS ;
errstr = NULL ;
} else {
/* currently we have no way to tell if there was an internal ldb error
* or if the object was not found , return the most probable error
*/
2004-10-20 23:12:30 +00:00
result = LDAP_OPERATIONS_ERROR ;
2005-02-27 11:35:47 +00:00
errstr = ldb_errstring ( samdb ) ;
2004-09-28 10:44:44 +00:00
}
}
2004-10-20 23:12:30 +00:00
add_result = & add_reply - > msg . r . AddResponse ;
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
return ldapsrv_queue_reply ( call , add_reply ) ;
}
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 ;
2004-10-20 23:25:39 +00:00
struct ldap_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
samdb = samdb_connect ( local_ctx ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( samdb ) ;
2004-10-20 23:12:30 +00:00
2004-10-20 23:25:39 +00:00
dn = ldap_parse_dn ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-09-28 10:44:44 +00:00
2004-10-20 23:25:39 +00:00
DEBUG ( 10 , ( " sldb_Del: dn: [%s] \n " , dn - > 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-02-27 11:35:47 +00:00
ldb_ret = ldb_delete ( samdb , dn - > dn ) ;
2004-10-20 23:12:30 +00:00
if ( ldb_ret = = 0 ) {
result = LDAP_SUCCESS ;
errstr = NULL ;
} else {
/* currently we have no way to tell if there was an internal ldb error
* or if the object was not found , return the most probable error
*/
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
}
2004-09-27 14:11:11 +00:00
}
2004-10-20 23:12:30 +00:00
del_result = & del_reply - > msg . r . DelResponse ;
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
2004-09-28 10:44:44 +00:00
return ldapsrv_queue_reply ( call , del_reply ) ;
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 ;
2004-10-20 23:25:39 +00:00
struct ldap_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
2004-10-09 16:38:18 +00:00
samdb = samdb_connect ( local_ctx ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( samdb ) ;
2004-10-04 21:02:00 +00:00
2004-10-20 23:25:39 +00:00
dn = ldap_parse_dn ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-09-28 11:57:56 +00:00
2004-10-20 23:25:39 +00:00
DEBUG ( 10 , ( " sldb_modify: dn: [%s] \n " , dn - > 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
2004-10-20 23:25:39 +00:00
msg - > dn = 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 ) ;
2004-09-28 11:57:56 +00:00
if ( ldb_ret = = 0 ) {
result = LDAP_SUCCESS ;
errstr = NULL ;
} else {
/* currently we have no way to tell if there was an internal ldb error
* or if the object was not found , return the most probable error
*/
2004-10-20 23:12:30 +00:00
result = LDAP_OPERATIONS_ERROR ;
2005-02-27 11:35:47 +00:00
errstr = ldb_errstring ( samdb ) ;
2004-09-28 11:57:56 +00:00
}
}
2004-09-28 12:17:03 +00:00
2004-10-20 23:12:30 +00:00
modify_result = & modify_reply - > msg . r . AddResponse ;
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
return ldapsrv_queue_reply ( call , modify_reply ) ;
}
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 ;
2004-10-20 23:25:39 +00:00
struct ldap_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-01-02 07:51:13 +00:00
struct ldb_message * * 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 ;
2004-09-29 12:20:59 +00:00
int count ;
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
samdb = samdb_connect ( local_ctx ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( samdb ) ;
2004-09-29 12:20:59 +00:00
2004-10-20 23:25:39 +00:00
dn = ldap_parse_dn ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( dn , 1 ) ;
2004-10-04 21:02:00 +00:00
2004-10-20 23:25:39 +00:00
DEBUG ( 10 , ( " sldb_Compare: dn: [%s] \n " , dn - > dn ) ) ;
2004-10-04 21:02:00 +00:00
filter = talloc_asprintf ( local_ctx , " (%s=%*s) " , r - > attribute , 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-02-27 11:35:47 +00:00
count = ldb_search ( samdb , dn - > dn , LDB_SCOPE_BASE , filter , attrs , & res ) ;
2005-01-02 07:51:13 +00:00
talloc_steal ( samdb , res ) ;
2004-10-20 23:12:30 +00:00
if ( count = = 1 ) {
DEBUG ( 10 , ( " sldb_Compare: matched \n " ) ) ;
result = LDAP_COMPARE_TRUE ;
errstr = NULL ;
} else if ( count = = 0 ) {
DEBUG ( 10 , ( " sldb_Compare: doesn't matched \n " ) ) ;
result = LDAP_COMPARE_FALSE ;
errstr = NULL ;
} else if ( count > 1 ) {
result = LDAP_OTHER ;
errstr = " too many objects match " ;
DEBUG ( 10 , ( " sldb_Compare: %d results: %s \n " , count , errstr ) ) ;
} else if ( count = = - 1 ) {
result = LDAP_OTHER ;
2005-02-27 11:35:47 +00:00
errstr = ldb_errstring ( samdb ) ;
2004-10-20 23:12:30 +00:00
DEBUG ( 10 , ( " sldb_Compare: error: %s \n " , errstr ) ) ;
}
2004-09-29 12:20:59 +00:00
}
compare = & compare_r - > msg . r . CompareResponse ;
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
return ldapsrv_queue_reply ( call , compare_r ) ;
}
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 ;
struct ldap_dn * olddn , * newrdn , * newsuperior ;
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 ;
2004-12-02 04:51:56 +00:00
const char * newdn = NULL ;
2004-10-20 23:27:09 +00:00
char * parentdn = NULL ;
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
samdb = samdb_connect ( local_ctx ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( samdb ) ;
2004-10-20 23:27:09 +00:00
olddn = ldap_parse_dn ( local_ctx , r - > dn ) ;
VALID_DN_SYNTAX ( olddn , 2 ) ;
newrdn = ldap_parse_dn ( local_ctx , r - > newrdn ) ;
VALID_DN_SYNTAX ( newrdn , 1 ) ;
DEBUG ( 10 , ( " sldb_ModifyDN: olddn: [%s] \n " , olddn - > dn ) ) ;
DEBUG ( 10 , ( " sldb_ModifyDN: newrdn: [%s] \n " , newrdn - > dn ) ) ;
/* 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 ) {
newsuperior = ldap_parse_dn ( local_ctx , r - > newsuperior ) ;
VALID_DN_SYNTAX ( newsuperior , 0 ) ;
DEBUG ( 10 , ( " sldb_ModifyDN: newsuperior: [%s] \n " , newsuperior - > dn ) ) ;
if ( newsuperior - > comp_num < 1 ) {
result = LDAP_AFFECTS_MULTIPLE_DSAS ;
errstr = " Error new Superior DN invalid " ;
goto reply ;
}
parentdn = newsuperior - > dn ;
}
if ( ! parentdn ) {
int i ;
parentdn = talloc_strdup ( local_ctx , olddn - > components [ 1 ] - > component ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( parentdn ) ;
2004-10-20 23:27:09 +00:00
for ( i = 2 ; i < olddn - > comp_num ; i + + ) {
char * old = parentdn ;
parentdn = talloc_asprintf ( local_ctx , " %s,%s " , old , olddn - > components [ i ] - > component ) ;
2005-01-10 08:54:31 +00:00
NT_STATUS_HAVE_NO_MEMORY ( parentdn ) ;
2004-10-20 23:27:09 +00:00
talloc_free ( old ) ;
}
}
newdn = talloc_asprintf ( local_ctx , " %s,%s " , newrdn - > dn , 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-02-27 11:35:47 +00:00
ldb_ret = ldb_rename ( samdb , olddn - > dn , newdn ) ;
2004-10-20 23:27:09 +00:00
if ( ldb_ret = = 0 ) {
result = LDAP_SUCCESS ;
errstr = NULL ;
} else {
/* currently we have no way to tell if there was an internal ldb error
* or if the object was not found , return the most probable error
*/
result = LDAP_NO_SUCH_OBJECT ;
2005-02-27 11:35:47 +00:00
errstr = ldb_errstring ( samdb ) ;
2004-10-20 23:27:09 +00:00
}
}
modifydn = & modifydn_r - > msg . r . ModifyDNResponse ;
modifydn - > dn = NULL ;
modifydn - > resultcode = result ;
modifydn - > errormessage = ( errstr ? talloc_strdup ( modifydn_r , errstr ) : NULL ) ;
modifydn - > referral = NULL ;
talloc_free ( local_ctx ) ;
return ldapsrv_queue_reply ( call , modifydn_r ) ;
}
2004-09-22 14:16:42 +00:00
static const struct ldapsrv_partition_ops sldb_ops = {
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 ;
}