2005-06-27 00:00:50 +00:00
/*
ldb database library
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 06:21:26 +00:00
Copyright ( C ) Simo Sorce 2005
2005-06-27 00:00:50 +00: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
version 2 of the License , or ( at your option ) any later version .
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
License along with this library ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/*
* Name : ldb
*
* Component : ldb dn explode and utility functions
*
* Description : - explode a dn into it ' s own basic elements
* and put them in a structure
* - manipulate ldb_dn structures
*
* Author : Simo Sorce
*/
# include "includes.h"
2006-01-10 16:48:32 +00:00
# include "ldb/include/includes.h"
2005-06-27 00:00:50 +00: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 06:21:26 +00:00
# define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
2005-06-27 00:00:50 +00:00
2005-08-18 15:02:01 +00:00
# define LDB_SPECIAL "@SPECIAL"
2005-08-18 16:41:27 +00:00
int ldb_dn_is_special ( const struct ldb_dn * dn )
2005-08-18 15:02:01 +00:00
{
if ( dn = = NULL | | dn - > comp_num ! = 1 ) return 0 ;
return ! strcmp ( dn - > components [ 0 ] . name , LDB_SPECIAL ) ;
}
2005-08-18 16:41:27 +00:00
int ldb_dn_check_special ( const struct ldb_dn * dn , const char * check )
2005-08-18 15:02:01 +00:00
{
if ( dn = = NULL | | dn - > comp_num ! = 1 ) return 0 ;
2005-10-12 06:10:23 +00:00
return ! strcmp ( ( char * ) dn - > components [ 0 ] . value . data , check ) ;
2005-08-18 15:02:01 +00:00
}
2005-08-18 11:15:15 +00:00
char * ldb_dn_escape_value ( void * mem_ctx , struct ldb_val value )
2005-06-27 00:00:50 +00:00
{
2005-07-02 17:30:03 +00:00
const char * p , * s , * src ;
char * d , * dst ;
int len ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
if ( ! value . length )
return NULL ;
p = s = src = ( const char * ) value . data ;
len = value . length ;
2005-06-27 00:00:50 +00:00
/* allocate destination string, it will be at most 3 times the source */
2005-07-02 17:30:03 +00:00
dst = d = talloc_array ( mem_ctx , char , len * 3 + 1 ) ;
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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( dst ) ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
while ( p - src < len ) {
2005-06-27 00:00:50 +00:00
p + = strcspn ( p , " ,= \n +<>#; \\ \" " ) ;
2005-07-02 17:30:03 +00:00
if ( p - src = = len ) /* found no escapable chars */
2005-06-27 00:00:50 +00:00
break ;
2005-07-02 17:30:03 +00:00
memcpy ( d , s , p - s ) ; /* copy the part of the string before the stop */
d + = ( p - s ) ; /* move to current position */
if ( * p ) { /* it is a normal escapable character */
2005-06-27 00:00:50 +00:00
* d + + = ' \\ ' ;
* d + + = * p + + ;
2005-07-02 17:30:03 +00:00
} else { /* we have a zero byte in the string */
strncpy ( d , " \00 " , 3 ) ; /* escape the zero */
d = d + 3 ;
p + + ; /* skip the zero */
2005-06-27 00:00:50 +00:00
}
2005-07-02 17:30:03 +00:00
s = p ; /* move forward */
2005-06-27 00:00:50 +00:00
}
/* copy the last part (with zero) and return */
2005-07-02 17:30:03 +00:00
memcpy ( d , s , & src [ len ] - s + 1 ) ;
2005-06-27 00:00:50 +00:00
return dst ;
2005-07-02 17:30:03 +00: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 06:21:26 +00:00
failed :
talloc_free ( dst ) ;
return NULL ;
2005-06-27 00:00:50 +00:00
}
2005-07-02 17:30:03 +00:00
static struct ldb_val ldb_dn_unescape_value ( void * mem_ctx , const char * src )
2005-06-27 00:00:50 +00:00
{
2005-07-02 17:30:03 +00:00
struct ldb_val value ;
2005-06-27 00:00:50 +00:00
unsigned x ;
2005-07-02 17:30:03 +00:00
char * p , * dst = NULL , * end ;
2005-10-12 08:51:12 +00:00
memset ( & value , 0 , sizeof ( value ) ) ;
2005-06-27 00:00:50 +00: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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( src ) ;
2005-06-27 00:00:50 +00:00
2006-10-09 08:00:18 +00:00
dst = p = ( char * ) talloc_memdup ( mem_ctx , src , strlen ( src ) + 1 ) ;
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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( dst ) ;
2005-06-27 00:00:50 +00:00
end = & dst [ strlen ( dst ) ] ;
while ( * p ) {
p + = strcspn ( p , " ,= \n +<>#; \\ \" " ) ;
if ( * p = = ' \\ ' ) {
if ( strchr ( " ,= \n +<>#; \\ \" " , p [ 1 ] ) ) {
memmove ( p , p + 1 , end - ( p + 1 ) + 1 ) ;
end - - ;
p + + ;
continue ;
}
if ( sscanf ( p + 1 , " %02x " , & x ) = = 1 ) {
* p = ( unsigned char ) x ;
memmove ( p + 1 , p + 3 , end - ( p + 3 ) + 1 ) ;
end - = 2 ;
p + + ;
continue ;
}
}
2005-07-02 17:30:03 +00:00
/* a string with not escaped specials is invalid (tested) */
if ( * p ! = ' \0 ' ) {
goto failed ;
}
2005-06-27 00:00:50 +00:00
}
2005-07-02 17:30:03 +00:00
value . length = end - dst ;
2005-10-12 06:10:23 +00:00
value . data = ( uint8_t * ) dst ;
2005-07-02 17:30:03 +00:00
return value ;
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 06:21:26 +00:00
failed :
talloc_free ( dst ) ;
2005-07-02 17:30:03 +00:00
return value ;
2005-06-27 00:00:50 +00:00
}
2005-07-02 17:30:03 +00:00
/* check if the string contains quotes
* skips leading and trailing spaces
* - returns 0 if no quotes found
* - returns 1 if quotes are found and put their position
* in * quote_start and * quote_end parameters
* - return - 1 if there are open quotes
*/
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
static int get_quotes_position ( const char * source , int * quote_start , int * quote_end )
{
const char * p ;
2005-06-27 00:00:50 +00:00
2005-08-18 15:02:01 +00:00
if ( source = = NULL | | quote_start = = NULL | | quote_end = = NULL ) return - 1 ;
2005-07-02 17:30:03 +00:00
p = source ;
2005-06-27 00:00:50 +00:00
/* check if there are quotes surrounding the value */
2005-07-02 17:30:03 +00:00
p + = strspn ( p , " \n " ) ; /* skip white spaces */
2005-06-27 00:00:50 +00:00
if ( * p = = ' \" ' ) {
2005-07-02 17:30:03 +00:00
* quote_start = p - source ;
2005-06-27 00:00:50 +00:00
p + + ;
while ( * p ! = ' \" ' ) {
p = strchr ( p , ' \" ' ) ;
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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( p ) ;
2005-06-27 00:00:50 +00:00
if ( * ( p - 1 ) = = ' \\ ' )
p + + ;
}
2005-07-02 17:30:03 +00:00
* quote_end = p - source ;
return 1 ;
}
return 0 ;
failed :
return - 1 ;
}
static char * seek_to_separator ( char * string , const char * separators )
{
2006-01-06 21:39:37 +00:00
char * p , * q ;
int ret , qs , qe , escaped ;
2005-07-02 17:30:03 +00:00
2005-08-18 15:02:01 +00:00
if ( string = = NULL | | separators = = NULL ) return NULL ;
2005-07-02 17:30:03 +00:00
p = strchr ( string , ' = ' ) ;
LDB_DN_NULL_FAILED ( p ) ;
p + + ;
/* check if there are quotes surrounding the value */
ret = get_quotes_position ( p , & qs , & qe ) ;
if ( ret = = - 1 )
return NULL ;
if ( ret = = 1 ) { /* quotes found */
p + = qe ; /* positioning after quotes */
p + = strspn ( p , " \n " ) ; /* skip white spaces after the quote */
if ( strcspn ( p , separators ) ! = 0 ) /* if there are characters between quotes */
return NULL ; /* and separators, the dn is invalid */
return p ; /* return on the separator */
2005-06-27 00:00:50 +00:00
}
2005-07-02 17:30:03 +00:00
/* no quotes found seek to separators */
2006-01-06 21:39:37 +00:00
q = p ;
do {
escaped = 0 ;
ret = strcspn ( q , separators ) ;
if ( q [ ret - 1 ] = = ' \\ ' ) {
escaped = 1 ;
q = q + ret + 1 ;
}
} while ( escaped ) ;
if ( ret = = 0 & & p = = q ) /* no separators ?! bail out */
2005-07-02 17:30:03 +00:00
return NULL ;
2005-06-27 00:00:50 +00:00
2006-01-06 21:39:37 +00:00
return q + ret ;
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 06:21:26 +00:00
failed :
return NULL ;
2005-06-27 00:00:50 +00:00
}
static char * ldb_dn_trim_string ( char * string , const char * edge )
{
char * s , * p ;
/* seek out edge from start of string */
s = string + strspn ( string , edge ) ;
/* backwards skip from end of string */
p = & s [ strlen ( s ) - 1 ] ;
while ( p > s & & strchr ( edge , * p ) ) {
* p = ' \0 ' ;
p - - ;
}
return s ;
}
2005-07-02 17:30:03 +00:00
/* we choosed to not support multpile valued components */
static struct ldb_dn_component ldb_dn_explode_component ( void * mem_ctx , char * raw_component )
2005-06-27 00:00:50 +00:00
{
2005-07-02 17:30:03 +00:00
struct ldb_dn_component dc ;
2005-06-27 00:00:50 +00:00
char * p ;
2005-07-02 17:30:03 +00:00
int ret , qs , qe ;
2005-06-27 00:00:50 +00:00
2005-10-12 08:51:12 +00:00
memset ( & dc , 0 , sizeof ( dc ) ) ;
2005-08-18 15:02:01 +00:00
if ( raw_component = = NULL ) {
return dc ;
}
2005-07-02 17:30:03 +00:00
/* find attribute type/value separator */
p = strchr ( raw_component , ' = ' ) ;
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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( p ) ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
* p + + = ' \0 ' ; /* terminate name and point to value */
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
/* copy and trim name in the component */
dc . name = talloc_strdup ( mem_ctx , ldb_dn_trim_string ( raw_component , " \n " ) ) ;
if ( ! dc . name )
return dc ;
2005-06-27 00:00:50 +00:00
2006-02-04 00:38:48 +00:00
if ( ! ldb_valid_attr_name ( dc . name ) ) {
2005-07-02 18:34:13 +00:00
goto failed ;
}
2005-07-02 17:30:03 +00:00
ret = get_quotes_position ( p , & qs , & qe ) ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
switch ( ret ) {
case 0 : /* no quotes trim the string */
p = ldb_dn_trim_string ( p , " \n " ) ;
dc . value = ldb_dn_unescape_value ( mem_ctx , p ) ;
break ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
case 1 : /* quotes found get the unquoted string */
p [ qe ] = ' \0 ' ;
p = p + qs + 1 ;
dc . value . length = strlen ( p ) ;
2006-10-09 08:00:18 +00:00
dc . value . data = ( uint8_t * ) talloc_memdup ( mem_ctx , p ,
dc . value . length + 1 ) ;
2005-07-02 17:30:03 +00:00
break ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
default : /* mismatched quotes ot other error, bail out */
goto failed ;
2005-06-27 00:00:50 +00:00
}
2005-07-02 17:30:03 +00:00
if ( dc . value . length = = 0 ) {
goto failed ;
}
2005-06-27 00:00:50 +00:00
return dc ;
2005-07-02 17:30:03 +00:00
failed :
talloc_free ( dc . name ) ;
dc . name = NULL ;
return dc ;
2005-06-27 00:00:50 +00:00
}
2005-08-18 15:02:01 +00:00
struct ldb_dn * ldb_dn_new ( void * mem_ctx )
2005-06-27 00:00:50 +00:00
{
2005-08-18 15:02:01 +00:00
struct ldb_dn * edn ;
2005-06-27 00:00:50 +00:00
edn = talloc ( mem_ctx , struct ldb_dn ) ;
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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( edn ) ;
2005-06-27 00:00:50 +00:00
/* Initially there are no components */
edn - > comp_num = 0 ;
edn - > components = NULL ;
2005-08-18 15:02:01 +00:00
return edn ;
failed :
return NULL ;
}
2006-10-17 01:18:47 +00:00
/*
explode a DN string into a ldb_dn structure
*/
2005-08-18 15:02:01 +00:00
struct ldb_dn * ldb_dn_explode ( void * mem_ctx , const char * dn )
{
struct ldb_dn * edn ; /* the exploded dn */
char * pdn , * p ;
if ( dn = = NULL ) return NULL ;
/* Allocate a structure to hold the exploded DN */
edn = ldb_dn_new ( mem_ctx ) ;
2006-10-04 19:03:29 +00:00
if ( edn = = NULL ) {
return NULL ;
}
2005-08-18 16:27:09 +00:00
pdn = NULL ;
2005-08-18 15:02:01 +00:00
/* Empty DNs */
if ( dn [ 0 ] = = ' \0 ' ) {
return edn ;
}
2005-07-12 12:04:54 +00:00
/* Special DNs case */
if ( dn [ 0 ] = = ' @ ' ) {
edn - > comp_num = 1 ;
edn - > components = talloc ( edn , struct ldb_dn_component ) ;
if ( edn - > components = = NULL ) goto failed ;
2005-08-18 15:02:01 +00:00
edn - > components [ 0 ] . name = talloc_strdup ( edn - > components , LDB_SPECIAL ) ;
2005-07-12 12:04:54 +00:00
if ( edn - > components [ 0 ] . name = = NULL ) goto failed ;
2005-10-12 06:10:23 +00:00
edn - > components [ 0 ] . value . data = ( uint8_t * ) talloc_strdup ( edn - > components , dn ) ;
2005-07-12 12:04:54 +00:00
if ( edn - > components [ 0 ] . value . data = = NULL ) goto failed ;
edn - > components [ 0 ] . value . length = strlen ( dn ) ;
return edn ;
}
2005-06-27 00:00:50 +00:00
pdn = p = talloc_strdup ( edn , dn ) ;
2005-07-02 17:30:03 +00:00
LDB_DN_NULL_FAILED ( pdn ) ;
2005-06-27 00:00:50 +00:00
/* get the components */
do {
char * t ;
/* terminate the current component and return pointer to the next one */
t = seek_to_separator ( p , " ,; " ) ;
2005-07-02 17:30:03 +00:00
LDB_DN_NULL_FAILED ( t ) ;
2005-06-27 00:00:50 +00:00
if ( * t ) { /* here there is a separator */
* t = ' \0 ' ; /*terminate */
2005-07-02 17:30:03 +00:00
t + + ; /* a separtor means another component follows */
2005-06-27 00:00:50 +00:00
}
/* allocate space to hold the dn component */
edn - > components = talloc_realloc ( edn , edn - > components ,
2005-07-02 17:30:03 +00:00
struct ldb_dn_component ,
2005-06-27 00:00:50 +00:00
edn - > comp_num + 1 ) ;
if ( edn - > components = = NULL )
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 06:21:26 +00:00
goto failed ;
2005-06-27 00:00:50 +00:00
/* store the exploded component in the main structure */
2005-07-02 17:30:03 +00:00
edn - > components [ edn - > comp_num ] = ldb_dn_explode_component ( edn , p ) ;
LDB_DN_NULL_FAILED ( edn - > components [ edn - > comp_num ] . name ) ;
2005-06-27 00:00:50 +00:00
edn - > comp_num + + ;
/* jump to the next component if any */
p = t ;
} while ( * p ) ;
talloc_free ( pdn ) ;
return edn ;
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 06:21:26 +00:00
failed :
2005-07-02 17:30:03 +00:00
talloc_free ( pdn ) ;
2005-06-27 00:00:50 +00:00
talloc_free ( edn ) ;
return NULL ;
}
2006-01-06 04:01:23 +00:00
struct ldb_dn * ldb_dn_explode_or_special ( void * mem_ctx , const char * dn )
{
struct ldb_dn * edn ; /* the exploded dn */
if ( dn = = NULL ) return NULL ;
if ( strncasecmp ( dn , " <GUID= " , 6 ) = = 0 ) {
/* this is special DN returned when the
* exploded_dn control is used
*/
/* Allocate a structure to hold the exploded DN */
edn = ldb_dn_new ( mem_ctx ) ;
edn - > comp_num = 1 ;
edn - > components = talloc ( edn , struct ldb_dn_component ) ;
if ( edn - > components = = NULL ) goto failed ;
edn - > components [ 0 ] . name = talloc_strdup ( edn - > components , LDB_SPECIAL ) ;
if ( edn - > components [ 0 ] . name = = NULL ) goto failed ;
edn - > components [ 0 ] . value . data = ( uint8_t * ) talloc_strdup ( edn - > components , dn ) ;
if ( edn - > components [ 0 ] . value . data = = NULL ) goto failed ;
edn - > components [ 0 ] . value . length = strlen ( dn ) ;
return edn ;
}
return ldb_dn_explode ( mem_ctx , dn ) ;
failed :
talloc_free ( edn ) ;
return NULL ;
}
2005-07-02 17:30:03 +00:00
char * ldb_dn_linearize ( void * mem_ctx , const struct ldb_dn * edn )
2005-06-27 00:00:50 +00:00
{
2005-07-02 17:30:03 +00:00
char * dn , * value ;
int i ;
2005-06-27 00:00:50 +00:00
2005-08-18 15:02:01 +00:00
if ( edn = = NULL ) return NULL ;
2005-07-12 12:04:54 +00:00
/* Special DNs */
2005-08-18 15:02:01 +00:00
if ( ldb_dn_is_special ( edn ) ) {
2005-10-12 06:10:23 +00:00
dn = talloc_strdup ( mem_ctx , ( char * ) edn - > components [ 0 ] . value . data ) ;
2005-07-12 12:04:54 +00:00
return dn ;
}
2005-06-27 00:00:50 +00:00
dn = talloc_strdup ( 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 06:21:26 +00:00
LDB_DN_NULL_FAILED ( dn ) ;
2005-06-27 00:00:50 +00:00
for ( i = 0 ; i < edn - > comp_num ; i + + ) {
2005-07-02 17:30:03 +00:00
value = ldb_dn_escape_value ( dn , edn - > components [ i ] . value ) ;
LDB_DN_NULL_FAILED ( value ) ;
2005-06-27 00:00:50 +00:00
2005-07-04 15:06:05 +00:00
if ( i = = 0 ) {
dn = talloc_asprintf_append ( dn , " %s=%s " , edn - > components [ i ] . name , value ) ;
} else {
dn = talloc_asprintf_append ( dn , " ,%s=%s " , edn - > components [ i ] . name , value ) ;
}
2005-07-02 17:30:03 +00:00
LDB_DN_NULL_FAILED ( dn ) ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
talloc_free ( value ) ;
2005-06-27 00:00:50 +00:00
}
return dn ;
2005-07-02 17:30:03 +00: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 06:21:26 +00:00
failed :
talloc_free ( dn ) ;
return NULL ;
2005-06-27 00:00:50 +00:00
}
2006-06-08 01:00:46 +00:00
/* Determine if dn is below base, in the ldap tree. Used for
* evaluating a subtree search .
* 0 if they match , otherwise non - zero
*/
2005-07-12 12:04:54 +00:00
int ldb_dn_compare_base ( struct ldb_context * ldb ,
2006-06-08 01:00:46 +00:00
const struct ldb_dn * base ,
const struct ldb_dn * dn )
2005-06-27 00:00:50 +00:00
{
2005-07-17 09:06:58 +00:00
int ret ;
2005-07-12 12:04:54 +00:00
int n0 , n1 ;
2005-06-27 00:00:50 +00:00
2006-06-08 01:00:46 +00:00
if ( base = = NULL | | base - > comp_num = = 0 ) return 0 ;
if ( dn = = NULL | | dn - > comp_num = = 0 ) return - 1 ;
2006-07-11 03:44:51 +00:00
/* if the base has more componts than the dn, then they differ */
r9318: fix searches with scope ONE and SUB,
the problem was that ldb_dn_compare_base() just looked at if
both dn's mtach some how, and the following happens:
basedn: CN=bar,DC=foo,DC=com
dn: DC=foo,DC=com
and dn: DC=foo,DC=com was return as result of a sub and base search
and also the ONE search with
basedn: DC=foo,DC=com
returned this
dn: CN=bla,CN=bar,DC=foo,DC=com
metze
(This used to be commit 2a107472c373e425013050e28b944c830f653a87)
2005-08-16 06:55:40 +00:00
if ( base - > comp_num > dn - > comp_num ) {
return ( dn - > comp_num - base - > comp_num ) ;
}
2005-07-12 12:04:54 +00:00
n0 = base - > comp_num - 1 ;
n1 = dn - > comp_num - 1 ;
2005-07-17 09:06:58 +00:00
while ( n0 > = 0 & & n1 > = 0 ) {
2005-07-02 17:30:03 +00:00
const struct ldb_attrib_handler * h ;
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
/* compare names (attribute names are guaranteed to be ASCII only) */
2006-02-04 05:59:48 +00:00
ret = ldb_attr_cmp ( base - > components [ n0 ] . name ,
dn - > components [ n1 ] . name ) ;
2005-07-02 17:30:03 +00:00
if ( ret ) {
return ret ;
}
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
/* names match, compare values */
2005-07-12 12:04:54 +00:00
h = ldb_attrib_handler ( ldb , base - > components [ n0 ] . name ) ;
ret = h - > comparison_fn ( ldb , ldb , & ( base - > components [ n0 ] . value ) ,
& ( dn - > components [ n1 ] . value ) ) ;
2005-07-02 17:30:03 +00:00
if ( ret ) {
return ret ;
2005-06-27 00:00:50 +00:00
}
2005-07-17 09:06:58 +00:00
n1 - - ;
n0 - - ;
2005-06-27 00:00:50 +00: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 06:21:26 +00:00
return 0 ;
2005-06-27 00:00:50 +00:00
}
2006-06-08 01:00:46 +00:00
/* compare DNs using casefolding compare functions.
If they match , then return 0
*/
2005-07-12 12:04:54 +00:00
int ldb_dn_compare ( struct ldb_context * ldb ,
const struct ldb_dn * edn0 ,
const struct ldb_dn * edn1 )
{
2005-08-18 15:02:01 +00:00
if ( edn0 = = NULL | | edn1 = = NULL ) return edn1 - edn0 ;
2005-07-12 12:04:54 +00:00
if ( edn0 - > comp_num ! = edn1 - > comp_num )
return ( edn1 - > comp_num - edn0 - > comp_num ) ;
return ldb_dn_compare_base ( ldb , edn0 , edn1 ) ;
}
2005-07-16 18:16:32 +00:00
int ldb_dn_cmp ( struct ldb_context * ldb , const char * dn0 , const char * dn1 )
{
struct ldb_dn * edn0 ;
struct ldb_dn * edn1 ;
int ret ;
2005-08-18 15:02:01 +00:00
if ( dn0 = = NULL | | dn1 = = NULL ) return dn1 - dn0 ;
2006-10-09 09:56:13 +00:00
edn0 = ldb_dn_explode_casefold ( ldb , ldb , dn0 ) ;
2005-09-14 22:39:24 +00:00
if ( edn0 = = NULL ) return 1 ;
2005-07-16 18:16:32 +00:00
2006-10-09 09:56:13 +00:00
edn1 = ldb_dn_explode_casefold ( ldb , ldb , dn1 ) ;
2005-07-16 18:16:32 +00:00
if ( edn1 = = NULL ) {
talloc_free ( edn0 ) ;
2005-09-14 22:39:24 +00:00
return - 1 ;
2005-07-16 18:16:32 +00:00
}
ret = ldb_dn_compare ( ldb , edn0 , edn1 ) ;
talloc_free ( edn0 ) ;
talloc_free ( edn1 ) ;
return ret ;
}
2005-06-27 00:00:50 +00:00
/*
2005-07-02 17:30:03 +00:00
casefold a dn . We need to casefold the attribute names , and canonicalize
attribute values of case insensitive attributes .
2005-06-27 00:00:50 +00:00
*/
2006-10-09 09:56:13 +00:00
struct ldb_dn * ldb_dn_casefold ( struct ldb_context * ldb , void * mem_ctx , const struct ldb_dn * edn )
2005-06-27 00:00:50 +00:00
{
struct ldb_dn * cedn ;
2006-10-09 09:56:13 +00:00
int i , ret ;
2005-06-27 00:00:50 +00:00
2005-08-18 15:02:01 +00:00
if ( edn = = NULL ) return NULL ;
2006-10-09 09:56:13 +00:00
cedn = ldb_dn_new ( mem_ctx ) ;
2006-07-06 07:37:41 +00:00
if ( ! cedn ) {
return NULL ;
}
2005-06-27 00:00:50 +00:00
cedn - > comp_num = edn - > comp_num ;
2005-07-02 17:30:03 +00:00
cedn - > components = talloc_array ( cedn , struct ldb_dn_component , edn - > comp_num ) ;
2006-07-06 05:51:39 +00:00
if ( ! cedn - > components ) {
talloc_free ( cedn ) ;
return NULL ;
}
2005-06-27 00:00:50 +00:00
for ( i = 0 ; i < edn - > comp_num ; i + + ) {
2005-07-02 17:30:03 +00:00
struct ldb_dn_component dc ;
const struct ldb_attrib_handler * h ;
2005-06-27 00:00:50 +00:00
2006-10-06 06:42:05 +00:00
memset ( & dc , 0 , sizeof ( dc ) ) ;
2006-10-09 09:56:13 +00:00
dc . name = ldb_attr_casefold ( cedn - > components , edn - > components [ i ] . name ) ;
2006-07-06 05:51:39 +00:00
if ( ! dc . name ) {
talloc_free ( cedn ) ;
return NULL ;
}
2005-06-27 00:00:50 +00:00
2005-07-02 17:30:03 +00:00
h = ldb_attrib_handler ( ldb , dc . name ) ;
2006-10-09 09:56:13 +00:00
ret = h - > canonicalise_fn ( ldb , cedn - > components ,
& ( edn - > components [ i ] . value ) ,
& ( dc . value ) ) ;
if ( ret ! = 0 ) {
2006-07-06 05:51:39 +00:00
talloc_free ( cedn ) ;
return NULL ;
2005-06-27 00:00:50 +00:00
}
cedn - > components [ i ] = dc ;
}
return cedn ;
}
2006-10-09 09:56:13 +00:00
struct ldb_dn * ldb_dn_explode_casefold ( struct ldb_context * ldb , void * mem_ctx , const char * dn )
2005-07-12 12:04:54 +00:00
{
struct ldb_dn * edn , * cdn ;
2005-08-18 15:02:01 +00:00
if ( dn = = NULL ) return NULL ;
2005-07-12 12:04:54 +00:00
edn = ldb_dn_explode ( ldb , dn ) ;
if ( edn = = NULL ) return NULL ;
2006-10-09 09:56:13 +00:00
cdn = ldb_dn_casefold ( ldb , mem_ctx , edn ) ;
2005-07-12 12:04:54 +00:00
talloc_free ( edn ) ;
return cdn ;
}
2005-08-18 15:02:01 +00:00
2006-10-09 09:56:13 +00:00
char * ldb_dn_linearize_casefold ( struct ldb_context * ldb , void * mem_ctx , const struct ldb_dn * edn )
2005-08-18 15:02:01 +00:00
{
struct ldb_dn * cdn ;
char * dn ;
if ( edn = = NULL ) return NULL ;
/* Special DNs */
if ( ldb_dn_is_special ( edn ) ) {
2006-10-09 09:56:13 +00:00
dn = talloc_strdup ( mem_ctx , ( char * ) edn - > components [ 0 ] . value . data ) ;
2005-08-18 15:02:01 +00:00
return dn ;
}
2006-10-09 09:56:13 +00:00
cdn = ldb_dn_casefold ( ldb , mem_ctx , edn ) ;
2005-08-18 15:02:01 +00:00
if ( cdn = = NULL ) return NULL ;
dn = ldb_dn_linearize ( ldb , cdn ) ;
if ( dn = = NULL ) {
talloc_free ( cdn ) ;
return NULL ;
}
talloc_free ( cdn ) ;
return dn ;
}
static struct ldb_dn_component ldb_dn_copy_component ( void * mem_ctx , struct ldb_dn_component * src )
{
struct ldb_dn_component dst ;
2005-10-12 08:51:12 +00:00
memset ( & dst , 0 , sizeof ( dst ) ) ;
2005-08-18 15:02:01 +00:00
if ( src = = NULL ) {
return dst ;
}
dst . value = ldb_val_dup ( mem_ctx , & ( src - > value ) ) ;
if ( dst . value . data = = NULL ) {
return dst ;
}
dst . name = talloc_strdup ( mem_ctx , src - > name ) ;
if ( dst . name = = NULL ) {
talloc_free ( dst . value . data ) ;
2006-10-04 20:15:23 +00:00
dst . value . data = NULL ;
2005-08-18 15:02:01 +00:00
}
return dst ;
}
/* copy specified number of elements of a dn into a new one
element are copied from top level up to the unique rdn
2006-06-08 15:20:05 +00:00
num_el may be greater than dn - > comp_num ( see ldb_dn_make_child )
2005-08-18 15:02:01 +00:00
*/
struct ldb_dn * ldb_dn_copy_partial ( void * mem_ctx , const struct ldb_dn * dn , int num_el )
{
2006-08-17 01:52:24 +00:00
struct ldb_dn * newdn ;
2005-08-18 15:02:01 +00:00
int i , n , e ;
if ( dn = = NULL ) return NULL ;
if ( num_el < = 0 ) return NULL ;
2006-08-17 01:52:24 +00:00
newdn = ldb_dn_new ( mem_ctx ) ;
LDB_DN_NULL_FAILED ( newdn ) ;
2005-08-18 15:02:01 +00:00
2006-08-17 01:52:24 +00:00
newdn - > comp_num = num_el ;
n = newdn - > comp_num - 1 ;
newdn - > components = talloc_array ( newdn , struct ldb_dn_component , newdn - > comp_num ) ;
2006-10-04 20:59:06 +00:00
if ( newdn - > components = = NULL ) goto failed ;
2005-08-18 15:02:01 +00:00
2006-08-17 01:52:24 +00:00
if ( dn - > comp_num = = 0 ) return newdn ;
2005-08-18 15:02:01 +00:00
e = dn - > comp_num - 1 ;
2006-08-17 01:52:24 +00:00
for ( i = 0 ; i < newdn - > comp_num ; i + + ) {
newdn - > components [ n - i ] = ldb_dn_copy_component ( newdn - > components ,
2005-08-18 15:02:01 +00:00
& ( dn - > components [ e - i ] ) ) ;
if ( ( e - i ) = = 0 ) {
2006-08-17 01:52:24 +00:00
return newdn ;
2005-08-18 15:02:01 +00:00
}
}
2006-08-17 01:52:24 +00:00
return newdn ;
2005-08-18 15:02:01 +00:00
failed :
2006-08-17 01:52:24 +00:00
talloc_free ( newdn ) ;
2005-08-18 15:02:01 +00:00
return NULL ;
}
struct ldb_dn * ldb_dn_copy ( void * mem_ctx , const struct ldb_dn * dn )
{
if ( dn = = NULL ) return NULL ;
return ldb_dn_copy_partial ( mem_ctx , dn , dn - > comp_num ) ;
}
struct ldb_dn * ldb_dn_get_parent ( void * mem_ctx , const struct ldb_dn * dn )
{
if ( dn = = NULL ) return NULL ;
return ldb_dn_copy_partial ( mem_ctx , dn , dn - > comp_num - 1 ) ;
}
struct ldb_dn_component * ldb_dn_build_component ( void * mem_ctx , const char * attr ,
2005-09-01 23:24:47 +00:00
const char * val )
2005-08-18 15:02:01 +00:00
{
struct ldb_dn_component * dc ;
if ( attr = = NULL | | val = = NULL ) return NULL ;
dc = talloc ( mem_ctx , struct ldb_dn_component ) ;
if ( dc = = NULL ) return NULL ;
dc - > name = talloc_strdup ( dc , attr ) ;
if ( dc - > name = = NULL ) {
talloc_free ( dc ) ;
return NULL ;
}
2005-10-12 06:10:23 +00:00
dc - > value . data = ( uint8_t * ) talloc_strdup ( dc , val ) ;
2005-08-18 15:02:01 +00:00
if ( dc - > value . data = = NULL ) {
talloc_free ( dc ) ;
return NULL ;
}
dc - > value . length = strlen ( val ) ;
return dc ;
}
struct ldb_dn * ldb_dn_build_child ( void * mem_ctx , const char * attr ,
const char * value ,
const struct ldb_dn * base )
{
2006-08-17 01:52:24 +00:00
struct ldb_dn * newdn ;
2006-02-04 00:38:48 +00:00
if ( ! ldb_valid_attr_name ( attr ) ) return NULL ;
2005-08-18 15:02:01 +00:00
if ( value = = NULL | | value = = ' \0 ' ) return NULL ;
if ( base ! = NULL ) {
2006-08-17 01:52:24 +00:00
newdn = ldb_dn_copy_partial ( mem_ctx , base , base - > comp_num + 1 ) ;
LDB_DN_NULL_FAILED ( newdn ) ;
2005-08-18 15:02:01 +00:00
} else {
2006-08-17 01:52:24 +00:00
newdn = ldb_dn_new ( mem_ctx ) ;
LDB_DN_NULL_FAILED ( newdn ) ;
2005-08-18 15:02:01 +00:00
2006-08-17 01:52:24 +00:00
newdn - > comp_num = 1 ;
newdn - > components = talloc_array ( newdn , struct ldb_dn_component , newdn - > comp_num ) ;
2005-08-18 15:02:01 +00:00
}
2006-08-17 01:52:24 +00:00
newdn - > components [ 0 ] . name = talloc_strdup ( newdn - > components , attr ) ;
LDB_DN_NULL_FAILED ( newdn - > components [ 0 ] . name ) ;
2005-08-18 15:02:01 +00:00
2006-08-17 01:52:24 +00:00
newdn - > components [ 0 ] . value . data = ( uint8_t * ) talloc_strdup ( newdn - > components , value ) ;
LDB_DN_NULL_FAILED ( newdn - > components [ 0 ] . value . data ) ;
newdn - > components [ 0 ] . value . length = strlen ( ( char * ) newdn - > components [ 0 ] . value . data ) ;
2005-08-18 15:02:01 +00:00
2006-08-17 01:52:24 +00:00
return newdn ;
2005-08-18 15:02:01 +00:00
failed :
2006-08-17 01:52:24 +00:00
talloc_free ( newdn ) ;
2005-08-18 15:02:01 +00:00
return NULL ;
}
struct ldb_dn * ldb_dn_make_child ( void * mem_ctx , const struct ldb_dn_component * component ,
const struct ldb_dn * base )
{
if ( component = = NULL ) return NULL ;
2005-10-12 06:10:23 +00:00
return ldb_dn_build_child ( mem_ctx , component - > name ,
( char * ) component - > value . data , base ) ;
2005-08-18 15:02:01 +00:00
}
struct ldb_dn * ldb_dn_compose ( void * mem_ctx , const struct ldb_dn * dn1 , const struct ldb_dn * dn2 )
{
int i ;
2006-08-17 01:52:24 +00:00
struct ldb_dn * newdn ;
2005-08-18 15:02:01 +00:00
if ( dn2 = = NULL & & dn1 = = NULL ) {
return NULL ;
}
if ( dn2 = = NULL ) {
2006-08-17 01:52:24 +00:00
newdn = ldb_dn_new ( mem_ctx ) ;
LDB_DN_NULL_FAILED ( newdn ) ;
2005-08-18 15:02:01 +00:00
2006-08-17 01:52:24 +00:00
newdn - > comp_num = dn1 - > comp_num ;
newdn - > components = talloc_array ( newdn , struct ldb_dn_component , newdn - > comp_num ) ;
2005-08-18 15:02:01 +00:00
} else {
2005-08-18 16:18:48 +00:00
int comp_num = dn2 - > comp_num ;
if ( dn1 ! = NULL ) comp_num + = dn1 - > comp_num ;
2006-08-17 01:52:24 +00:00
newdn = ldb_dn_copy_partial ( mem_ctx , dn2 , comp_num ) ;
2006-10-04 20:22:08 +00:00
LDB_DN_NULL_FAILED ( newdn ) ;
2005-08-18 15:02:01 +00:00
}
if ( dn1 = = NULL ) {
2006-08-17 01:52:24 +00:00
return newdn ;
2005-08-18 15:02:01 +00:00
}
for ( i = 0 ; i < dn1 - > comp_num ; i + + ) {
2006-08-17 01:52:24 +00:00
newdn - > components [ i ] = ldb_dn_copy_component ( newdn - > components ,
2005-09-01 23:24:47 +00:00
& ( dn1 - > components [ i ] ) ) ;
2006-10-04 20:15:23 +00:00
if ( newdn - > components [ i ] . value . data = = NULL ) {
goto failed ;
}
2005-08-18 15:02:01 +00:00
}
2006-08-17 01:52:24 +00:00
return newdn ;
2005-08-18 15:02:01 +00:00
failed :
2006-08-17 01:52:24 +00:00
talloc_free ( newdn ) ;
2005-08-18 15:02:01 +00:00
return NULL ;
}
2005-08-18 16:18:48 +00:00
struct ldb_dn * ldb_dn_string_compose ( void * mem_ctx , const struct ldb_dn * base , const char * child_fmt , . . . )
2005-08-18 15:02:01 +00:00
{
2006-10-15 10:11:15 +00:00
struct ldb_dn * dn , * dn1 ;
2005-08-18 16:18:48 +00:00
char * child_str ;
va_list ap ;
if ( child_fmt = = NULL ) return NULL ;
va_start ( ap , child_fmt ) ;
2006-08-22 22:28:37 +00:00
child_str = talloc_vasprintf ( mem_ctx , child_fmt , ap ) ;
2005-08-18 16:18:48 +00:00
va_end ( ap ) ;
2006-08-22 22:28:37 +00:00
if ( child_str = = NULL ) return NULL ;
2005-08-18 15:02:01 +00:00
2006-10-15 10:11:15 +00:00
dn1 = ldb_dn_explode ( mem_ctx , child_str ) ;
dn = ldb_dn_compose ( mem_ctx , dn1 , base ) ;
2005-08-18 16:18:48 +00:00
2006-08-22 22:28:37 +00:00
talloc_free ( child_str ) ;
2006-10-15 10:11:15 +00:00
talloc_free ( dn1 ) ;
2005-08-18 16:18:48 +00:00
return dn ;
2005-08-18 15:02:01 +00:00
}
struct ldb_dn_component * ldb_dn_get_rdn ( void * mem_ctx , const struct ldb_dn * dn )
{
struct ldb_dn_component * rdn ;
if ( dn = = NULL ) return NULL ;
if ( dn - > comp_num < 1 ) {
return NULL ;
}
rdn = talloc ( mem_ctx , struct ldb_dn_component ) ;
if ( rdn = = NULL ) return NULL ;
* rdn = ldb_dn_copy_component ( mem_ctx , & dn - > components [ 0 ] ) ;
if ( rdn - > name = = NULL ) {
talloc_free ( rdn ) ;
return NULL ;
}
return rdn ;
}
2005-10-13 07:47:57 +00:00
/* Create a 'canonical name' string from a DN:
ie dc = samba , dc = org - > samba . org /
uid = administrator , ou = users , dc = samba , dc = org = samba . org / users / administrator
There are two formats , the EX format has the last / replaced with a newline ( \ n ) .
*/
2005-10-13 04:24:49 +00:00
static char * ldb_dn_canonical ( void * mem_ctx , const struct ldb_dn * dn , int ex_format ) {
int i ;
char * cracked = NULL ;
2005-10-13 07:47:57 +00:00
/* Walk backwards down the DN, grabbing 'dc' components at first */
2005-10-13 04:24:49 +00:00
for ( i = dn - > comp_num - 1 ; i > = 0 ; i - - ) {
2005-10-14 02:05:51 +00:00
if ( ldb_attr_cmp ( dn - > components [ i ] . name , " dc " ) ! = 0 ) {
2005-10-13 04:24:49 +00:00
break ;
}
if ( cracked ) {
2005-10-13 10:02:36 +00:00
cracked = talloc_asprintf ( mem_ctx , " %s.%s " ,
2005-10-14 02:05:51 +00:00
ldb_dn_escape_value ( mem_ctx , dn - > components [ i ] . value ) ,
2005-10-13 04:24:49 +00:00
cracked ) ;
} else {
2005-10-14 02:05:51 +00:00
cracked = ldb_dn_escape_value ( mem_ctx , dn - > components [ i ] . value ) ;
2005-10-13 04:24:49 +00:00
}
if ( ! cracked ) {
return NULL ;
}
}
2005-10-13 07:47:57 +00:00
/* Only domain components? Finish here */
2005-10-13 04:24:49 +00:00
if ( i < 0 ) {
if ( ex_format ) {
cracked = talloc_asprintf ( mem_ctx , " %s \n " , cracked ) ;
} else {
cracked = talloc_asprintf ( mem_ctx , " %s/ " , cracked ) ;
}
return cracked ;
}
2005-10-13 07:47:57 +00:00
/* Now walk backwards appending remaining components */
2005-10-13 04:24:49 +00:00
for ( ; i > 0 ; i - - ) {
cracked = talloc_asprintf ( mem_ctx , " %s/%s " , cracked ,
2005-10-14 02:05:51 +00:00
ldb_dn_escape_value ( mem_ctx , dn - > components [ i ] . value ) ) ;
2005-10-13 04:24:49 +00:00
if ( ! cracked ) {
return NULL ;
}
}
2005-10-13 07:47:57 +00:00
/* Last one, possibly a newline for the 'ex' format */
2005-10-13 04:24:49 +00:00
if ( ex_format ) {
cracked = talloc_asprintf ( mem_ctx , " %s \n %s " , cracked ,
2005-10-14 02:05:51 +00:00
ldb_dn_escape_value ( mem_ctx , dn - > components [ i ] . value ) ) ;
2005-10-13 04:24:49 +00:00
} else {
cracked = talloc_asprintf ( mem_ctx , " %s/%s " , cracked ,
2005-10-14 02:05:51 +00:00
ldb_dn_escape_value ( mem_ctx , dn - > components [ i ] . value ) ) ;
2005-10-13 04:24:49 +00:00
}
return cracked ;
}
2005-10-13 07:47:57 +00:00
/* Wrapper functions for the above, for the two different string formats */
2005-10-13 04:24:49 +00:00
char * ldb_dn_canonical_string ( void * mem_ctx , const struct ldb_dn * dn ) {
return ldb_dn_canonical ( mem_ctx , dn , 0 ) ;
}
char * ldb_dn_canonical_ex_string ( void * mem_ctx , const struct ldb_dn * dn ) {
return ldb_dn_canonical ( mem_ctx , dn , 1 ) ;
}