2008-08-15 20:40:57 +10:00
/*
Unix SMB / CIFS mplementation .
Print schema info into string format
Copyright ( C ) Andrew Bartlett 2006 - 2008
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "dsdb/samdb/samdb.h"
2008-11-14 08:49:06 +01:00
# include "librpc/ndr/libndr.h"
2008-08-15 20:40:57 +10:00
# define IF_NULL_FAIL_RET(x) do { \
if ( ! x ) { \
return NULL ; \
} \
} while ( 0 )
char * schema_attribute_description ( TALLOC_CTX * mem_ctx ,
enum dsdb_schema_convert_target target ,
const char * seperator ,
const char * oid ,
const char * name ,
const char * equality ,
const char * substring ,
const char * syntax ,
2008-11-14 08:49:06 +01:00
bool single_value , bool operational ,
uint32_t * range_lower ,
uint32_t * range_upper ,
const char * property_guid ,
const char * property_set_guid ,
bool indexed , bool system_only )
2008-08-15 20:40:57 +10:00
{
char * schema_entry = talloc_asprintf ( mem_ctx ,
" (%s%s%s " , seperator , oid , seperator ) ;
schema_entry = talloc_asprintf_append ( schema_entry ,
" NAME '%s'%s " , name , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
if ( equality ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" EQUALITY %s%s " , equality , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( substring ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" SUBSTR %s%s " , substring , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-11-14 08:49:06 +01:00
if ( syntax ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" SYNTAX %s%s " , syntax , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-08-15 20:40:57 +10:00
if ( single_value ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" SINGLE-VALUE%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( operational ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" NO-USER-MODIFICATION%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-11-14 08:49:06 +01:00
if ( range_lower ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" RANGE-LOWER '%u'%s " ,
* range_lower , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( range_upper ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" RANGE-UPPER '%u'%s " ,
* range_upper , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( property_guid ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" PROPERTY-GUID '%s'%s " ,
property_guid , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( property_set_guid ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" PROPERTY-SET-GUID '%s'%s " ,
property_set_guid , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( indexed ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" INDEXED%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( system_only ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" SYSTEM-ONLY%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-08-15 20:40:57 +10:00
schema_entry = talloc_asprintf_append ( schema_entry ,
" ) " ) ;
return schema_entry ;
}
char * schema_attribute_to_description ( TALLOC_CTX * mem_ctx , const struct dsdb_attribute * attribute )
{
char * schema_description ;
2008-11-13 21:31:03 +01:00
const char * syntax = attribute - > syntax - > ldap_oid ;
2008-08-15 20:40:57 +10:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( ! tmp_ctx ) {
return NULL ;
}
schema_description
= schema_attribute_description ( mem_ctx ,
TARGET_AD_SCHEMA_SUBENTRY ,
" " ,
attribute - > attributeID_oid ,
attribute - > lDAPDisplayName ,
2008-10-03 16:36:04 -07:00
NULL , NULL , talloc_asprintf ( tmp_ctx , " '%s' " , syntax ) ,
2008-08-15 20:40:57 +10:00
attribute - > isSingleValued ,
2008-11-14 08:49:06 +01:00
attribute - > systemOnly , /* TODO: is this correct? */
NULL , NULL , NULL , NULL ,
false , false ) ;
talloc_free ( tmp_ctx ) ;
return schema_description ;
}
char * schema_attribute_to_extendedInfo ( TALLOC_CTX * mem_ctx , const struct dsdb_attribute * attribute )
{
char * schema_description ;
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( ! tmp_ctx ) {
return NULL ;
}
schema_description
= schema_attribute_description ( mem_ctx ,
TARGET_AD_SCHEMA_SUBENTRY ,
" " ,
attribute - > attributeID_oid ,
attribute - > lDAPDisplayName ,
NULL , NULL , NULL ,
false , false ,
attribute - > rangeLower ,
attribute - > rangeUpper ,
GUID_hexstring ( tmp_ctx , & attribute - > schemaIDGUID ) ,
GUID_hexstring ( tmp_ctx , & attribute - > attributeSecurityGUID ) ,
( attribute - > searchFlags & SEARCH_FLAG_ATTINDEX ) ,
2008-08-15 20:40:57 +10:00
attribute - > systemOnly ) ;
talloc_free ( tmp_ctx ) ;
return schema_description ;
}
# define APPEND_ATTRS(attributes) \
do { \
2009-11-06 20:14:41 +01:00
unsigned int k ; \
2008-08-15 20:40:57 +10:00
for ( k = 0 ; attributes & & attributes [ k ] ; k + + ) { \
const char * attr_name = attributes [ k ] ; \
\
schema_entry = talloc_asprintf_append ( schema_entry , \
" %s " , \
attr_name ) ; \
IF_NULL_FAIL_RET ( schema_entry ) ; \
if ( attributes [ k + 1 ] ) { \
IF_NULL_FAIL_RET ( schema_entry ) ; \
if ( target = = TARGET_OPENLDAP & & ( ( k + 1 ) % 5 = = 0 ) ) { \
schema_entry = talloc_asprintf_append ( schema_entry , \
" $%s " , seperator ) ; \
IF_NULL_FAIL_RET ( schema_entry ) ; \
} else { \
schema_entry = talloc_asprintf_append ( schema_entry , \
" $ " ) ; \
} \
} \
} \
} while ( 0 )
/* Print a schema class or dITContentRule as a string.
*
* To print a scheam class , specify objectClassCategory but not auxillary_classes
* To print a dITContentRule , specify auxillary_classes but set objectClassCategory = = - 1
*
*/
char * schema_class_description ( TALLOC_CTX * mem_ctx ,
enum dsdb_schema_convert_target target ,
const char * seperator ,
const char * oid ,
const char * name ,
const char * * auxillary_classes ,
const char * subClassOf ,
int objectClassCategory ,
2008-12-23 22:57:11 +01:00
const char * * must ,
const char * * may ,
2008-11-14 08:51:59 +01:00
const char * schemaHexGUID )
2008-08-15 20:40:57 +10:00
{
char * schema_entry = talloc_asprintf ( mem_ctx ,
" (%s%s%s " , seperator , oid , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
schema_entry = talloc_asprintf_append ( schema_entry ,
" NAME '%s'%s " , name , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
if ( auxillary_classes ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" AUX ( " ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
APPEND_ATTRS ( auxillary_classes ) ;
schema_entry = talloc_asprintf_append ( schema_entry ,
" )%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-09-09 18:02:05 +10:00
if ( subClassOf & & strcasecmp ( subClassOf , name ) ! = 0 ) {
2008-08-15 20:40:57 +10:00
schema_entry = talloc_asprintf_append ( schema_entry ,
" SUP %s%s " , subClassOf , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
switch ( objectClassCategory ) {
case - 1 :
break ;
/* Dummy case for when used for printing ditContentRules */
case 0 :
/*
* NOTE : this is an type 88 class
* e . g . 2.5 .6 .6 NAME ' person '
* but w2k3 gives STRUCTURAL here !
*/
schema_entry = talloc_asprintf_append ( schema_entry ,
" STRUCTURAL%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
break ;
case 1 :
schema_entry = talloc_asprintf_append ( schema_entry ,
" STRUCTURAL%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
break ;
case 2 :
schema_entry = talloc_asprintf_append ( schema_entry ,
" ABSTRACT%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
break ;
case 3 :
schema_entry = talloc_asprintf_append ( schema_entry ,
" AUXILIARY%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
break ;
}
if ( must ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
2008-09-11 12:36:58 +10:00
" MUST (%s " , target = = TARGET_AD_SCHEMA_SUBENTRY ? " " : " " ) ;
2008-08-15 20:40:57 +10:00
IF_NULL_FAIL_RET ( schema_entry ) ;
APPEND_ATTRS ( must ) ;
schema_entry = talloc_asprintf_append ( schema_entry ,
" )%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
if ( may ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
2008-09-11 12:36:58 +10:00
" MAY (%s " , target = = TARGET_AD_SCHEMA_SUBENTRY ? " " : " " ) ;
2008-08-15 20:40:57 +10:00
IF_NULL_FAIL_RET ( schema_entry ) ;
APPEND_ATTRS ( may ) ;
schema_entry = talloc_asprintf_append ( schema_entry ,
" )%s " , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-11-14 08:51:59 +01:00
if ( schemaHexGUID ) {
schema_entry = talloc_asprintf_append ( schema_entry ,
" CLASS-GUID '%s'%s " ,
schemaHexGUID , seperator ) ;
IF_NULL_FAIL_RET ( schema_entry ) ;
}
2008-08-15 20:40:57 +10:00
schema_entry = talloc_asprintf_append ( schema_entry ,
" ) " ) ;
return schema_entry ;
}
2009-02-02 09:20:36 +01:00
char * schema_class_to_description ( TALLOC_CTX * mem_ctx , const struct dsdb_class * sclass )
2008-08-15 20:40:57 +10:00
{
char * schema_description ;
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( ! tmp_ctx ) {
return NULL ;
}
schema_description
= schema_class_description ( mem_ctx ,
TARGET_AD_SCHEMA_SUBENTRY ,
" " ,
2009-02-02 09:20:36 +01:00
sclass - > governsID_oid ,
sclass - > lDAPDisplayName ,
2008-08-15 20:40:57 +10:00
NULL ,
2009-02-02 09:20:36 +01:00
sclass - > subClassOf ,
sclass - > objectClassCategory ,
2008-08-15 20:40:57 +10:00
dsdb_attribute_list ( tmp_ctx ,
2009-02-02 09:20:36 +01:00
sclass , DSDB_SCHEMA_ALL_MUST ) ,
2008-08-15 20:40:57 +10:00
dsdb_attribute_list ( tmp_ctx ,
2009-02-02 09:20:36 +01:00
sclass , DSDB_SCHEMA_ALL_MAY ) ,
2008-11-14 08:51:59 +01:00
NULL ) ;
2008-08-15 20:40:57 +10:00
talloc_free ( tmp_ctx ) ;
return schema_description ;
}
2009-02-02 09:20:36 +01:00
char * schema_class_to_dITContentRule ( TALLOC_CTX * mem_ctx , const struct dsdb_class * sclass ,
const struct dsdb_schema * schema )
2008-08-15 20:40:57 +10:00
{
2009-11-06 20:14:41 +01:00
unsigned int i ;
2008-08-15 20:40:57 +10:00
char * schema_description ;
2008-12-23 22:57:11 +01:00
const char * * aux_class_list = NULL ;
const char * * attrs ;
const char * * must_attr_list = NULL ;
const char * * may_attr_list = NULL ;
2008-08-15 20:40:57 +10:00
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
const struct dsdb_class * aux_class ;
if ( ! tmp_ctx ) {
return NULL ;
}
2009-02-02 09:20:36 +01:00
aux_class_list = merge_attr_list ( tmp_ctx , aux_class_list , sclass - > systemAuxiliaryClass ) ;
aux_class_list = merge_attr_list ( tmp_ctx , aux_class_list , sclass - > auxiliaryClass ) ;
2008-08-15 20:40:57 +10:00
for ( i = 0 ; aux_class_list & & aux_class_list [ i ] ; i + + ) {
aux_class = dsdb_class_by_lDAPDisplayName ( schema , aux_class_list [ i ] ) ;
attrs = dsdb_attribute_list ( mem_ctx , aux_class , DSDB_SCHEMA_ALL_MUST ) ;
must_attr_list = merge_attr_list ( mem_ctx , must_attr_list , attrs ) ;
attrs = dsdb_attribute_list ( mem_ctx , aux_class , DSDB_SCHEMA_ALL_MAY ) ;
may_attr_list = merge_attr_list ( mem_ctx , may_attr_list , attrs ) ;
}
schema_description
= schema_class_description ( mem_ctx ,
TARGET_AD_SCHEMA_SUBENTRY ,
" " ,
2009-02-02 09:20:36 +01:00
sclass - > governsID_oid ,
sclass - > lDAPDisplayName ,
2008-08-15 20:40:57 +10:00
( const char * * ) aux_class_list ,
2008-10-03 16:25:59 -07:00
NULL , /* Must not specify a
* SUP ( subclass ) in
* ditContentRules
* per MS - ADTS
* 3.1 .1 .3 .1 .1 .1 */
2008-11-14 08:51:59 +01:00
- 1 , must_attr_list , may_attr_list ,
NULL ) ;
talloc_free ( tmp_ctx ) ;
return schema_description ;
}
char * schema_class_to_extendedInfo ( TALLOC_CTX * mem_ctx , const struct dsdb_class * sclass )
{
char * schema_description = NULL ;
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
if ( ! tmp_ctx ) {
return NULL ;
}
schema_description
= schema_class_description ( mem_ctx ,
TARGET_AD_SCHEMA_SUBENTRY ,
" " ,
sclass - > governsID_oid ,
sclass - > lDAPDisplayName ,
NULL ,
NULL , /* Must not specify a
* SUP ( subclass ) in
* ditContentRules
* per MS - ADTS
* 3.1 .1 .3 .1 .1 .1 */
- 1 , NULL , NULL ,
GUID_hexstring ( tmp_ctx , & sclass - > schemaIDGUID ) ) ;
2008-08-15 20:40:57 +10:00
talloc_free ( tmp_ctx ) ;
return schema_description ;
}
2008-11-14 08:51:59 +01:00