From 75c9a1e222c1c5f32bca11c4aae1e2aeaa36efee Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 19 Aug 1999 22:09:33 +0000 Subject: [PATCH] Add OIDmacros for attribute & objectclass numericOIDs. Allow parsing attribute syntaxes using syntax description in addition to syntax OID. Removed all whitespace from syntax descriptions. --- servers/slapd/config.c | 7 +- servers/slapd/proto-slap.h | 6 +- servers/slapd/schema.c | 81 +++++++++-------- servers/slapd/schemaparse.c | 167 +++++++++++++++++++++++++++++++++++- servers/slapd/slap.h | 7 ++ 5 files changed, 227 insertions(+), 41 deletions(-) diff --git a/servers/slapd/config.c b/servers/slapd/config.c index a4e566b49f..294b8ed06f 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -421,12 +421,15 @@ read_config( char *fname ) fname, lineno, 0 ); return( 1 ); #endif + /* specify an Object Identifier macro */ + } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) { + parse_oidm( fname, lineno, cargc, cargv ); /* specify an objectclass */ } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) { if ( *cargv[1] == '(' ) { char * p; p = strchr(saveline,'('); - parse_oc( fname, lineno, p ); + parse_oc( fname, lineno, p, cargv ); } else { parse_oc_old( be, fname, lineno, cargc, cargv ); } @@ -436,7 +439,7 @@ read_config( char *fname ) if ( *cargv[1] == '(' ) { char * p; p = strchr(saveline,'('); - parse_at( fname, lineno, p ); + parse_at( fname, lineno, p, cargv ); } else { attr_syntax_config( fname, lineno, cargc - 1, &cargv[1] ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 59ee788ff7..e4234c7cef 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -357,6 +357,7 @@ int oc_check_no_usermod_attr LDAP_P(( char *type )); ObjectClass *oc_find LDAP_P((const char *ocname)); int oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, const char **err)); Syntax *syn_find LDAP_P((const char *synname)); +Syntax *syn_find_desc LDAP_P((const char *syndesc, int *slen)); int syn_add LDAP_P((LDAP_SYNTAX *syn, slap_syntax_check_func *check, const char **err)); MatchingRule *mr_find LDAP_P((const char *mrname)); int mr_add LDAP_P((LDAP_MATCHING_RULE *mr, slap_mr_normalize_func *normalize, slap_mr_compare_func *compare, const char **err)); @@ -373,9 +374,10 @@ int is_entry_objectclass LDAP_P(( Entry *, char* objectclass )); */ void parse_oc_old LDAP_P(( Backend *be, char *fname, int lineno, int argc, char **argv )); -void parse_oc LDAP_P(( char *fname, int lineno, char *line )); -void parse_at LDAP_P(( char *fname, int lineno, char *line )); +void parse_oc LDAP_P(( char *fname, int lineno, char *line, char **argv )); +void parse_at LDAP_P(( char *fname, int lineno, char *line, char **argv )); char *scherr2str LDAP_P((int code)); +int dscompare LDAP_P(( char *s1, char *s2del, char delim )); /* * str2filter.c */ diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index ad022a60bb..b26fd9004e 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -559,6 +559,17 @@ syn_find( const char *synname ) return( NULL ); } +Syntax * +syn_find_desc( const char *syndesc, int *len ) +{ + Syntax *synp; + + for (synp = syn_list; synp; synp = synp->ssyn_next) + if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{'))) + return synp; + return( NULL ); +} + static int syn_insert( Syntax *ssyn, @@ -879,47 +890,47 @@ struct syntax_defs_rec { }; struct syntax_defs_rec syntax_defs[] = { - {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'AttributeTypeDescription' )", NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' )", NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'BitString' )", NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'CertificateList' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'CertificatePair' )", NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'DeliveryMethod' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'DirectoryString' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DITContentRuleDescription' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DITStructureRuleDescription' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'EnhancedGuide' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'FacsimileTelephoneNumber' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'GeneralizedTime' )", NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'INTEGER' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5String' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'MatchingRuleDescription' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'MatchingRuleUseDescription' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'MailPreference' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'NameAndOptionalUID' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'NameFormDescription' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'NumericString' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'ObjectClassDescription' )", NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )", NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )", NULL}, - {"( 1.3.6.1.1.1.0.0 DESC 'NIS netgroup triple' )", NULL}, - {"( 1.3.6.1.1.1.0.1 DESC 'Boot parameter' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'OtherMailbox' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'OctetString' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'PostalAddress' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'ProtocolInformation' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'PresentationAddress' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'PrintableString' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'SupportedAlgorithm' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'TelephoneNumber' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'TeletexTerminalIdentifier' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'TelexNumber' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTCTime' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAPSyntaxDescription' )", NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'SubstringAssertion' )", NULL}, + {"( 1.3.6.1.1.1.0.0 DESC 'NISnetgrouptriple' )", NULL}, + {"( 1.3.6.1.1.1.0.1 DESC 'Bootparameter' )", NULL}, {NULL, NULL} }; diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c index 202329978f..13f3f6e36f 100644 --- a/servers/slapd/schemaparse.c +++ b/servers/slapd/schemaparse.c @@ -144,23 +144,135 @@ parse_oc_old( ldap_memfree(oc); } +/* OID Macros */ + +/* String compare with delimiter check. Return 0 if not + * matched, otherwise return length matched. + */ +int +dscompare(char *s1, char *s2, char delim) +{ + char *orig = s1; + while (*s1++ == *s2++) + if (!s1[-1]) break; + --s1; + --s2; + if (!*s1 && (!*s2 || *s2 == delim)) + return s1 - orig; + return 0; +} + +static OidMacro *om_list = NULL; + +/* Replace an OID Macro invocation with its full numeric OID. + * If the macro is used with "macroname:suffix" append ".suffix" + * to the expansion. + */ +static char * +find_oidm(char *oid) +{ + OidMacro *om; + char *new; + int pos, suflen; + + /* OID macros must start alpha */ + if ( !isdigit( *oid ) ) + { + for (om = om_list; om; om=om->next) + { + if ((pos = dscompare(om->name, oid, ':'))) + { + suflen = strlen(oid + pos); + new = ch_calloc(1, om->oidlen + suflen + 1); + strcpy(new, om->oid); + if (suflen) + { + suflen = om->oidlen; + new[suflen++] = '.'; + strcpy(new+suflen, oid+pos+1); + } + return new; + } + } + return NULL; + } + return oid; +} + +void +parse_oidm( + char *fname, + int lineno, + int argc, + char **argv +) +{ + OidMacro *om; + + if (argc != 3) + { +usage: fprintf( stderr, "ObjectIdentifier \n"); + exit( EXIT_FAILURE ); + } + om = (OidMacro *) ch_malloc( sizeof(OidMacro) ); + om->name = ch_strdup( argv[1] ); + om->oid = find_oidm( argv[2] ); + if (!om->oid) + { + fprintf( stderr, "%s: line %d: OID %s not recognized\n", + fname, lineno, argv[2] ); + goto usage; + } + if (om->oid == argv[2]) + om->oid = ch_strdup( argv[2] ); + om->oidlen = strlen( om->oid ); + om->next = om_list; + om_list = om; +} + void parse_oc( char *fname, int lineno, - char *line + char *line, + char **argv ) { LDAP_OBJECT_CLASS *oc; int code; const char *err; + char *oid = NULL; + /* Kludge for OIDmacros. If the numericOid field starts nonnumeric + * look for and expand a macro. The macro's place in the input line + * will be replaced with a field of '0's to keep ldap_str2objectclass + * happy. The actual oid will be swapped into place afterward. + */ + if ( !isdigit( *argv[2] )) + { + oid = find_oidm(argv[2]); + if (!oid) + { + fprintf(stderr, "%s: line %d: OID %s not recognized\n", + fname, lineno, argv[2]); + exit( EXIT_FAILURE ); + } + if (oid != argv[2]) + memset(strstr(line, argv[2]), '0', strlen(argv[2])); + else + oid = NULL; + } oc = ldap_str2objectclass(line,&code,&err); if ( !oc ) { fprintf( stderr, "%s: line %d: %s before %s\n", fname, lineno, ldap_scherr2str(code), err ); oc_usage(); } + if (oid) + { + ldap_memfree(oc->oc_oid); + oc->oc_oid = oid; + } code = oc_add(oc,&err); if ( code ) { fprintf( stderr, "%s: line %d: %s %s\n", @@ -226,19 +338,70 @@ void parse_at( char *fname, int lineno, - char *line + char *line, + char **argv ) { LDAP_ATTRIBUTE_TYPE *at; int code; const char *err; + char *oid = NULL; + char *soid = NULL; + /* Kludge for OIDmacros. If the numericOid field starts nonnumeric + * look for and expand a macro. The macro's place in the input line + * will be replaced with a field of '0's to keep ldap_str2attr + * happy. The actual oid will be swapped into place afterward. + */ + if ( !isdigit( *argv[2] )) + { + oid = find_oidm(argv[2]); + if (!oid) + { + fprintf(stderr, "%s: line %d: OID %s not recognized\n", + fname, lineno, argv[2]); + exit( EXIT_FAILURE ); + } + if (oid != argv[2]) + memset(strstr(line, argv[2]), '0', strlen(argv[2])); + else + oid = NULL; + } + for (; argv[3]; argv++) + { + if (!strcasecmp(argv[3], "syntax") && + !isdigit(*argv[4])) + { + int slen; + Syntax *syn; + syn = syn_find_desc(argv[4], &slen); + if (!syn) + { + fprintf(stderr, "%s: line %d: OID %s not found\n", + fname, lineno, argv[4]); + exit( EXIT_FAILURE ); + } + memset(strstr(line, argv[4]), '0', slen); + soid = ch_strdup(syn->ssyn_syn.syn_oid ); + break; + } + } at = ldap_str2attributetype(line,&code,&err); if ( !at ) { fprintf( stderr, "%s: line %d: %s before %s\n", fname, lineno, ldap_scherr2str(code), err ); at_usage(); } + if (oid) + { + ldap_memfree(at->at_oid); + at->at_oid = oid; + } + if (soid) + { + ldap_memfree(at->at_syntax_oid); + at->at_syntax_oid = soid; + } code = at_add(at,&err); if ( code ) { fprintf( stderr, "%s: line %d: %s %s\n", diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index bc67e28b85..4f544f4ca6 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -308,6 +308,13 @@ typedef struct ldapmodlist { /* * represents schema information for a database */ +typedef struct slap_oid_macro { + struct slap_oid_macro *next; + char *name; + char *oid; + int oidlen; +} OidMacro; + typedef int slap_syntax_check_func LDAP_P((struct berval * val)); typedef struct slap_syntax { -- 2.39.5