2005-06-21 11:52:00 +04:00
/*
ldb database library - ldif handlers for Samba
2006-06-07 02:04:55 +04:00
Copyright ( C ) Andrew Tridgell 2005
2009-11-05 09:00:20 +03:00
Copyright ( C ) Andrew Bartlett 2006 - 2009
2009-06-18 13:05:45 +04:00
Copyright ( C ) Matthias Dieter Wallnöfer 2009
2005-06-21 11:52:00 +04:00
* * NOTE ! The following LGPL license applies to the ldb
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
2007-07-10 06:46:15 +04:00
version 3 of the License , or ( at your option ) any later version .
2005-06-21 11:52:00 +04:00
This library 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
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
2007-07-10 07:42:26 +04:00
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2005-06-21 11:52:00 +04:00
*/
# include "includes.h"
2009-06-30 09:12:29 +04:00
# include "lib/ldb/include/ldb.h"
# include "lib/ldb/include/ldb_module.h"
2009-01-31 04:12:16 +03:00
# include "ldb_handlers.h"
2007-12-08 01:56:53 +03:00
# include "dsdb/samdb/samdb.h"
2006-01-06 07:01:23 +03:00
# include "librpc/gen_ndr/ndr_security.h"
2005-07-28 02:14:55 +04:00
# include "librpc/gen_ndr/ndr_misc.h"
2008-05-29 12:38:17 +04:00
# include "librpc/gen_ndr/ndr_drsblobs.h"
2009-09-08 15:45:08 +04:00
# include "librpc/ndr/libndr.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2008-05-29 12:38:17 +04:00
# include "param/param.h"
2009-10-11 22:00:55 +04:00
# include "../lib/util/asn1.h"
2005-06-21 11:52:00 +04:00
2009-09-08 15:55:56 +04:00
/*
use ndr_print_ * to convert a NDR formatted blob to a ldif formatted blob
*/
static int ldif_write_NDR ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out ,
size_t struct_size ,
ndr_pull_flags_fn_t pull_fn ,
ndr_print_fn_t print_fn )
{
uint8_t * p ;
enum ndr_err_code err ;
if ( ! ( ldb_get_flags ( ldb ) & LDB_FLG_SHOW_BINARY ) ) {
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
}
p = talloc_size ( mem_ctx , struct_size ) ;
err = ndr_pull_struct_blob ( in , mem_ctx ,
lp_iconv_convenience ( ldb_get_opaque ( ldb , " loadparm " ) ) ,
p , pull_fn ) ;
if ( err ! = NDR_ERR_SUCCESS ) {
talloc_free ( p ) ;
2009-09-20 05:41:22 +04:00
out - > data = ( uint8_t * ) talloc_strdup ( mem_ctx , " <Unable to decode binary data> " ) ;
out - > length = strlen ( ( const char * ) out - > data ) ;
return 0 ;
2009-09-08 15:55:56 +04:00
}
out - > data = ( uint8_t * ) ndr_print_struct_string ( mem_ctx , print_fn , " NDR " , p ) ;
talloc_free ( p ) ;
if ( out - > data = = NULL ) {
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
}
out - > length = strlen ( ( char * ) out - > data ) ;
return 0 ;
}
2005-06-21 11:52:00 +04:00
/*
convert a ldif formatted objectSid to a NDR formatted blob
*/
2005-07-02 21:30:03 +04:00
static int ldif_read_objectSid ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
2005-06-21 11:52:00 +04:00
{
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2005-06-21 11:52:00 +04:00
struct dom_sid * sid ;
2008-08-21 13:24:58 +04:00
sid = dom_sid_parse_length ( mem_ctx , in ) ;
2005-06-21 11:52:00 +04:00
if ( sid = = NULL ) {
return - 1 ;
}
2008-01-02 07:05:05 +03:00
ndr_err = ndr_push_struct_blob ( out , mem_ctx , NULL , sid ,
2007-11-09 21:24:51 +03:00
( ndr_push_flags_fn_t ) ndr_push_dom_sid ) ;
2005-06-21 11:52:00 +04:00
talloc_free ( sid ) ;
2007-11-09 21:24:51 +03:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2005-06-21 11:52:00 +04:00
return - 1 ;
}
return 0 ;
}
/*
convert a NDR formatted blob to a ldif formatted objectSid
*/
2009-10-24 07:59:48 +04:00
int ldif_write_objectSid ( struct ldb_context * ldb , void * mem_ctx ,
2005-07-02 21:30:03 +04:00
const struct ldb_val * in , struct ldb_val * out )
2005-06-21 11:52:00 +04:00
{
struct dom_sid * sid ;
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2005-07-02 21:30:03 +04:00
sid = talloc ( mem_ctx , struct dom_sid ) ;
2005-06-21 11:52:00 +04:00
if ( sid = = NULL ) {
return - 1 ;
}
2008-12-16 10:43:12 +03:00
ndr_err = ndr_pull_struct_blob_all ( in , sid , NULL , sid ,
( ndr_pull_flags_fn_t ) ndr_pull_dom_sid ) ;
2007-11-09 21:24:51 +03:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2005-06-21 11:52:00 +04:00
talloc_free ( sid ) ;
return - 1 ;
}
2008-08-21 13:24:58 +04:00
* out = data_blob_string_const ( dom_sid_string ( mem_ctx , sid ) ) ;
2005-06-21 11:52:00 +04:00
talloc_free ( sid ) ;
if ( out - > data = = NULL ) {
return - 1 ;
}
return 0 ;
}
2009-10-24 07:59:48 +04:00
bool ldif_comparision_objectSid_isString ( const struct ldb_val * v )
2005-07-08 09:14:46 +04:00
{
2006-11-01 06:17:23 +03:00
if ( v - > length < 3 ) {
2007-10-07 01:42:58 +04:00
return false ;
2006-11-01 06:17:23 +03:00
}
2007-10-07 01:42:58 +04:00
if ( strncmp ( " S- " , ( const char * ) v - > data , 2 ) ! = 0 ) return false ;
2006-11-01 06:17:23 +03:00
2007-10-05 21:24:50 +04:00
return true ;
2005-07-08 09:14:46 +04:00
}
r8037: a fairly major update to the internals of ldb. Changes are:
- moved the knowledge of attribute types out of ldb_tdb and into the
generic ldb code. This allows the ldb_match() message match logic
to be generic, so it can be used by other backend
- added the generic ability to load attribute handlers, for
canonicalisation, compare, ldif read and ldif write. In the future
this will be used by the schema module to allow us to correctly
obey the attributetype schema elements
- added attribute handlers for some of the core ldap attribute types,
Integer, DirectoryString, DN, ObjectClass etc
- added automatic registration of attribute handlers for well-known
attribute names 'cn', 'dc', 'dn', 'ou' and 'objectClass'
- converted the objectSid special handlers for Samba to the new system
- added more correct handling of indexing in tdb backend based on the
attribute canonicalisation function
- added generic support for subclasses, moving it out of the tdb
backend. This will be used in future by the schema module
- fixed several bugs in the dn_explode code. It still needs more
work, but doesn't corrupt ldb dbs any more.
(This used to be commit 944c5844ab441b96d8e5d7b2d151982139d1fab9)
2005-07-01 10:21:26 +04:00
/*
compare two objectSids
*/
2009-06-18 13:05:45 +04:00
static int ldif_comparison_objectSid ( struct ldb_context * ldb , void * mem_ctx ,
r8037: a fairly major update to the internals of ldb. Changes are:
- moved the knowledge of attribute types out of ldb_tdb and into the
generic ldb code. This allows the ldb_match() message match logic
to be generic, so it can be used by other backend
- added the generic ability to load attribute handlers, for
canonicalisation, compare, ldif read and ldif write. In the future
this will be used by the schema module to allow us to correctly
obey the attributetype schema elements
- added attribute handlers for some of the core ldap attribute types,
Integer, DirectoryString, DN, ObjectClass etc
- added automatic registration of attribute handlers for well-known
attribute names 'cn', 'dc', 'dn', 'ou' and 'objectClass'
- converted the objectSid special handlers for Samba to the new system
- added more correct handling of indexing in tdb backend based on the
attribute canonicalisation function
- added generic support for subclasses, moving it out of the tdb
backend. This will be used in future by the schema module
- fixed several bugs in the dn_explode code. It still needs more
work, but doesn't corrupt ldb dbs any more.
(This used to be commit 944c5844ab441b96d8e5d7b2d151982139d1fab9)
2005-07-01 10:21:26 +04:00
const struct ldb_val * v1 , const struct ldb_val * v2 )
{
2009-06-18 13:05:45 +04:00
if ( ldif_comparision_objectSid_isString ( v1 ) & & ldif_comparision_objectSid_isString ( v2 ) ) {
2008-08-21 09:10:40 +04:00
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
2009-06-18 13:05:45 +04:00
} else if ( ldif_comparision_objectSid_isString ( v1 )
& & ! ldif_comparision_objectSid_isString ( v2 ) ) {
2006-07-12 05:25:20 +04:00
struct ldb_val v ;
int ret ;
if ( ldif_read_objectSid ( ldb , mem_ctx , v1 , & v ) ! = 0 ) {
2008-08-21 09:10:40 +04:00
/* Perhaps not a string after all */
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
2005-07-01 11:02:26 +04:00
}
2006-07-12 05:25:20 +04:00
ret = ldb_comparison_binary ( ldb , mem_ctx , & v , v2 ) ;
talloc_free ( v . data ) ;
return ret ;
2009-06-18 13:05:45 +04:00
} else if ( ! ldif_comparision_objectSid_isString ( v1 )
& & ldif_comparision_objectSid_isString ( v2 ) ) {
2006-07-12 05:25:20 +04:00
struct ldb_val v ;
int ret ;
if ( ldif_read_objectSid ( ldb , mem_ctx , v2 , & v ) ! = 0 ) {
2008-08-21 09:10:40 +04:00
/* Perhaps not a string after all */
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
2006-07-12 05:25:20 +04:00
}
ret = ldb_comparison_binary ( ldb , mem_ctx , v1 , & v ) ;
talloc_free ( v . data ) ;
return ret ;
2005-07-01 11:02:26 +04:00
}
2005-07-02 21:30:03 +04:00
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
r8037: a fairly major update to the internals of ldb. Changes are:
- moved the knowledge of attribute types out of ldb_tdb and into the
generic ldb code. This allows the ldb_match() message match logic
to be generic, so it can be used by other backend
- added the generic ability to load attribute handlers, for
canonicalisation, compare, ldif read and ldif write. In the future
this will be used by the schema module to allow us to correctly
obey the attributetype schema elements
- added attribute handlers for some of the core ldap attribute types,
Integer, DirectoryString, DN, ObjectClass etc
- added automatic registration of attribute handlers for well-known
attribute names 'cn', 'dc', 'dn', 'ou' and 'objectClass'
- converted the objectSid special handlers for Samba to the new system
- added more correct handling of indexing in tdb backend based on the
attribute canonicalisation function
- added generic support for subclasses, moving it out of the tdb
backend. This will be used in future by the schema module
- fixed several bugs in the dn_explode code. It still needs more
work, but doesn't corrupt ldb dbs any more.
(This used to be commit 944c5844ab441b96d8e5d7b2d151982139d1fab9)
2005-07-01 10:21:26 +04:00
}
2005-07-01 11:02:26 +04:00
/*
canonicalise a objectSid
*/
2009-06-18 13:05:45 +04:00
static int ldif_canonicalise_objectSid ( struct ldb_context * ldb , void * mem_ctx ,
2005-07-02 21:30:03 +04:00
const struct ldb_val * in , struct ldb_val * out )
2005-07-01 11:02:26 +04:00
{
2009-06-18 13:05:45 +04:00
if ( ldif_comparision_objectSid_isString ( in ) ) {
2008-08-21 09:10:40 +04:00
if ( ldif_read_objectSid ( ldb , mem_ctx , in , out ) ! = 0 ) {
/* Perhaps not a string after all */
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
}
2008-08-22 12:37:34 +04:00
return 0 ;
2005-07-01 11:02:26 +04:00
}
2005-07-02 21:30:03 +04:00
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
2005-07-01 11:02:26 +04:00
}
2008-12-16 10:43:12 +03:00
static int extended_dn_read_SID ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct dom_sid sid ;
enum ndr_err_code ndr_err ;
2009-06-18 13:05:45 +04:00
if ( ldif_comparision_objectSid_isString ( in ) ) {
2008-12-16 10:43:12 +03:00
if ( ldif_read_objectSid ( ldb , mem_ctx , in , out ) = = 0 ) {
return 0 ;
}
}
/* Perhaps not a string after all */
2009-10-02 16:40:50 +04:00
* out = data_blob_talloc ( mem_ctx , NULL , in - > length / 2 + 1 ) ;
2008-12-16 10:43:12 +03:00
if ( ! out - > data ) {
return - 1 ;
}
2009-10-02 16:40:50 +04:00
( * out ) . length = strhex_to_str ( ( char * ) out - > data , out - > length ,
( const char * ) in - > data , in - > length ) ;
2008-12-16 10:43:12 +03:00
/* Check it looks like a SID */
2009-10-02 16:40:50 +04:00
ndr_err = ndr_pull_struct_blob_all ( out , mem_ctx , NULL , & sid ,
2008-12-16 10:43:12 +03:00
( ndr_pull_flags_fn_t ) ndr_pull_dom_sid ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return - 1 ;
}
return 0 ;
}
2005-07-08 09:14:46 +04:00
/*
convert a ldif formatted objectGUID to a NDR formatted blob
*/
static int ldif_read_objectGUID ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct GUID guid ;
NTSTATUS status ;
2008-12-16 10:43:12 +03:00
status = GUID_from_data_blob ( in , & guid ) ;
2005-07-08 09:14:46 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
2009-12-10 06:32:47 +03:00
status = GUID_to_ndr_blob ( & guid , mem_ctx , out ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-07-08 09:14:46 +04:00
return - 1 ;
}
return 0 ;
}
/*
convert a NDR formatted blob to a ldif formatted objectGUID
*/
static int ldif_write_objectGUID ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct GUID guid ;
2009-12-10 03:27:09 +03:00
NTSTATUS status ;
status = GUID_from_ndr_blob ( in , & guid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-07-08 09:14:46 +04:00
return - 1 ;
}
2005-07-08 09:27:47 +04:00
out - > data = ( uint8_t * ) GUID_string ( mem_ctx , & guid ) ;
2005-07-08 09:14:46 +04:00
if ( out - > data = = NULL ) {
return - 1 ;
}
2005-07-08 09:27:47 +04:00
out - > length = strlen ( ( const char * ) out - > data ) ;
2005-07-08 09:14:46 +04:00
return 0 ;
}
2009-06-18 13:05:45 +04:00
static bool ldif_comparision_objectGUID_isString ( const struct ldb_val * v )
2005-07-08 09:14:46 +04:00
{
2008-12-16 10:43:12 +03:00
if ( v - > length ! = 36 & & v - > length ! = 38 ) return false ;
2006-07-12 05:25:20 +04:00
2008-12-16 10:43:12 +03:00
/* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
return true ;
}
2006-11-13 06:21:13 +03:00
2008-12-16 10:43:12 +03:00
static int extended_dn_read_GUID ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct GUID guid ;
2009-12-10 03:27:09 +03:00
NTSTATUS status ;
2008-12-16 10:43:12 +03:00
if ( in - > length = = 36 & & ldif_read_objectGUID ( ldb , mem_ctx , in , out ) = = 0 ) {
return 0 ;
2005-07-08 09:14:46 +04:00
}
2008-12-16 10:43:12 +03:00
/* Try as 'hex' form */
if ( in - > length ! = 32 ) {
return - 1 ;
}
2009-10-02 16:40:50 +04:00
* out = data_blob_talloc ( mem_ctx , NULL , in - > length / 2 + 1 ) ;
2008-12-16 10:43:12 +03:00
if ( ! out - > data ) {
return - 1 ;
}
2009-10-02 16:40:50 +04:00
( * out ) . length = strhex_to_str ( ( char * ) out - > data , out - > length ,
( const char * ) in - > data , in - > length ) ;
2008-12-16 10:43:12 +03:00
/* Check it looks like a GUID */
2009-12-10 03:27:09 +03:00
status = GUID_from_ndr_blob ( out , & guid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
data_blob_free ( out ) ;
2008-12-16 10:43:12 +03:00
return - 1 ;
}
return 0 ;
2005-07-08 09:14:46 +04:00
}
/*
compare two objectGUIDs
*/
2009-06-18 13:05:45 +04:00
static int ldif_comparison_objectGUID ( struct ldb_context * ldb , void * mem_ctx ,
2005-07-08 09:14:46 +04:00
const struct ldb_val * v1 , const struct ldb_val * v2 )
{
2009-06-18 13:05:45 +04:00
if ( ldif_comparision_objectGUID_isString ( v1 ) & & ldif_comparision_objectGUID_isString ( v2 ) ) {
2008-08-21 09:10:40 +04:00
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
2009-06-18 13:05:45 +04:00
} else if ( ldif_comparision_objectGUID_isString ( v1 )
& & ! ldif_comparision_objectGUID_isString ( v2 ) ) {
2006-07-12 05:25:20 +04:00
struct ldb_val v ;
int ret ;
if ( ldif_read_objectGUID ( ldb , mem_ctx , v1 , & v ) ! = 0 ) {
2008-08-21 09:10:40 +04:00
/* Perhaps it wasn't a valid string after all */
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
2006-07-12 05:25:20 +04:00
}
ret = ldb_comparison_binary ( ldb , mem_ctx , & v , v2 ) ;
talloc_free ( v . data ) ;
return ret ;
2009-06-18 13:05:45 +04:00
} else if ( ! ldif_comparision_objectGUID_isString ( v1 )
& & ldif_comparision_objectGUID_isString ( v2 ) ) {
2006-07-12 05:25:20 +04:00
struct ldb_val v ;
int ret ;
if ( ldif_read_objectGUID ( ldb , mem_ctx , v2 , & v ) ! = 0 ) {
2008-08-21 09:10:40 +04:00
/* Perhaps it wasn't a valid string after all */
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
2005-07-08 09:14:46 +04:00
}
2006-07-12 05:25:20 +04:00
ret = ldb_comparison_binary ( ldb , mem_ctx , v1 , & v ) ;
talloc_free ( v . data ) ;
return ret ;
2005-07-08 09:14:46 +04:00
}
return ldb_comparison_binary ( ldb , mem_ctx , v1 , v2 ) ;
}
/*
canonicalise a objectGUID
*/
2009-06-18 13:05:45 +04:00
static int ldif_canonicalise_objectGUID ( struct ldb_context * ldb , void * mem_ctx ,
2005-07-08 09:14:46 +04:00
const struct ldb_val * in , struct ldb_val * out )
{
2009-06-18 13:05:45 +04:00
if ( ldif_comparision_objectGUID_isString ( in ) ) {
2008-08-21 09:10:40 +04:00
if ( ldif_read_objectGUID ( ldb , mem_ctx , in , out ) ! = 0 ) {
/* Perhaps it wasn't a valid string after all */
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
}
2008-08-22 12:37:34 +04:00
return 0 ;
2005-07-08 09:14:46 +04:00
}
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
}
2005-06-21 11:52:00 +04:00
2005-12-10 02:43:02 +03:00
/*
convert a ldif ( SDDL ) formatted ntSecurityDescriptor to a NDR formatted blob
*/
static int ldif_read_ntSecurityDescriptor ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct security_descriptor * sd ;
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2006-08-05 10:35:32 +04:00
2009-08-04 10:07:18 +04:00
sd = talloc ( mem_ctx , struct security_descriptor ) ;
2005-12-10 02:43:02 +03:00
if ( sd = = NULL ) {
return - 1 ;
}
2009-08-04 10:07:18 +04:00
ndr_err = ndr_pull_struct_blob ( in , sd , NULL , sd ,
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
/* If this does not parse, then it is probably SDDL, and we should try it that way */
2009-08-04 10:11:55 +04:00
const struct dom_sid * sid = samdb_domain_sid ( ldb ) ;
2009-08-04 10:07:18 +04:00
talloc_free ( sd ) ;
sd = sddl_decode ( mem_ctx , ( const char * ) in - > data , sid ) ;
if ( sd = = NULL ) {
return - 1 ;
}
}
2009-10-02 16:40:50 +04:00
ndr_err = ndr_push_struct_blob ( out , mem_ctx , NULL , sd ,
2007-11-09 21:24:51 +03:00
( ndr_push_flags_fn_t ) ndr_push_security_descriptor ) ;
2009-10-02 16:40:50 +04:00
talloc_free ( sd ) ;
2007-11-09 21:24:51 +03:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2005-12-10 02:43:02 +03:00
return - 1 ;
}
2009-08-04 10:07:18 +04:00
2005-12-10 02:43:02 +03:00
return 0 ;
}
/*
convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor ( SDDL format )
*/
static int ldif_write_ntSecurityDescriptor ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct security_descriptor * sd ;
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2005-12-10 02:43:02 +03:00
2009-09-08 15:55:56 +04:00
if ( ldb_get_flags ( ldb ) & LDB_FLG_SHOW_BINARY ) {
return ldif_write_NDR ( ldb , mem_ctx , in , out ,
sizeof ( struct security_descriptor ) ,
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ,
( ndr_print_fn_t ) ndr_print_security_descriptor ) ;
}
2005-12-10 02:43:02 +03:00
sd = talloc ( mem_ctx , struct security_descriptor ) ;
if ( sd = = NULL ) {
return - 1 ;
}
2008-12-16 10:43:12 +03:00
/* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
2008-01-02 07:05:13 +03:00
ndr_err = ndr_pull_struct_blob ( in , sd , NULL , sd ,
2008-12-16 10:43:12 +03:00
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
2007-11-09 21:24:51 +03:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2005-12-10 02:43:02 +03:00
talloc_free ( sd ) ;
return - 1 ;
}
2006-08-05 10:35:32 +04:00
out - > data = ( uint8_t * ) sddl_encode ( mem_ctx , sd , NULL ) ;
2005-12-10 02:43:02 +03:00
talloc_free ( sd ) ;
if ( out - > data = = NULL ) {
return - 1 ;
}
out - > length = strlen ( ( const char * ) out - > data ) ;
return 0 ;
}
2006-06-07 02:04:55 +04:00
/*
2007-12-08 01:56:53 +03:00
canonicalise an objectCategory . We use the short form as the cannoical form :
2006-06-07 02:04:55 +04:00
cn = Person , cn = Schema , cn = Configuration , < basedn > becomes ' person '
*/
static int ldif_canonicalise_objectCategory ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct ldb_dn * dn1 = NULL ;
2007-06-21 14:18:20 +04:00
const struct dsdb_schema * schema = dsdb_get_schema ( ldb ) ;
2009-02-02 13:25:39 +03:00
const struct dsdb_class * sclass ;
2007-08-20 04:22:53 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( ! tmp_ctx ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2006-06-07 02:04:55 +04:00
2007-06-21 14:18:20 +04:00
if ( ! schema ) {
2009-09-01 13:56:56 +04:00
talloc_free ( tmp_ctx ) ;
2007-06-21 14:18:20 +04:00
* out = data_blob_talloc ( mem_ctx , in - > data , in - > length ) ;
2007-08-20 04:22:53 +04:00
if ( in - > data & & ! out - > data ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-06-21 14:18:20 +04:00
return LDB_SUCCESS ;
}
2008-08-21 13:24:58 +04:00
dn1 = ldb_dn_from_ldb_val ( tmp_ctx , ldb , in ) ;
2006-11-22 03:59:34 +03:00
if ( ! ldb_dn_validate ( dn1 ) ) {
2007-08-20 04:22:53 +04:00
const char * lDAPDisplayName = talloc_strndup ( tmp_ctx , ( char * ) in - > data , in - > length ) ;
2009-02-02 13:25:39 +03:00
sclass = dsdb_class_by_lDAPDisplayName ( schema , lDAPDisplayName ) ;
if ( sclass ) {
2007-08-15 17:14:38 +04:00
struct ldb_dn * dn = ldb_dn_new ( mem_ctx , ldb ,
2009-02-02 13:25:39 +03:00
sclass - > defaultObjectCategory ) ;
2007-08-20 04:22:53 +04:00
* out = data_blob_string_const ( ldb_dn_alloc_casefold ( mem_ctx , dn ) ) ;
talloc_free ( tmp_ctx ) ;
if ( ! out - > data ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-08-15 17:14:38 +04:00
return LDB_SUCCESS ;
} else {
* out = data_blob_talloc ( mem_ctx , in - > data , in - > length ) ;
2007-08-20 04:22:53 +04:00
talloc_free ( tmp_ctx ) ;
if ( in - > data & & ! out - > data ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-08-15 17:14:38 +04:00
return LDB_SUCCESS ;
}
2007-06-21 14:18:20 +04:00
}
2007-08-20 04:22:53 +04:00
* out = data_blob_string_const ( ldb_dn_alloc_casefold ( mem_ctx , dn1 ) ) ;
talloc_free ( tmp_ctx ) ;
if ( ! out - > data ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
2007-06-21 14:18:20 +04:00
return LDB_SUCCESS ;
2006-06-07 02:04:55 +04:00
}
static int ldif_comparison_objectCategory ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * v1 ,
const struct ldb_val * v2 )
{
2009-11-05 09:00:20 +03:00
return ldb_any_comparison ( ldb , mem_ctx , ldif_canonicalise_objectCategory ,
v1 , v2 ) ;
2006-06-07 02:04:55 +04:00
}
2008-05-29 12:38:17 +04:00
/*
convert a ldif formatted prefixMap to a NDR formatted blob
*/
static int ldif_read_prefixMap ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct prefixMapBlob * blob ;
enum ndr_err_code ndr_err ;
char * string , * line , * p , * oid ;
2009-10-11 22:00:55 +04:00
DATA_BLOB oid_blob ;
2008-05-29 12:38:17 +04:00
2008-05-29 14:01:32 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return - 1 ;
}
blob = talloc_zero ( tmp_ctx , struct prefixMapBlob ) ;
2008-05-29 12:38:17 +04:00
if ( blob = = NULL ) {
2008-05-29 14:01:32 +04:00
talloc_free ( blob ) ;
2008-05-29 12:38:17 +04:00
return - 1 ;
}
2008-05-29 14:01:32 +04:00
blob - > version = PREFIX_MAP_VERSION_DSDB ;
2008-05-29 12:38:17 +04:00
2008-05-29 14:01:32 +04:00
string = talloc_strndup ( mem_ctx , ( const char * ) in - > data , in - > length ) ;
if ( string = = NULL ) {
talloc_free ( blob ) ;
return - 1 ;
}
2008-05-29 12:38:17 +04:00
line = string ;
while ( line & & line [ 0 ] ) {
p = strchr ( line , ' ; ' ) ;
if ( p ) {
p [ 0 ] = ' \0 ' ;
} else {
2008-05-29 14:01:32 +04:00
p = strchr ( line , ' \n ' ) ;
2008-05-29 12:38:17 +04:00
if ( p ) {
p [ 0 ] = ' \0 ' ;
}
}
2008-05-29 14:01:32 +04:00
/* allow a traling seperator */
if ( line = = p ) {
break ;
}
2008-05-29 12:38:17 +04:00
blob - > ctr . dsdb . mappings = talloc_realloc ( blob ,
blob - > ctr . dsdb . mappings ,
struct drsuapi_DsReplicaOIDMapping ,
blob - > ctr . dsdb . num_mappings + 1 ) ;
if ( ! blob - > ctr . dsdb . mappings ) {
2008-05-29 14:01:32 +04:00
talloc_free ( tmp_ctx ) ;
2008-05-29 12:38:17 +04:00
return - 1 ;
}
2008-05-29 14:01:32 +04:00
blob - > ctr . dsdb . mappings [ blob - > ctr . dsdb . num_mappings ] . id_prefix = strtoul ( line , & oid , 10 ) ;
2008-05-29 12:38:17 +04:00
if ( oid [ 0 ] ! = ' : ' ) {
2008-05-29 14:01:32 +04:00
talloc_free ( tmp_ctx ) ;
2008-05-29 12:38:17 +04:00
return - 1 ;
}
/* we know there must be at least ":" */
oid + + ;
2009-10-11 22:00:55 +04:00
if ( ! ber_write_partial_OID_String ( blob - > ctr . dsdb . mappings , & oid_blob , oid ) ) {
talloc_free ( tmp_ctx ) ;
return - 1 ;
}
blob - > ctr . dsdb . mappings [ blob - > ctr . dsdb . num_mappings ] . oid . length = oid_blob . length ;
blob - > ctr . dsdb . mappings [ blob - > ctr . dsdb . num_mappings ] . oid . binary_oid = oid_blob . data ;
2008-05-29 12:38:17 +04:00
blob - > ctr . dsdb . num_mappings + + ;
2008-05-29 14:01:32 +04:00
/* Now look past the terminator we added above */
2008-05-29 12:38:17 +04:00
if ( p ) {
2008-05-29 14:01:32 +04:00
line = p + 1 ;
2008-05-29 12:38:17 +04:00
} else {
line = NULL ;
}
}
ndr_err = ndr_push_struct_blob ( out , mem_ctx ,
lp_iconv_convenience ( ldb_get_opaque ( ldb , " loadparm " ) ) ,
blob ,
( ndr_push_flags_fn_t ) ndr_push_prefixMapBlob ) ;
2008-05-29 14:01:32 +04:00
talloc_free ( tmp_ctx ) ;
2008-05-29 12:38:17 +04:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return - 1 ;
}
return 0 ;
}
/*
convert a NDR formatted blob to a ldif formatted prefixMap
*/
static int ldif_write_prefixMap ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
struct prefixMapBlob * blob ;
enum ndr_err_code ndr_err ;
2008-05-29 14:01:32 +04:00
char * string ;
2008-05-29 12:38:17 +04:00
uint32_t i ;
2009-09-08 16:02:59 +04:00
if ( ldb_get_flags ( ldb ) & LDB_FLG_SHOW_BINARY ) {
return ldif_write_NDR ( ldb , mem_ctx , in , out ,
sizeof ( struct prefixMapBlob ) ,
( ndr_pull_flags_fn_t ) ndr_pull_prefixMapBlob ,
( ndr_print_fn_t ) ndr_print_prefixMapBlob ) ;
}
2008-05-29 12:38:17 +04:00
blob = talloc ( mem_ctx , struct prefixMapBlob ) ;
if ( blob = = NULL ) {
return - 1 ;
}
2008-12-16 10:43:12 +03:00
ndr_err = ndr_pull_struct_blob_all ( in , blob ,
lp_iconv_convenience ( ldb_get_opaque ( ldb , " loadparm " ) ) ,
blob ,
( ndr_pull_flags_fn_t ) ndr_pull_prefixMapBlob ) ;
2008-05-29 12:38:17 +04:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2009-10-11 22:00:55 +04:00
goto failed ;
2008-05-29 12:38:17 +04:00
}
if ( blob - > version ! = PREFIX_MAP_VERSION_DSDB ) {
2009-10-11 22:00:55 +04:00
goto failed ;
2008-05-29 12:38:17 +04:00
}
2008-05-29 14:01:32 +04:00
string = talloc_strdup ( mem_ctx , " " ) ;
if ( string = = NULL ) {
2009-10-11 22:00:55 +04:00
goto failed ;
2008-05-29 12:38:17 +04:00
}
for ( i = 0 ; i < blob - > ctr . dsdb . num_mappings ; i + + ) {
2009-10-11 22:00:55 +04:00
DATA_BLOB oid_blob ;
const char * partial_oid = NULL ;
2008-05-29 12:38:17 +04:00
if ( i > 0 ) {
2008-05-29 14:01:32 +04:00
string = talloc_asprintf_append ( string , " ; " ) ;
2008-05-29 12:38:17 +04:00
}
2009-10-11 22:00:55 +04:00
oid_blob = data_blob_const ( blob - > ctr . dsdb . mappings [ i ] . oid . binary_oid ,
blob - > ctr . dsdb . mappings [ i ] . oid . length ) ;
if ( ! ber_read_partial_OID_String ( blob , oid_blob , & partial_oid ) ) {
DEBUG ( 0 , ( " ber_read_partial_OID failed on prefixMap item with id: 0x%X " ,
blob - > ctr . dsdb . mappings [ i ] . id_prefix ) ) ;
goto failed ;
}
2008-05-29 14:16:18 +04:00
string = talloc_asprintf_append ( string , " %u:%s " ,
2008-05-29 12:38:17 +04:00
blob - > ctr . dsdb . mappings [ i ] . id_prefix ,
2009-10-11 22:00:55 +04:00
partial_oid ) ;
talloc_free ( discard_const ( partial_oid ) ) ;
2008-05-29 14:01:32 +04:00
if ( string = = NULL ) {
2009-10-11 22:00:55 +04:00
goto failed ;
2008-05-29 12:38:17 +04:00
}
}
talloc_free ( blob ) ;
2008-05-29 14:01:32 +04:00
* out = data_blob_string_const ( string ) ;
2008-05-29 12:38:17 +04:00
return 0 ;
2009-10-11 22:00:55 +04:00
failed :
talloc_free ( blob ) ;
return - 1 ;
2008-05-29 12:38:17 +04:00
}
static bool ldif_comparision_prefixMap_isString ( const struct ldb_val * v )
{
if ( v - > length < 4 ) {
return true ;
}
if ( IVAL ( v - > data , 0 ) = = PREFIX_MAP_VERSION_DSDB ) {
return false ;
}
return true ;
}
/*
canonicalise a prefixMap
*/
static int ldif_canonicalise_prefixMap ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
if ( ldif_comparision_prefixMap_isString ( in ) ) {
return ldif_read_prefixMap ( ldb , mem_ctx , in , out ) ;
}
return ldb_handler_copy ( ldb , mem_ctx , in , out ) ;
}
static int ldif_comparison_prefixMap ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * v1 ,
const struct ldb_val * v2 )
{
2009-11-05 09:00:20 +03:00
return ldb_any_comparison ( ldb , mem_ctx , ldif_canonicalise_prefixMap ,
v1 , v2 ) ;
2008-05-29 12:38:17 +04:00
}
2009-12-29 03:38:17 +03:00
/* length limited conversion of a ldb_val to a int32_t */
static int val_to_int32 ( const struct ldb_val * in , int32_t * v )
2009-06-18 13:05:45 +04:00
{
char * end ;
2009-12-29 03:38:17 +03:00
char buf [ 64 ] ;
/* make sure we don't read past the end of the data */
if ( in - > length > sizeof ( buf ) - 1 ) {
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX ;
}
strncpy ( buf , ( char * ) in - > data , in - > length ) ;
buf [ in - > length ] = 0 ;
2009-08-17 22:29:11 +04:00
/* We've to use "strtoll" here to have the intended overflows.
* Otherwise we may get " LONG_MAX " and the conversion is wrong . */
2009-12-29 03:38:17 +03:00
* v = ( int32_t ) strtoll ( buf , & end , 0 ) ;
2009-06-18 13:05:45 +04:00
if ( * end ! = 0 ) {
2009-12-29 03:38:17 +03:00
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX ;
}
return LDB_SUCCESS ;
}
/* Canonicalisation of two 32-bit integers */
static int ldif_canonicalise_int32 ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
int32_t i ;
int ret ;
ret = val_to_int32 ( in , & i ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
2009-06-18 13:05:45 +04:00
}
out - > data = ( uint8_t * ) talloc_asprintf ( mem_ctx , " %d " , i ) ;
if ( out - > data = = NULL ) {
2009-12-29 03:38:17 +03:00
ldb_oom ( ldb ) ;
return LDB_ERR_OPERATIONS_ERROR ;
2009-06-18 13:05:45 +04:00
}
out - > length = strlen ( ( char * ) out - > data ) ;
return 0 ;
}
/* Comparison of two 32-bit integers */
static int ldif_comparison_int32 ( struct ldb_context * ldb , void * mem_ctx ,
2009-12-29 03:38:17 +03:00
const struct ldb_val * v1 , const struct ldb_val * v2 )
2009-06-18 13:05:45 +04:00
{
2009-12-29 03:38:17 +03:00
int32_t i1 = 0 , i2 = 0 ;
val_to_int32 ( v1 , & i1 ) ;
val_to_int32 ( v2 , & i2 ) ;
if ( i1 = = i2 ) return 0 ;
return i1 > i2 ? 1 : - 1 ;
2009-06-18 13:05:45 +04:00
}
2009-09-08 15:45:08 +04:00
/*
convert a NDR formatted blob to a ldif formatted repsFromTo
*/
static int ldif_write_repsFromTo ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
return ldif_write_NDR ( ldb , mem_ctx , in , out ,
sizeof ( struct repsFromToBlob ) ,
( ndr_pull_flags_fn_t ) ndr_pull_repsFromToBlob ,
( ndr_print_fn_t ) ndr_print_repsFromToBlob ) ;
}
2009-09-08 16:15:59 +04:00
/*
convert a NDR formatted blob to a ldif formatted replPropertyMetaData
*/
static int ldif_write_replPropertyMetaData ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
return ldif_write_NDR ( ldb , mem_ctx , in , out ,
sizeof ( struct replPropertyMetaDataBlob ) ,
( ndr_pull_flags_fn_t ) ndr_pull_replPropertyMetaDataBlob ,
( ndr_print_fn_t ) ndr_print_replPropertyMetaDataBlob ) ;
}
/*
convert a NDR formatted blob to a ldif formatted replUpToDateVector
*/
static int ldif_write_replUpToDateVector ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
return ldif_write_NDR ( ldb , mem_ctx , in , out ,
sizeof ( struct replUpToDateVectorBlob ) ,
( ndr_pull_flags_fn_t ) ndr_pull_replUpToDateVectorBlob ,
2009-10-14 08:57:15 +04:00
( ndr_print_fn_t ) ndr_print_replUpToDateVectorBlob ) ;
2009-09-08 16:15:59 +04:00
}
2009-09-08 15:45:08 +04:00
2008-12-16 10:43:12 +03:00
static int extended_dn_write_hex ( struct ldb_context * ldb , void * mem_ctx ,
const struct ldb_val * in , struct ldb_val * out )
{
2009-11-04 09:42:53 +03:00
* out = data_blob_string_const ( data_blob_hex_string_lower ( mem_ctx , in ) ) ;
2008-12-16 10:43:12 +03:00
if ( ! out - > data ) {
return - 1 ;
}
return 0 ;
}
2006-12-15 16:08:57 +03:00
static const struct ldb_schema_syntax samba_syntaxes [ ] = {
2006-11-25 18:43:56 +03:00
{
2008-12-16 10:43:12 +03:00
. name = LDB_SYNTAX_SAMBA_SID ,
. ldif_read_fn = ldif_read_objectSid ,
. ldif_write_fn = ldif_write_objectSid ,
2009-06-18 13:05:45 +04:00
. canonicalise_fn = ldif_canonicalise_objectSid ,
. comparison_fn = ldif_comparison_objectSid
2008-12-16 10:43:12 +03:00
} , {
. name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR ,
. ldif_read_fn = ldif_read_ntSecurityDescriptor ,
. ldif_write_fn = ldif_write_ntSecurityDescriptor ,
. canonicalise_fn = ldb_handler_copy ,
. comparison_fn = ldb_comparison_binary
} , {
. name = LDB_SYNTAX_SAMBA_GUID ,
. ldif_read_fn = ldif_read_objectGUID ,
. ldif_write_fn = ldif_write_objectGUID ,
2009-06-18 13:05:45 +04:00
. canonicalise_fn = ldif_canonicalise_objectGUID ,
. comparison_fn = ldif_comparison_objectGUID
2006-12-15 16:08:57 +03:00
} , {
2008-12-16 10:43:12 +03:00
. name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldb_handler_copy ,
. canonicalise_fn = ldif_canonicalise_objectCategory ,
. comparison_fn = ldif_comparison_objectCategory
2006-12-15 16:08:57 +03:00
} , {
2008-12-16 10:43:12 +03:00
. name = LDB_SYNTAX_SAMBA_PREFIX_MAP ,
. ldif_read_fn = ldif_read_prefixMap ,
. ldif_write_fn = ldif_write_prefixMap ,
. canonicalise_fn = ldif_canonicalise_prefixMap ,
. comparison_fn = ldif_comparison_prefixMap
2009-06-18 13:05:45 +04:00
} , {
. name = LDB_SYNTAX_SAMBA_INT32 ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldb_handler_copy ,
. canonicalise_fn = ldif_canonicalise_int32 ,
. comparison_fn = ldif_comparison_int32
2009-09-08 15:45:08 +04:00
} , {
. name = LDB_SYNTAX_SAMBA_REPSFROMTO ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldif_write_repsFromTo ,
. canonicalise_fn = ldb_handler_copy ,
. comparison_fn = ldb_comparison_binary
2009-09-08 16:15:59 +04:00
} , {
. name = LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldif_write_replPropertyMetaData ,
. canonicalise_fn = ldb_handler_copy ,
. comparison_fn = ldb_comparison_binary
} , {
. name = LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldif_write_replUpToDateVector ,
. canonicalise_fn = ldb_handler_copy ,
. comparison_fn = ldb_comparison_binary
2009-11-05 09:04:10 +03:00
} , {
. name = DSDB_SYNTAX_BINARY_DN ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldb_handler_copy ,
. canonicalise_fn = dsdb_dn_binary_canonicalise ,
. comparison_fn = dsdb_dn_binary_comparison
} , {
. name = DSDB_SYNTAX_STRING_DN ,
. ldif_read_fn = ldb_handler_copy ,
. ldif_write_fn = ldb_handler_copy ,
. canonicalise_fn = dsdb_dn_string_canonicalise ,
. comparison_fn = dsdb_dn_string_comparison
2009-09-08 15:45:08 +04:00
} ,
2008-12-16 10:43:12 +03:00
} ;
static const struct ldb_dn_extended_syntax samba_dn_syntax [ ] = {
{
. name = " SID " ,
. read_fn = extended_dn_read_SID ,
. write_clear_fn = ldif_write_objectSid ,
. write_hex_fn = extended_dn_write_hex
2006-12-15 16:08:57 +03:00
} , {
2008-12-16 10:43:12 +03:00
. name = " GUID " ,
. read_fn = extended_dn_read_GUID ,
. write_clear_fn = ldif_write_objectGUID ,
. write_hex_fn = extended_dn_write_hex
2008-05-29 12:38:17 +04:00
} , {
2008-12-16 10:43:12 +03:00
. name = " WKGUID " ,
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
2009-12-10 15:45:16 +03:00
} , {
. name = " RMD_INVOCID " ,
. read_fn = extended_dn_read_GUID ,
. write_clear_fn = ldif_write_objectGUID ,
. write_hex_fn = extended_dn_write_hex
} , {
2010-01-02 00:14:52 +03:00
. name = " RMD_FLAGS " ,
2009-12-10 15:45:16 +03:00
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
} , {
. name = " RMD_ADDTIME " ,
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
} , {
. name = " RMD_CHANGETIME " ,
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
} , {
2009-12-18 04:47:31 +03:00
. name = " RMD_LOCAL_USN " ,
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
} , {
. name = " RMD_ORIGINATING_USN " ,
2009-12-10 15:45:16 +03:00
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
} , {
. name = " RMD_VERSION " ,
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy
r8037: a fairly major update to the internals of ldb. Changes are:
- moved the knowledge of attribute types out of ldb_tdb and into the
generic ldb code. This allows the ldb_match() message match logic
to be generic, so it can be used by other backend
- added the generic ability to load attribute handlers, for
canonicalisation, compare, ldif read and ldif write. In the future
this will be used by the schema module to allow us to correctly
obey the attributetype schema elements
- added attribute handlers for some of the core ldap attribute types,
Integer, DirectoryString, DN, ObjectClass etc
- added automatic registration of attribute handlers for well-known
attribute names 'cn', 'dc', 'dn', 'ou' and 'objectClass'
- converted the objectSid special handlers for Samba to the new system
- added more correct handling of indexing in tdb backend based on the
attribute canonicalisation function
- added generic support for subclasses, moving it out of the tdb
backend. This will be used in future by the schema module
- fixed several bugs in the dn_explode code. It still needs more
work, but doesn't corrupt ldb dbs any more.
(This used to be commit 944c5844ab441b96d8e5d7b2d151982139d1fab9)
2005-07-01 10:21:26 +04:00
}
2005-06-21 11:52:00 +04:00
} ;
2009-06-18 13:05:45 +04:00
/* TODO: Should be dynamic at some point */
2006-12-15 16:08:57 +03:00
static const struct {
const char * name ;
const char * syntax ;
} samba_attributes [ ] = {
{ " objectSid " , LDB_SYNTAX_SAMBA_SID } ,
{ " securityIdentifier " , LDB_SYNTAX_SAMBA_SID } ,
{ " ntSecurityDescriptor " , LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR } ,
{ " objectGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " invocationId " , LDB_SYNTAX_SAMBA_GUID } ,
{ " schemaIDGUID " , LDB_SYNTAX_SAMBA_GUID } ,
2009-11-13 18:58:20 +03:00
{ " oMSyntax " , LDB_SYNTAX_SAMBA_INT32 } ,
2006-12-15 16:08:57 +03:00
{ " attributeSecurityGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " parentGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " siteGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " pKTGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " fRSVersionGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " fRSReplicaSetGUID " , LDB_SYNTAX_SAMBA_GUID } ,
{ " netbootGUID " , LDB_SYNTAX_SAMBA_GUID } ,
2009-12-18 03:43:21 +03:00
{ " msDS-OptionalFeatureGUID " , LDB_SYNTAX_SAMBA_GUID } ,
2006-12-15 16:08:57 +03:00
{ " objectCategory " , LDB_SYNTAX_SAMBA_OBJECT_CATEGORY } ,
2009-09-08 15:45:08 +04:00
{ " prefixMap " , LDB_SYNTAX_SAMBA_PREFIX_MAP } ,
{ " repsFrom " , LDB_SYNTAX_SAMBA_REPSFROMTO } ,
{ " repsTo " , LDB_SYNTAX_SAMBA_REPSFROMTO } ,
2009-09-08 16:15:59 +04:00
{ " replPropertyMetaData " , LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA } ,
{ " replUpToDateVector " , LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR } ,
2006-12-15 16:08:57 +03:00
} ;
2008-08-18 14:30:27 +04:00
const struct ldb_schema_syntax * ldb_samba_syntax_by_name ( struct ldb_context * ldb , const char * name )
{
uint32_t j ;
const struct ldb_schema_syntax * s = NULL ;
for ( j = 0 ; j < ARRAY_SIZE ( samba_syntaxes ) ; j + + ) {
if ( strcmp ( name , samba_syntaxes [ j ] . name ) = = 0 ) {
s = & samba_syntaxes [ j ] ;
break ;
}
}
return s ;
}
2009-04-02 09:42:21 +04:00
const struct ldb_schema_syntax * ldb_samba_syntax_by_lDAPDisplayName ( struct ldb_context * ldb , const char * name )
{
uint32_t j ;
const struct ldb_schema_syntax * s = NULL ;
for ( j = 0 ; j < ARRAY_SIZE ( samba_attributes ) ; j + + ) {
if ( strcmp ( samba_attributes [ j ] . name , name ) = = 0 ) {
s = ldb_samba_syntax_by_name ( ldb , samba_attributes [ j ] . syntax ) ;
break ;
}
}
return s ;
}
2008-08-18 14:30:27 +04:00
2005-06-21 11:52:00 +04:00
/*
register the samba ldif handlers
*/
int ldb_register_samba_handlers ( struct ldb_context * ldb )
{
2006-12-15 16:08:57 +03:00
uint32_t i ;
for ( i = 0 ; i < ARRAY_SIZE ( samba_attributes ) ; i + + ) {
int ret ;
2007-05-07 01:28:03 +04:00
const struct ldb_schema_syntax * s = NULL ;
2006-12-15 16:08:57 +03:00
2008-08-18 14:30:27 +04:00
s = ldb_samba_syntax_by_name ( ldb , samba_attributes [ i ] . syntax ) ;
2006-12-15 16:08:57 +03:00
if ( ! s ) {
s = ldb_standard_syntax_by_name ( ldb , samba_attributes [ i ] . syntax ) ;
}
if ( ! s ) {
return - 1 ;
}
2008-08-21 06:56:04 +04:00
ret = ldb_schema_attribute_add_with_syntax ( ldb , samba_attributes [ i ] . name , LDB_ATTR_FLAG_FIXED , s ) ;
2006-12-15 16:08:57 +03:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
2008-12-16 10:43:12 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( samba_dn_syntax ) ; i + + ) {
int ret ;
ret = ldb_dn_extended_add_syntax ( ldb , LDB_ATTR_FLAG_FIXED , & samba_dn_syntax [ i ] ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
}
2006-12-15 16:08:57 +03:00
return LDB_SUCCESS ;
2005-06-21 11:52:00 +04:00
}