1/* schema.c - routines to manage schema definitions */ 2/* $OpenLDAP$ */ 3/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 1998-2011 The OpenLDAP Foundation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted only as authorized by the OpenLDAP 10 * Public License. 11 * 12 * A copy of this license is available in the file LICENSE in the 13 * top-level directory of the distribution or, alternatively, at 14 * <http://www.OpenLDAP.org/license.html>. 15 */ 16 17#include "portable.h" 18 19#include <stdio.h> 20 21#include <ac/ctype.h> 22#include <ac/string.h> 23#include <ac/socket.h> 24 25#include "slap.h" 26#include "lutil.h" 27 28 29int 30schema_info( Entry **entry, const char **text ) 31{ 32 AttributeDescription *ad_structuralObjectClass 33 = slap_schema.si_ad_structuralObjectClass; 34 AttributeDescription *ad_objectClass 35 = slap_schema.si_ad_objectClass; 36 AttributeDescription *ad_createTimestamp 37 = slap_schema.si_ad_createTimestamp; 38 AttributeDescription *ad_modifyTimestamp 39 = slap_schema.si_ad_modifyTimestamp; 40 41 Entry *e; 42 struct berval vals[5]; 43 struct berval nvals[5]; 44 45 e = entry_alloc(); 46 if( e == NULL ) { 47 /* Out of memory, do something about it */ 48 Debug( LDAP_DEBUG_ANY, 49 "schema_info: entry_alloc failed - out of memory.\n", 0, 0, 0 ); 50 *text = "out of memory"; 51 return LDAP_OTHER; 52 } 53 54 e->e_attrs = NULL; 55 /* backend-specific schema info should be created by the 56 * backend itself 57 */ 58 ber_dupbv( &e->e_name, &frontendDB->be_schemadn ); 59 ber_dupbv( &e->e_nname, &frontendDB->be_schemandn ); 60 e->e_private = NULL; 61 62 BER_BVSTR( &vals[0], "subentry" ); 63 if( attr_merge_one( e, ad_structuralObjectClass, vals, NULL ) ) { 64 /* Out of memory, do something about it */ 65 entry_free( e ); 66 *text = "out of memory"; 67 return LDAP_OTHER; 68 } 69 70 BER_BVSTR( &vals[0], "top" ); 71 BER_BVSTR( &vals[1], "subentry" ); 72 BER_BVSTR( &vals[2], "subschema" ); 73 BER_BVSTR( &vals[3], "extensibleObject" ); 74 BER_BVZERO( &vals[4] ); 75 if ( attr_merge( e, ad_objectClass, vals, NULL ) ) { 76 /* Out of memory, do something about it */ 77 entry_free( e ); 78 *text = "out of memory"; 79 return LDAP_OTHER; 80 } 81 82 { 83 int rc; 84 AttributeDescription *desc = NULL; 85 struct berval rdn = frontendDB->be_schemadn; 86 vals[0].bv_val = ber_bvchr( &rdn, '=' ); 87 88 if( vals[0].bv_val == NULL ) { 89 *text = "improperly configured subschema subentry"; 90 return LDAP_OTHER; 91 } 92 93 vals[0].bv_val++; 94 vals[0].bv_len = rdn.bv_len - (vals[0].bv_val - rdn.bv_val); 95 rdn.bv_len -= vals[0].bv_len + 1; 96 97 rc = slap_bv2ad( &rdn, &desc, text ); 98 99 if( rc != LDAP_SUCCESS ) { 100 entry_free( e ); 101 *text = "improperly configured subschema subentry"; 102 return LDAP_OTHER; 103 } 104 105 nvals[0].bv_val = ber_bvchr( &frontendDB->be_schemandn, '=' ); 106 assert( nvals[0].bv_val != NULL ); 107 nvals[0].bv_val++; 108 nvals[0].bv_len = frontendDB->be_schemandn.bv_len - 109 (nvals[0].bv_val - frontendDB->be_schemandn.bv_val); 110 111 if ( attr_merge_one( e, desc, vals, nvals ) ) { 112 /* Out of memory, do something about it */ 113 entry_free( e ); 114 *text = "out of memory"; 115 return LDAP_OTHER; 116 } 117 } 118 119 { 120 char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; 121 122 /* 123 * According to RFC 4512: 124 125 Servers SHOULD maintain the 'creatorsName', 'createTimestamp', 126 'modifiersName', and 'modifyTimestamp' attributes for all entries of 127 the DIT. 128 129 * to be conservative, we declare schema created 130 * AND modified at server startup time ... 131 */ 132 133 vals[0].bv_val = timebuf; 134 vals[0].bv_len = sizeof( timebuf ); 135 136 slap_timestamp( &starttime, vals ); 137 138 if( attr_merge_one( e, ad_createTimestamp, vals, NULL ) ) { 139 /* Out of memory, do something about it */ 140 entry_free( e ); 141 *text = "out of memory"; 142 return LDAP_OTHER; 143 } 144 if( attr_merge_one( e, ad_modifyTimestamp, vals, NULL ) ) { 145 /* Out of memory, do something about it */ 146 entry_free( e ); 147 *text = "out of memory"; 148 return LDAP_OTHER; 149 } 150 } 151 152 if ( syn_schema_info( e ) 153 || mr_schema_info( e ) 154 || mru_schema_info( e ) 155 || at_schema_info( e ) 156 || oc_schema_info( e ) 157 || cr_schema_info( e ) ) 158 { 159 /* Out of memory, do something about it */ 160 entry_free( e ); 161 *text = "out of memory"; 162 return LDAP_OTHER; 163 } 164 165 *entry = e; 166 return LDAP_SUCCESS; 167} 168