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