mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
5a54b204c3
Counters which are used in the way "for (i = 0; array[i] != NULL; i++)" I modified to "unsigned" since for sure we don't want to have negative array indexes there.
415 lines
12 KiB
C
415 lines
12 KiB
C
/*
|
|
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"
|
|
#include "librpc/ndr/libndr.h"
|
|
|
|
#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,
|
|
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)
|
|
{
|
|
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);
|
|
}
|
|
|
|
if (syntax) {
|
|
schema_entry = talloc_asprintf_append(schema_entry,
|
|
"SYNTAX %s%s", syntax, seperator);
|
|
IF_NULL_FAIL_RET(schema_entry);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
const char *syntax = attribute->syntax->ldap_oid;
|
|
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, talloc_asprintf(tmp_ctx, "'%s'", syntax),
|
|
attribute->isSingleValued,
|
|
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),
|
|
attribute->systemOnly);
|
|
talloc_free(tmp_ctx);
|
|
return schema_description;
|
|
}
|
|
|
|
#define APPEND_ATTRS(attributes) \
|
|
do { \
|
|
unsigned int k; \
|
|
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,
|
|
const char **must,
|
|
const char **may,
|
|
const char *schemaHexGUID)
|
|
{
|
|
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);
|
|
}
|
|
|
|
if (subClassOf && strcasecmp(subClassOf, name) != 0) {
|
|
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,
|
|
"MUST (%s", target == TARGET_AD_SCHEMA_SUBENTRY ? "" : " ");
|
|
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,
|
|
"MAY (%s", target == TARGET_AD_SCHEMA_SUBENTRY ? "" : " ");
|
|
IF_NULL_FAIL_RET(schema_entry);
|
|
|
|
APPEND_ATTRS(may);
|
|
|
|
schema_entry = talloc_asprintf_append(schema_entry,
|
|
")%s", seperator);
|
|
IF_NULL_FAIL_RET(schema_entry);
|
|
}
|
|
|
|
if (schemaHexGUID) {
|
|
schema_entry = talloc_asprintf_append(schema_entry,
|
|
"CLASS-GUID '%s'%s",
|
|
schemaHexGUID, seperator);
|
|
IF_NULL_FAIL_RET(schema_entry);
|
|
}
|
|
|
|
schema_entry = talloc_asprintf_append(schema_entry,
|
|
")");
|
|
return schema_entry;
|
|
}
|
|
|
|
char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass)
|
|
{
|
|
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,
|
|
" ",
|
|
sclass->governsID_oid,
|
|
sclass->lDAPDisplayName,
|
|
NULL,
|
|
sclass->subClassOf,
|
|
sclass->objectClassCategory,
|
|
dsdb_attribute_list(tmp_ctx,
|
|
sclass, DSDB_SCHEMA_ALL_MUST),
|
|
dsdb_attribute_list(tmp_ctx,
|
|
sclass, DSDB_SCHEMA_ALL_MAY),
|
|
NULL);
|
|
talloc_free(tmp_ctx);
|
|
return schema_description;
|
|
}
|
|
|
|
char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass,
|
|
const struct dsdb_schema *schema)
|
|
{
|
|
unsigned int i;
|
|
char *schema_description;
|
|
const char **aux_class_list = NULL;
|
|
const char **attrs;
|
|
const char **must_attr_list = NULL;
|
|
const char **may_attr_list = NULL;
|
|
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
|
const struct dsdb_class *aux_class;
|
|
if (!tmp_ctx) {
|
|
return NULL;
|
|
}
|
|
|
|
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);
|
|
|
|
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,
|
|
" ",
|
|
sclass->governsID_oid,
|
|
sclass->lDAPDisplayName,
|
|
(const char **)aux_class_list,
|
|
NULL, /* Must not specify a
|
|
* SUP (subclass) in
|
|
* ditContentRules
|
|
* per MS-ADTS
|
|
* 3.1.1.3.1.1.1 */
|
|
-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));
|
|
talloc_free(tmp_ctx);
|
|
return schema_description;
|
|
}
|
|
|
|
|