Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
canvas-demo-techex17/deps/ldap/slapdconf/schema2ldif
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
executable file
343 lines (275 sloc)
7.9 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# | |
# Copyright (c) 2005-2015 Radovan Semancik | |
# Copyright (c) 2014-2015 Evolveum | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# | |
# | |
# schema2ldif: Tool for converting OpenLDAP-style schemas to the LDIF format | |
# ----------- | |
# | |
# The LDIF-formated LDAP schemas are difficult to edit and maintain. OpenLDAP | |
# defined a similar schema format that is more free-form and easier to edit. | |
# This tool converts the OpenLDAP-formatted schema files to the LDIF. | |
# | |
# Original author: Radovan Semancik | |
# | |
# Usage | |
# ----- | |
# | |
# schema2ldif < foo.schema > foo.ldif | |
# | |
# OpenLDAP schema format | |
# ---------------------- | |
# | |
# objectIdentifier nLight 1.3.6.1.4.1.23611 | |
# objectIdentifier nLightLdap nLight:1 | |
# | |
# attributetype ( oid-my-attr-1 | |
# NAME 'my-attr-1' | |
# DESC 'description of my-attr-1 attribute' | |
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 | |
# ) | |
# | |
# attributetype ( nLightLdap:2 | |
# NAME 'my-attr-2' | |
# DESC 'description of my-attr-2 attribute' | |
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 | |
# ) | |
# | |
# objectclass ( oid-my-person | |
# NAME 'my-person' | |
# DESC 'description of my-person attribute' | |
# SUP 'inetOrgPerson' | |
# MAY ( my-attr-1 ) | |
# ) | |
# | |
# LDIF schema format | |
# ------------------ | |
# | |
# dn: cn=schema | |
# objectClass: top | |
# objectClass: ldapSubentry | |
# objectClass: subschema | |
# cn: schema | |
# attributeTypes: ( oid-my-attr-1 NAME 'my-attr-1' DESC 'description of my-attr-1 attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) | |
# attributeTypes: ( 1.3.6.1.4.1.23611.1.2 NAME 'my-attr-2' DESC 'description of my-attr-2 attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) | |
# objectClasses: ( oid-my-person NAME 'my-person' DESC 'description of my-person attribute' SUP 'inetOrgPerson' MAY ( my-attr-1 ) X-ORIGIN 'user defined' ) | |
# | |
use strict; | |
my $mode = "static"; | |
my $flavor = "schema"; | |
my $flavorName = undef; | |
my $origin = 'user defined'; | |
# Turns on debug mode (for development purposes only) | |
my $debug = 0; | |
# Process command-line | |
while ($ARGV[0] =~ /^-/) { | |
my $arg = shift; | |
if ($arg eq "-h") { | |
usage(); | |
exit(); | |
} elsif ($arg eq "-m") { | |
$mode = "modify"; | |
} elsif ($arg eq "-s") { | |
$flavor = "openldap"; | |
$flavorName = shift; | |
} elsif ($arg eq "-o") { | |
$origin = shift; | |
} else { | |
print STDERR "Unknown option $arg\n"; | |
usage(); | |
exit(-1); | |
} | |
} | |
my $attrNameMap = undef; | |
my %ldifAttrNameMap = ( | |
'attributetype' => 'attributeTypes', | |
'objectclass' => 'objectClasses', | |
); | |
my %openLdapAttrNameMap = ( | |
'attributetype' => 'olcAttributeTypes', | |
'objectclass' => 'olcObjectClasses', | |
); | |
my @definitionOrder = qw(attributetype objectclass); | |
my %oidMapping = (); | |
my %definitions = (); | |
# Print proper LDIF header | |
if ($flavor eq "openldap") { | |
print "dn: cn=".$flavorName.",cn=schema,cn=config\n"; | |
if ($mode eq "modify") { | |
print "changetype: add\n"; | |
} | |
print "objectClass: olcSchemaConfig\n"; | |
print "cn: ".$flavorName."\n"; | |
$attrNameMap = \%openLdapAttrNameMap; | |
} else { | |
# schema (pure) flavor | |
if ($mode eq "static") { | |
# Header for static schema | |
# used to drop into a file that server picks up on start | |
print "dn: cn=schema\n"; | |
print "objectClass: top\n"; | |
print "objectClass: ldapSubentry\n"; | |
print "objectClass: subschema\n"; | |
print "cn: schema\n"; | |
} elsif ($mode eq "modify") { | |
# Header for schema that is being uploaded to running server | |
print "dn: cn=schema\n"; | |
print "changetype: modify\n"; | |
} else { | |
die ("Unknown mode $mode\n"); | |
} | |
$attrNameMap = \%ldifAttrNameMap; | |
} | |
# Reading the input schema file in loop | |
# processing definitions | |
READLOOP: | |
while (<>) { | |
# Comments | |
if (/^\s*#/) { | |
# In static mode pass the comments to output file | |
print if ($mode eq "static"); | |
# the comments are ignored in other modes as they make | |
# problems when used with some LDAP clients | |
next; | |
} | |
chomp; | |
if ( /^\s*objectIdentifier\s+(\S+)\s+(\S+)\s*$/) { | |
# We have got objectIdentifier macro here. | |
# Parse it and process to the %oidMapping map | |
my ($name,$oidExpression) = ($1,$2); | |
print STDERR "[P] objectIdentifier: $name -> $oidExpression\n" if $debug; | |
if (isOid($oidExpression)) { | |
$oidMapping{$name} = $oidExpression; | |
print STDERR " adding mapping $name -> $oidExpression\n" if $debug; | |
} else { | |
my $oid = expandOidMacro($oidExpression); | |
if (defined $oid) { | |
$oidMapping{$name} = $oid; | |
print STDERR " adding mapping $name -> $oid\n" if $debug; | |
} else { | |
print STDERR "Error processing objectIdentifier macro: $_\n"; | |
} | |
} | |
} | |
if ( /^\s*(attributetype)\s*\(/i || | |
/^\s*(objectclass)\s*\(/i ) { | |
my $type = lc($1); | |
my $ldifLine = $attrNameMap->{$type}.": ("; | |
$_ = $'; | |
my $level = 1; | |
my $foundOrigin = undef; | |
my $oid = undef; | |
while ($level) { | |
# raise or lower parenthesis level as necessary | |
while ( /\(/g ) { $level++ } | |
while ( /\)/g ) { $level-- } | |
# OID expression should be the very first token | |
# therefore process if it was not processed yet | |
if (! defined $oid && /^\s*(\S+)\s*/) { | |
my $oidExpression = $1; | |
if (isOid($oidExpression)) { | |
# OID expression is OID, no transformation needed | |
$oid = $oidExpression; | |
} else { | |
# Try if OID expression is macro | |
$oid = expandOidMacro($oidExpression); | |
if (! defined $oid) { | |
# OID expression is not macro, copy it verbatim to output | |
# This is used if symbolic names are used instead of OIDs | |
$oid = $oidExpression; | |
} | |
} | |
$ldifLine .= " $oid"; | |
$_ = $'; | |
} | |
# find X-ORIGIN clause in the input | |
if (/X\-ORIGIN\s+\'([^\'*])\'/) { | |
$foundOrigin = $1; | |
} | |
# if we are at the end (level 0) and there was no | |
# X-ORIGIN clause, insert the default one | |
# just before the last parenthesis | |
if ($level == 0 && !defined($foundOrigin)) { | |
s/\)\s*$/ X-ORIGIN \'$origin\' \)/; | |
} | |
$ldifLine .= $_; | |
# is we are at the end, check if the SINGLE-VALUE is in correct place | |
if ($level == 0) { | |
if ($ldifLine =~ /SINGLE-VALUE/ && $ldifLine !~ /SINGLE-VALUE\s+X-ORIGIN/) { | |
warn("The SINGLE-VALUE must be the last clause before X-ORIGIN (oid $oid)\n"); | |
} | |
} | |
$_ = <>; | |
last unless defined $_; | |
# trim whitespaces | |
chomp; | |
s/^\s+/ /; | |
s/\s+$//; | |
} | |
print STDERR "[P] $type: $oid\n" if $debug; | |
if ($mode eq "static") { | |
print $ldifLine . "\n"; | |
} else { | |
if (!$definitions{$type}) { | |
$definitions{$type} = []; | |
} | |
push @{$definitions{$type}},$ldifLine; | |
} | |
last unless defined $_; | |
} | |
} | |
if ($mode eq "modify") { | |
my $first = 1; | |
foreach my $type (@definitionOrder) { | |
next unless ($definitions{$type}); | |
if ($flavor eq "schema") { | |
if ($first) { | |
$first = 0; | |
} else { | |
print "-\n"; | |
} | |
print "add: ".$attrNameMap->{$type}."\n"; | |
} | |
foreach my $line (@{$definitions{$type}}) { | |
print $line."\n"; | |
} | |
} | |
} | |
sub isOid { | |
my ($s) = @_; | |
return ($s =~ /^[\.\d]+$/); | |
} | |
sub expandOidMacro { | |
my ($macro) = @_; | |
if ($macro =~ /:/) { | |
my $key = $`; | |
my $suffix = $'; | |
if (exists $oidMapping{$key}) { | |
return $oidMapping{$key}.".".$suffix; | |
} else { | |
return undef; | |
} | |
} | |
return $oidMapping{$macro}; | |
} | |
sub usage { | |
print STDERR "Usage: $0 [-h ] [-m] [-o <origin> ] in.schema > out.ldif\n"; | |
print STDERR "\t-h\t\tThis help message.\n"; | |
print STDERR "\t-m\t\tGenerate \"modify\" LDIF instead of \"static\"\n"; | |
print STDERR "\t-s <name>\t\tGenerate OpenLDAP LDIF flavor\n"; | |
print STDERR "\t-o <origin>\tSpecify X-ORIGIN to inject (default: user defined)\n"; | |
print STDERR "(c) 2000-2015 Radovan Semancik, Evolveum \n"; | |
} |