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