2008-08-15 20:40:57 +10:00
/*
2020-08-09 16:14:02 +02:00
Unix SMB / CIFS Implementation .
2008-08-15 20:40:57 +10:00
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
2020-08-07 13:27:39 -07:00
# undef strcasecmp
2008-08-15 20:40:57 +10:00
char * schema_attribute_description ( TALLOC_CTX * mem_ctx ,
enum dsdb_schema_convert_target target ,
2019-10-26 02:41:09 +02:00
const char * separator ,
2008-08-15 20:40:57 +10:00
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 ,
2019-10-26 02:41:09 +02:00
" (%s%s%s " , separator , oid , separator ) ;
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " NAME '%s'%s " , name , separator ) ;
2008-08-15 20:40:57 +10:00
if ( equality ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " EQUALITY %s%s " , equality , separator ) ;
2008-08-15 20:40:57 +10:00
}
if ( substring ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " SUBSTR %s%s " , substring , separator ) ;
2008-08-15 20:40:57 +10:00
}
2008-11-14 08:49:06 +01:00
if ( syntax ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " SYNTAX %s%s " , syntax , separator ) ;
2008-11-14 08:49:06 +01:00
}
2008-08-15 20:40:57 +10:00
if ( single_value ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " SINGLE-VALUE%s " , separator ) ;
2008-08-15 20:40:57 +10:00
}
2021-10-06 10:47:48 +02:00
2008-08-15 20:40:57 +10:00
if ( operational ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " NO-USER-MODIFICATION%s " , separator ) ;
2008-08-15 20:40:57 +10:00
}
2008-11-14 08:49:06 +01:00
if ( range_lower ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" RANGE-LOWER '%u'%s " ,
* range_lower ,
separator ) ;
2008-11-14 08:49:06 +01:00
}
if ( range_upper ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" RANGE-UPPER '%u'%s " ,
* range_upper ,
separator ) ;
2008-11-14 08:49:06 +01:00
}
if ( property_guid ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" PROPERTY-GUID '%s'%s " ,
property_guid ,
separator ) ;
2008-11-14 08:49:06 +01:00
}
if ( property_set_guid ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" PROPERTY-SET-GUID '%s'%s " ,
property_set_guid ,
separator ) ;
2008-11-14 08:49:06 +01:00
}
if ( indexed ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " INDEXED%s " , separator ) ;
2008-11-14 08:49:06 +01:00
}
if ( system_only ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " SYSTEM-ONLY%s " , separator ) ;
2008-11-14 08:49:06 +01:00
}
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , " ) " ) ;
2008-08-15 20:40:57 +10:00
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 ) ,
2023-02-24 10:03:25 +13:00
/*
* We actually ignore the indexed
* flag for confidential
* attributes , but we ' ll include
* it for the purposes of
* description .
*/
2008-11-14 08:49:06 +01:00
( 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 ] ; \
\
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , \
2008-08-15 20:40:57 +10:00
" %s " , \
attr_name ) ; \
if ( attributes [ k + 1 ] ) { \
if ( target = = TARGET_OPENLDAP & & ( ( k + 1 ) % 5 = = 0 ) ) { \
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , \
2019-10-26 02:41:09 +02:00
" $%s " , separator ) ; \
2008-08-15 20:40:57 +10:00
} else { \
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , \
2008-08-15 20:40:57 +10:00
" $ " ) ; \
} \
} \
} \
} 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 ,
2019-10-26 02:41:09 +02:00
const char * separator ,
2008-08-15 20:40:57 +10:00
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 ,
2019-10-26 02:41:09 +02:00
" (%s%s%s " , separator , oid , separator ) ;
2008-08-15 20:40:57 +10:00
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , " NAME '%s'%s " , name , separator ) ;
2008-08-15 20:40:57 +10:00
if ( auxillary_classes ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , " AUX ( " ) ;
2008-08-15 20:40:57 +10:00
APPEND_ATTRS ( auxillary_classes ) ;
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , " )%s " , separator ) ;
2008-08-15 20:40:57 +10:00
}
2008-09-09 18:02:05 +10:00
if ( subClassOf & & strcasecmp ( subClassOf , name ) ! = 0 ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " SUP %s%s " , subClassOf , separator ) ;
2008-08-15 20:40:57 +10:00
}
2021-10-06 10:47:48 +02:00
2008-08-15 20:40:57 +10:00
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 !
*/
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " STRUCTURAL%s " , separator ) ;
2008-08-15 20:40:57 +10:00
break ;
case 1 :
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " STRUCTURAL%s " , separator ) ;
2008-08-15 20:40:57 +10:00
break ;
case 2 :
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " ABSTRACT%s " , separator ) ;
2008-08-15 20:40:57 +10:00
break ;
case 3 :
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " AUXILIARY%s " , separator ) ;
2008-08-15 20:40:57 +10:00
break ;
}
2021-10-06 10:47:48 +02:00
2008-08-15 20:40:57 +10:00
if ( must ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" MUST (%s " ,
target = = TARGET_AD_SCHEMA_SUBENTRY ? " " : " " ) ;
2008-08-15 20:40:57 +10:00
APPEND_ATTRS ( must ) ;
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " )%s " , separator ) ;
2008-08-15 20:40:57 +10:00
}
2021-10-06 10:47:48 +02:00
2008-08-15 20:40:57 +10:00
if ( may ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" MAY (%s " ,
target = = TARGET_AD_SCHEMA_SUBENTRY ? " " : " " ) ;
2008-08-15 20:40:57 +10:00
APPEND_ATTRS ( may ) ;
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry , " )%s " , separator ) ;
2008-08-15 20:40:57 +10:00
}
2008-11-14 08:51:59 +01:00
if ( schemaHexGUID ) {
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf (
& schema_entry ,
" CLASS-GUID '%s'%s " ,
schemaHexGUID ,
separator ) ;
2008-11-14 08:51:59 +01:00
}
2021-10-06 10:47:48 +02:00
talloc_asprintf_addbuf ( & schema_entry , " ) " ) ;
2008-08-15 20:40:57 +10:00
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