2005-10-14 11:38:16 +04:00
#!/bin/sh
exec smbscript "$0" $ { 1 + "$@" }
/ *
2005-11-01 10:07:48 +03:00
work out the minimal schema for a set of objectclasses
2005-10-14 11:38:16 +04:00
* /
libinclude ( "base.js" ) ;
var ldb = ldb _init ( ) ;
var options = GetOptions ( ARGV ,
"POPT_AUTOHELP" ,
"POPT_COMMON_SAMBA" ,
2005-11-01 10:07:48 +03:00
"POPT_COMMON_CREDENTIALS" ,
2007-01-24 15:46:26 +03:00
"verbose" ,
"classes" ,
"attributes" ,
"subschema" ,
"subschema-auto" ) ;
2005-10-14 11:38:16 +04:00
if ( options == undefined ) {
println ( "Failed to parse options" ) ;
return - 1 ;
}
2005-11-01 10:07:48 +03:00
verbose = options [ "verbose" ] ;
2007-01-24 15:46:26 +03:00
dump _all = "yes" ;
dump _classes = options [ "classes" ] ;
dump _attributes = options [ "attributes" ] ;
dump _subschema = options [ "subschema" ] ;
dump _subschema _auto = options [ "subschema-auto" ] ;
if ( dump _classes != undefined ) {
dump _all = undefined ;
}
if ( dump _attributes != undefined ) {
dump _all = undefined ;
}
if ( dump _subschema != undefined ) {
dump _all = undefined ;
}
if ( dump _subschema _auto != undefined ) {
dump _all = undefined ;
dump _subschema = "yes" ;
}
if ( dump _all != undefined ) {
dump _classes = "yes" ;
dump _attributes = "yes" ;
dump _subschema = "yes" ;
dump _subschema _auto = "yes" ;
}
2005-10-14 11:38:16 +04:00
2005-11-01 10:07:48 +03:00
if ( options . ARGV . length != 2 ) {
println ( "Usage: minschema.js <URL> <classfile>" ) ;
2005-10-14 11:38:16 +04:00
return - 1 ;
}
var url = options . ARGV [ 0 ] ;
2005-11-01 10:07:48 +03:00
var classfile = options . ARGV [ 1 ] ;
2005-10-14 11:38:16 +04:00
2006-08-21 06:44:51 +04:00
/* use command line creds if available */
ldb . credentials = options . get _credentials ( ) ;
2005-10-14 11:38:16 +04:00
var ok = ldb . connect ( url ) ;
assert ( ok ) ;
objectclasses = new Object ( ) ;
attributes = new Object ( ) ;
2005-11-01 10:07:48 +03:00
rootDse = new Object ( ) ;
2006-08-21 17:04:14 +04:00
objectclasses _expanded = new Object ( ) ;
2005-11-01 10:07:48 +03:00
/* the attributes we need for objectclasses */
2007-01-24 15:23:42 +03:00
class _attrs = new Array ( "objectClass" ,
"subClassOf" ,
"governsID" ,
"possSuperiors" ,
2007-06-21 09:14:13 +04:00
"possibleInferiors" ,
2007-01-24 15:23:42 +03:00
"mayContain" ,
"mustContain" ,
"auxiliaryClass" ,
"rDNAttID" ,
"showInAdvancedViewOnly" ,
"adminDisplayName" ,
"adminDescription" ,
"objectClassCategory" ,
"lDAPDisplayName" ,
"schemaIDGUID" ,
"systemOnly" ,
"systemPossSuperiors" ,
"systemMayContain" ,
"systemMustContain" ,
"systemAuxiliaryClass" ,
"defaultSecurityDescriptor" ,
"systemFlags" ,
"defaultHidingValue" ,
"objectCategory" ,
"defaultObjectCategory" ,
/* this attributes are not used by w2k3 */
"schemaFlagsEx" ,
"msDs-IntId" ,
"msDs-Schema-Extensions" ,
"classDisplayName" ,
"isDefunct" ) ;
attrib _attrs = new Array ( "objectClass" ,
"attributeID" ,
"attributeSyntax" ,
"isSingleValued" ,
"rangeLower" ,
"rangeUpper" ,
"mAPIID" ,
"linkID" ,
"showInAdvancedViewOnly" ,
"adminDisplayName" ,
"oMObjectClass" ,
"adminDescription" ,
"oMSyntax" ,
"searchFlags" ,
"extendedCharsAllowed" ,
"lDAPDisplayName" ,
"schemaIDGUID" ,
"attributeSecurityGUID" ,
"systemOnly" ,
"systemFlags" ,
"isMemberOfPartialAttributeSet" ,
"objectCategory" ,
/* this attributes are not used by w2k3 */
"schemaFlagsEx" ,
"msDs-IntId" ,
"msDs-Schema-Extensions" ,
"classDisplayName" ,
"isEphemeral" ,
"isDefunct" ) ;
2005-11-01 10:07:48 +03:00
/ *
notes :
objectClassCategory
1 : structural
2 : abstract
3 : auxiliary
* /
/ *
print only if verbose is set
* /
function dprintf ( ) {
if ( verbose != undefined ) {
print ( vsprintf ( arguments ) ) ;
}
}
2006-08-21 07:52:43 +04:00
function get _object _cn ( ldb , name ) {
var attrs = new Array ( "cn" ) ;
var res = ldb . search ( sprintf ( "(ldapDisplayName=%s)" , name ) , rootDse . schemaNamingContext , ldb . SCOPE _SUBTREE , attrs ) ;
assert ( res != undefined ) ;
2007-02-15 00:55:29 +03:00
assert ( res . msgs . length == 1 ) ;
2006-08-21 07:52:43 +04:00
2007-02-15 00:55:29 +03:00
var cn = res . msgs [ 0 ] [ "cn" ] ;
2006-08-21 07:52:43 +04:00
assert ( cn != undefined ) ;
if ( typeof ( cn ) == "string" ) {
return cn ;
}
return cn [ 0 ] ;
}
2005-11-01 10:07:48 +03:00
/ *
create an objectclass object
* /
2006-08-21 07:52:43 +04:00
function obj _objectClass ( ldb , name ) {
2005-11-01 10:07:48 +03:00
var o = new Object ( ) ;
o . name = name ;
2006-08-21 07:52:43 +04:00
o . cn = get _object _cn ( ldb , name ) ;
2005-11-01 10:07:48 +03:00
return o ;
}
/ *
create an attribute object
* /
2006-08-21 07:52:43 +04:00
function obj _attribute ( ldb , name ) {
2005-11-01 10:07:48 +03:00
var o = new Object ( ) ;
o . name = name ;
2006-08-21 07:52:43 +04:00
o . cn = get _object _cn ( ldb , name ) ;
2005-11-01 10:07:48 +03:00
return o ;
}
2005-11-02 05:32:25 +03:00
syntaxmap = new Object ( ) ;
2005-11-02 06:23:05 +03:00
syntaxmap [ '2.5.5.1' ] = '1.3.6.1.4.1.1466.115.121.1.12' ;
syntaxmap [ '2.5.5.2' ] = '1.3.6.1.4.1.1466.115.121.1.38' ;
syntaxmap [ '2.5.5.3' ] = '1.2.840.113556.1.4.1362' ;
syntaxmap [ '2.5.5.4' ] = '1.2.840.113556.1.4.905' ;
syntaxmap [ '2.5.5.5' ] = '1.3.6.1.4.1.1466.115.121.1.26' ;
syntaxmap [ '2.5.5.6' ] = '1.3.6.1.4.1.1466.115.121.1.36' ;
syntaxmap [ '2.5.5.7' ] = '1.2.840.113556.1.4.903' ;
syntaxmap [ '2.5.5.8' ] = '1.3.6.1.4.1.1466.115.121.1.7' ;
2005-11-02 05:32:25 +03:00
syntaxmap [ '2.5.5.9' ] = '1.3.6.1.4.1.1466.115.121.1.27' ;
syntaxmap [ '2.5.5.10' ] = '1.3.6.1.4.1.1466.115.121.1.40' ;
syntaxmap [ '2.5.5.11' ] = '1.3.6.1.4.1.1466.115.121.1.24' ;
syntaxmap [ '2.5.5.12' ] = '1.3.6.1.4.1.1466.115.121.1.15' ;
2005-11-02 06:23:05 +03:00
syntaxmap [ '2.5.5.13' ] = '1.3.6.1.4.1.1466.115.121.1.43' ;
syntaxmap [ '2.5.5.14' ] = '1.2.840.113556.1.4.904' ;
syntaxmap [ '2.5.5.15' ] = '1.2.840.113556.1.4.907' ;
syntaxmap [ '2.5.5.16' ] = '1.2.840.113556.1.4.906' ;
syntaxmap [ '2.5.5.17' ] = '1.3.6.1.4.1.1466.115.121.1.40' ;
2005-11-02 05:32:25 +03:00
/ *
map some attribute syntaxes from some apparently MS specific
syntaxes to the standard syntaxes
* /
function map _attribute _syntax ( s ) {
if ( syntaxmap [ s ] != undefined ) {
return syntaxmap [ s ] ;
}
return s ;
}
2005-11-01 10:07:48 +03:00
/ *
2007-01-24 15:23:42 +03:00
fix a string DN to use $ { SCHEMADN }
2005-11-01 10:07:48 +03:00
* /
function fix _dn ( dn ) {
2007-01-24 15:23:42 +03:00
var s = strstr ( dn , rootDse . schemaNamingContext ) ;
2005-11-01 10:07:48 +03:00
if ( s == NULL ) {
return dn ;
}
2007-01-24 15:23:42 +03:00
return substr ( dn , 0 , strlen ( dn ) - strlen ( s ) ) + "${SCHEMADN}" ;
2005-11-01 10:07:48 +03:00
}
/ *
dump an object as ldif
* /
function write _ldif _one ( o , attrs ) {
var i ;
2007-01-24 15:23:42 +03:00
printf ( "dn: CN=%s,${SCHEMADN}\n" , o . cn ) ;
2005-11-01 10:07:48 +03:00
for ( i = 0 ; i < attrs . length ; i ++ ) {
var a = attrs [ i ] ;
if ( o [ a ] == undefined ) {
continue ;
}
2006-08-21 07:52:43 +04:00
/* special case for oMObjectClass, which is a binary object */
if ( a == "oMObjectClass" ) {
printf ( "%s:: %s\n" , a , o [ a ] ) ;
continue ;
}
2005-11-01 10:07:48 +03:00
var v = o [ a ] ;
if ( typeof ( v ) == "string" ) {
v = new Array ( v ) ;
}
var j ;
for ( j = 0 ; j < v . length ; j ++ ) {
printf ( "%s: %s\n" , a , fix _dn ( v [ j ] ) ) ;
}
}
printf ( "\n" ) ;
}
/ *
dump an array of objects as ldif
* /
function write _ldif ( o , attrs ) {
var i ;
for ( i in o ) {
write _ldif _one ( o [ i ] , attrs ) ;
}
}
/ *
create a testDN based an an example DN
the idea is to ensure we obey any structural rules
* /
function create _testdn ( exampleDN ) {
var a = split ( "," , exampleDN ) ;
a [ 0 ] = "CN=TestDN" ;
return join ( "," , a ) ;
}
/ *
find the properties of an objectclass
* /
function find _objectclass _properties ( ldb , o ) {
var res = ldb . search (
sprintf ( "(ldapDisplayName=%s)" , o . name ) ,
rootDse . schemaNamingContext , ldb . SCOPE _SUBTREE , class _attrs ) ;
assert ( res != undefined ) ;
2007-02-15 00:55:29 +03:00
assert ( res . msgs . length == 1 ) ;
var msg = res . msgs [ 0 ] ;
2005-11-01 10:07:48 +03:00
var a ;
for ( a in msg ) {
o [ a ] = msg [ a ] ;
}
}
/ *
find the properties of an attribute
* /
function find _attribute _properties ( ldb , o ) {
var res = ldb . search (
sprintf ( "(ldapDisplayName=%s)" , o . name ) ,
rootDse . schemaNamingContext , ldb . SCOPE _SUBTREE , attrib _attrs ) ;
assert ( res != undefined ) ;
2007-02-15 00:55:29 +03:00
assert ( res . msgs . length == 1 ) ;
var msg = res . msgs [ 0 ] ;
2005-11-01 10:07:48 +03:00
var a ;
for ( a in msg ) {
2006-08-21 07:52:43 +04:00
/* special case for oMObjectClass, which is a binary object */
if ( a == "oMObjectClass" ) {
o [ a ] = ldb . encode ( msg [ a ] ) ;
continue ;
}
2005-11-01 10:07:48 +03:00
o [ a ] = msg [ a ] ;
}
}
/ *
find the auto - created properties of an objectclass . Only works for classes
that can be created using just a DN and the objectclass
* /
function find _objectclass _auto ( ldb , o ) {
if ( o [ "exampleDN" ] == undefined ) {
return ;
}
var testdn = create _testdn ( o . exampleDN ) ;
var ok ;
dprintf ( "testdn is '%s'\n" , testdn ) ;
var ldif = "dn: " + testdn ;
ldif = ldif + "\nobjectClass: " + o . name ;
ok = ldb . add ( ldif ) ;
2007-02-15 00:55:29 +03:00
if ( ok . error != 0 ) {
dprintf ( "error adding %s: %s\n" , o . name , ok . errstr ) ;
2005-11-01 10:07:48 +03:00
dprintf ( "%s\n" , ldif ) ;
return ;
}
var res = ldb . search ( "" , testdn , ldb . SCOPE _BASE ) ;
ok = ldb . del ( testdn ) ;
2007-02-15 00:55:29 +03:00
assert ( ok . error == 0 ) ;
2005-11-01 10:07:48 +03:00
var a ;
2007-02-15 00:55:29 +03:00
for ( a in res . msgs [ 0 ] ) {
2005-11-01 10:07:48 +03:00
attributes [ a ] . autocreate = true ;
}
}
/ *
look at auxiliary information from a class to intuit the existance of more
classes needed for a minimal schema
* /
function expand _objectclass ( ldb , o ) {
var attrs = new Array ( "auxiliaryClass" , "systemAuxiliaryClass" ,
"possSuperiors" , "systemPossSuperiors" ,
"subClassOf" ) ;
var res = ldb . search (
sprintf ( "(&(objectClass=classSchema)(ldapDisplayName=%s))" , o . name ) ,
rootDse . schemaNamingContext , ldb . SCOPE _SUBTREE , attrs ) ;
var a ;
dprintf ( "Expanding class %s\n" , o . name ) ;
assert ( res != undefined ) ;
2007-02-15 00:55:29 +03:00
assert ( res . msgs . length == 1 ) ;
var msg = res . msgs [ 0 ] ;
2005-11-01 10:07:48 +03:00
for ( a = 0 ; a < attrs . length ; a ++ ) {
var aname = attrs [ a ] ;
if ( msg [ aname ] == undefined ) {
continue ;
}
var list = msg [ aname ] ;
if ( typeof ( list ) == "string" ) {
list = new Array ( msg [ aname ] ) ;
}
var i ;
for ( i = 0 ; i < list . length ; i ++ ) {
var name = list [ i ] ;
if ( objectclasses [ name ] == undefined ) {
dprintf ( "Found new objectclass '%s'\n" , name ) ;
2006-08-21 07:52:43 +04:00
objectclasses [ name ] = obj _objectClass ( ldb , name ) ;
2005-11-01 10:07:48 +03:00
}
}
}
}
/ *
add the must and may attributes from an objectclass to the full list
of attributes
* /
function add _objectclass _attributes ( ldb , class ) {
var attrs = new Array ( "mustContain" , "systemMustContain" ,
"mayContain" , "systemMayContain" ) ;
var i ;
for ( i = 0 ; i < attrs . length ; i ++ ) {
var aname = attrs [ i ] ;
if ( class [ aname ] == undefined ) {
continue ;
}
var alist = class [ aname ] ;
if ( typeof ( alist ) == "string" ) {
alist = new Array ( alist ) ;
}
var j ;
var len = alist . length ;
for ( j = 0 ; j < len ; j ++ ) {
var a = alist [ j ] ;
if ( attributes [ a ] == undefined ) {
2006-08-21 07:52:43 +04:00
attributes [ a ] = obj _attribute ( ldb , a ) ;
2005-11-01 10:07:48 +03:00
}
}
}
}
2005-10-14 11:38:16 +04:00
/ *
process an individual record , working out what attributes it has
* /
function walk _dn ( ldb , dn ) {
/* get a list of all possible attributes for this object */
var attrs = new Array ( "allowedAttributes" ) ;
var res = ldb . search ( "objectClass=*" , dn , ldb . SCOPE _BASE , attrs ) ;
2007-02-15 00:55:29 +03:00
if ( res . error != 0 ) {
2005-11-01 10:07:48 +03:00
dprintf ( "Unable to fetch allowedAttributes for '%s' - %s\n" ,
2007-02-15 00:55:29 +03:00
dn , res . errstr ) ;
2005-10-14 11:38:16 +04:00
return ;
}
2007-02-15 00:55:29 +03:00
var allattrs = res . msgs [ 0 ] . allowedAttributes ;
2005-10-14 11:38:16 +04:00
res = ldb . search ( "objectClass=*" , dn , ldb . SCOPE _BASE , allattrs ) ;
2007-02-15 00:55:29 +03:00
if ( res . error != 0 ) {
2005-11-01 10:07:48 +03:00
dprintf ( "Unable to fetch all attributes for '%s' - %s\n" ,
2007-02-15 00:55:29 +03:00
dn , res . errstr ) ;
2005-10-14 11:38:16 +04:00
return ;
}
var a ;
2007-02-15 00:55:29 +03:00
var msg = res . msgs [ 0 ] ;
2005-10-14 11:38:16 +04:00
for ( a in msg ) {
2005-11-01 10:07:48 +03:00
if ( attributes [ a ] == undefined ) {
2006-08-21 07:52:43 +04:00
attributes [ a ] = obj _attribute ( ldb , a ) ;
2005-11-01 10:07:48 +03:00
}
2005-10-14 11:38:16 +04:00
}
}
/ *
walk a naming context , looking for all records
* /
function walk _naming _context ( ldb , namingContext ) {
var attrs = new Array ( "objectClass" ) ;
var res = ldb . search ( "objectClass=*" , namingContext , ldb . SCOPE _DEFAULT , attrs ) ;
2007-02-15 00:55:29 +03:00
if ( res . error != 0 ) {
2005-11-01 10:07:48 +03:00
dprintf ( "Unable to fetch objectClasses for '%s' - %s\n" ,
2007-02-15 00:55:29 +03:00
namingContext , res . errstr ) ;
2005-10-14 11:38:16 +04:00
return ;
}
var r ;
2007-02-15 00:55:29 +03:00
for ( r = 0 ; r < res . msgs . length ; r ++ ) {
var msg = res . msgs [ r ] . objectClass ;
2005-10-14 11:38:16 +04:00
var c ;
for ( c = 0 ; c < msg . length ; c ++ ) {
var objectClass = msg [ c ] ;
2005-11-01 10:07:48 +03:00
if ( objectclasses [ objectClass ] == undefined ) {
2006-08-21 07:52:43 +04:00
objectclasses [ objectClass ] = obj _objectClass ( ldb , objectClass ) ;
2007-02-15 00:55:29 +03:00
objectclasses [ objectClass ] . exampleDN = res . msgs [ r ] . dn ;
2005-11-01 10:07:48 +03:00
}
2005-10-14 11:38:16 +04:00
}
2007-02-15 00:55:29 +03:00
walk _dn ( ldb , res . msgs [ r ] . dn ) ;
2005-10-14 11:38:16 +04:00
}
}
/ *
2005-11-01 10:07:48 +03:00
trim the may attributes for an objectClass
* /
function trim _objectclass _attributes ( ldb , class ) {
2006-08-26 19:38:01 +04:00
var i , j , n ;
/ * t r i m p o s s i b l e I n f e r i o r s ,
* include only the classes we extracted * /
var possinf = class [ "possibleInferiors" ] ;
if ( possinf != undefined ) {
var newpossinf = new Array ( ) ;
if ( typeof ( possinf ) == "string" ) {
possinf = new Array ( possinf ) ;
}
n = 0 ;
for ( j = 0 ; j < possinf . length ; j ++ ) {
var x = possinf [ j ] ;
if ( objectclasses [ x ] != undefined ) {
newpossinf [ n ] = x ;
n ++ ;
}
}
class [ "possibleInferiors" ] = newpossinf ;
}
/ * t r i m s y s t e m M a y C o n t a i n ,
* remove duplicates * /
var sysmay = class [ "systemMayContain" ] ;
if ( sysmay != undefined ) {
var newsysmay = new Array ( ) ;
if ( typeof ( sysmay ) == "string" ) {
sysmay = new Array ( sysmay ) ;
}
for ( j = 0 ; j < sysmay . length ; j ++ ) {
var x = sysmay [ j ] ;
var dup = false ;
if ( newsysmay [ 0 ] == undefined ) {
newsysmay [ 0 ] = x ;
} else {
for ( n = 0 ; n < newsysmay . length ; n ++ ) {
if ( newsysmay [ n ] == x ) {
dup = true ;
}
}
if ( dup == false ) {
newsysmay [ n ] = x ;
}
}
}
class [ "systemMayContain" ] = newsysmay ;
}
/ * t r i m m a y C o n t a i n ,
* remove duplicates * /
var may = class [ "mayContain" ] ;
if ( may != undefined ) {
var newmay = new Array ( ) ;
if ( typeof ( may ) == "string" ) {
may = new Array ( may ) ;
}
for ( j = 0 ; j < may . length ; j ++ ) {
var x = may [ j ] ;
var dup = false ;
if ( newmay [ 0 ] == undefined ) {
newmay [ 0 ] = x ;
} else {
for ( n = 0 ; n < newmay . length ; n ++ ) {
if ( newmay [ n ] == x ) {
dup = true ;
}
}
if ( dup == false ) {
newmay [ n ] = x ;
}
}
}
class [ "mayContain" ] = newmay ;
}
2005-11-01 10:07:48 +03:00
}
/ *
load the basic attributes of an objectClass
* /
function build _objectclass ( ldb , name ) {
var attrs = new Array ( "name" ) ;
var res = ldb . search (
sprintf ( "(&(objectClass=classSchema)(ldapDisplayName=%s))" , name ) ,
rootDse . schemaNamingContext , ldb . SCOPE _SUBTREE , attrs ) ;
2007-02-15 00:55:29 +03:00
if ( res . error != 0 ) {
2005-11-01 10:07:48 +03:00
dprintf ( "unknown class '%s'\n" , name ) ;
return undefined ;
}
2007-02-15 00:55:29 +03:00
if ( res . msgs . length == 0 ) {
2005-11-01 10:07:48 +03:00
dprintf ( "unknown class '%s'\n" , name ) ;
return undefined ;
}
2006-08-21 07:52:43 +04:00
return obj _objectClass ( ldb , name ) ;
2005-11-01 10:07:48 +03:00
}
/ *
append 2 lists
* /
function list _append ( a1 , a2 ) {
var i ;
if ( a1 == undefined ) {
return a2 ;
}
if ( a2 == undefined ) {
return a1 ;
}
for ( i = 0 ; i < a2 . length ; i ++ ) {
a1 [ a1 . length ] = a2 [ i ] ;
}
return a1 ;
}
/ *
form a coalesced attribute list
* /
function attribute _list ( class , attr1 , attr2 ) {
var a1 = class [ attr1 ] ;
var a2 = class [ attr2 ] ;
if ( typeof ( a1 ) == "string" ) {
a1 = new Array ( a1 ) ;
}
if ( typeof ( a2 ) == "string" ) {
a2 = new Array ( a2 ) ;
}
return list _append ( a1 , a2 ) ;
}
/ *
write out a list in aggregate form
* /
function aggregate _list ( name , list ) {
if ( list == undefined ) {
return ;
}
var i ;
printf ( "%s ( " , name ) ;
for ( i = 0 ; i < list . length ; i ++ ) {
printf ( "%s " , list [ i ] ) ;
if ( i < ( list . length - 1 ) ) {
printf ( "$ " ) ;
}
}
printf ( ") " ) ;
}
/ *
write the aggregate record for an objectclass
2005-10-14 11:38:16 +04:00
* /
2005-11-01 10:07:48 +03:00
function write _aggregate _objectclass ( class ) {
printf ( "objectClasses: ( %s NAME '%s' " , class . governsID , class . name ) ;
if ( class [ 'subClassOf' ] != undefined ) {
printf ( "SUP %s " , class [ 'subClassOf' ] ) ;
}
if ( class . objectClassCategory == 1 ) {
printf ( "STRUCTURAL " ) ;
} else if ( class . objectClassCategory == 2 ) {
printf ( "ABSTRACT " ) ;
} else if ( class . objectClassCategory == 3 ) {
printf ( "AUXILIARY " ) ;
}
var list ;
list = attribute _list ( class , "systemMustContain" , "mustContain" ) ;
aggregate _list ( "MUST" , list ) ;
list = attribute _list ( class , "systemMayContain" , "mayContain" ) ;
aggregate _list ( "MAY" , list ) ;
printf ( ")\n" ) ;
}
2005-10-14 11:38:16 +04:00
/ *
2005-11-01 10:07:48 +03:00
write the aggregate record for an ditcontentrule
2005-10-14 11:38:16 +04:00
* /
2005-11-01 10:07:48 +03:00
function write _aggregate _ditcontentrule ( class ) {
var list = attribute _list ( class , "auxiliaryClass" , "systemAuxiliaryClass" ) ;
var i ;
if ( list == undefined ) {
return ;
}
printf ( "dITContentRules: ( %s NAME '%s' " , class . governsID , class . name ) ;
aggregate _list ( "AUX" , list ) ;
var may _list = undefined ;
var must _list = undefined ;
for ( i = 0 ; i < list . length ; i ++ ) {
var c = list [ i ] ;
var list2 ;
list2 = attribute _list ( objectclasses [ c ] ,
"mayContain" , "systemMayContain" ) ;
may _list = list _append ( may _list , list2 ) ;
list2 = attribute _list ( objectclasses [ c ] ,
"mustContain" , "systemMustContain" ) ;
must _list = list _append ( must _list , list2 ) ;
}
aggregate _list ( "MUST" , must _list ) ;
aggregate _list ( "MAY" , may _list ) ;
printf ( ")\n" ) ;
}
/ *
write the aggregate record for an attribute
* /
function write _aggregate _attribute ( attrib ) {
printf ( "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " ,
2005-11-02 05:32:25 +03:00
attrib . attributeID , attrib . name ,
map _attribute _syntax ( attrib . attributeSyntax ) ) ;
2005-11-01 10:07:48 +03:00
if ( attrib [ 'isSingleValued' ] == "TRUE" ) {
printf ( "SINGLE-VALUE " ) ;
}
2007-01-24 15:23:42 +03:00
if ( attrib [ 'systemOnly' ] == "TRUE" ) {
printf ( "NO-USER-MODIFICATION " ) ;
}
2005-11-01 10:07:48 +03:00
printf ( ")\n" ) ;
}
/ *
write the aggregate record
* /
function write _aggregate ( ) {
2007-01-24 15:23:42 +03:00
printf ( "dn: CN=Aggregate,${SCHEMADN}\n" ) ;
2005-11-01 10:07:48 +03:00
print ( " objectClass : top
objectClass : subSchema
2007-01-24 15:23:42 +03:00
objectCategory : CN = SubSchema , $ { SCHEMADN }
2005-11-01 10:07:48 +03:00
" ) ;
2007-01-24 15:46:26 +03:00
if ( dump _subschema _auto == undefined ) {
return ;
}
2005-11-01 10:07:48 +03:00
for ( i in objectclasses ) {
write _aggregate _objectclass ( objectclasses [ i ] ) ;
}
for ( i in attributes ) {
write _aggregate _attribute ( attributes [ i ] ) ;
}
for ( i in objectclasses ) {
write _aggregate _ditcontentrule ( objectclasses [ i ] ) ;
}
}
/ *
load a list from a file
* /
function load _list ( file ) {
var sys = sys _init ( ) ;
var s = sys . file _load ( file ) ;
var a = split ( "\n" , s ) ;
return a ;
}
/* get the rootDSE */
var res = ldb . search ( "" , "" , ldb . SCOPE _BASE ) ;
2007-02-15 00:55:29 +03:00
rootDse = res . msgs [ 0 ] ;
2005-11-01 10:07:48 +03:00
/* load the list of classes we are interested in */
var classes = load _list ( classfile ) ;
var i ;
for ( i = 0 ; i < classes . length ; i ++ ) {
var classname = classes [ i ] ;
var class = build _objectclass ( ldb , classname ) ;
if ( class != undefined ) {
objectclasses [ classname ] = class ;
}
}
/ *
expand the objectclass list as needed
* /
2006-08-21 17:04:14 +04:00
var num _classes = 0 ;
var expanded = 0 ;
/* calculate the actual number of classes */
2005-11-01 10:07:48 +03:00
for ( i in objectclasses ) {
2006-08-21 17:04:14 +04:00
num _classes ++ ;
}
/ * s o E J S d o n o t h a v e w h i l e n o r t h e b r e a k s t a t e m e n t
2007-01-24 15:23:42 +03:00
cannot find any other way than doing more loops
2006-08-21 17:04:14 +04:00
than necessary to recursively expand all classes
* /
var inf ;
for ( inf = 0 ; inf < 500 ; inf ++ ) {
if ( expanded < num _classes ) {
for ( i in objectclasses ) {
var n = objectclasses [ i ] ;
if ( objectclasses _expanded [ i ] != "DONE" ) {
expand _objectclass ( ldb , objectclasses [ i ] ) ;
objectclasses _expanded [ i ] = "DONE" ;
expanded ++ ;
}
}
/* recalculate the actual number of classes */
num _classes = 0 ;
for ( i in objectclasses ) {
num _classes ++ ;
}
}
2005-11-01 10:07:48 +03:00
}
/ *
find objectclass properties
* /
for ( i in objectclasses ) {
find _objectclass _properties ( ldb , objectclasses [ i ] ) ;
}
/ *
form the full list of attributes
* /
for ( i in objectclasses ) {
add _objectclass _attributes ( ldb , objectclasses [ i ] ) ;
}
/* and attribute properties */
for ( i in attributes ) {
find _attribute _properties ( ldb , attributes [ i ] ) ;
}
2006-08-26 19:38:01 +04:00
/ *
trim the 'may' attribute lists to those really needed
* /
for ( i in objectclasses ) {
trim _objectclass _attributes ( ldb , objectclasses [ i ] ) ;
}
2005-11-01 10:07:48 +03:00
/ *
dump an ldif form of the attributes and objectclasses
* /
2007-01-24 15:46:26 +03:00
if ( dump _attributes != undefined ) {
write _ldif ( attributes , attrib _attrs ) ;
}
if ( dump _classes != undefined ) {
write _ldif ( objectclasses , class _attrs ) ;
}
if ( dump _subschema != undefined ) {
write _aggregate ( ) ;
}
2005-11-01 10:07:48 +03:00
if ( verbose == undefined ) {
exit ( 0 ) ;
2005-10-14 11:38:16 +04:00
}
/ *
dump list of objectclasses
* /
printf ( "objectClasses:\n" )
for ( i in objectclasses ) {
printf ( "\t%s\n" , i ) ;
}
printf ( "attributes:\n" )
for ( i in attributes ) {
printf ( "\t%s\n" , i ) ;
}
2005-11-01 10:07:48 +03:00
printf ( "autocreated attributes:\n" ) ;
for ( i in attributes ) {
if ( attributes [ i ] . autocreate == true ) {
printf ( "\t%s\n" , i ) ;
}
}
2005-10-14 11:38:16 +04:00
return 0 ;