2009-09-02 12:20:50 +04:00
# Create DisplaySpecifiers LDIF (as a string) from the documents provided by
# Microsoft under the WSPP.
#
# Copyright (C) Andrew Kroeger <andrew@id10ts.net> 2009
#
# Based on ms_schema.py
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
2018-07-30 09:20:39 +03:00
2009-09-02 12:20:50 +04:00
def __read_folded_line ( f , buffer ) :
""" Read a line from an LDIF file, unfolding it """
line = buffer
while True :
l = f . readline ( )
if l [ : 1 ] == " " :
# continued line
# cannot fold an empty line
assert ( line != " " and line != " \n " )
# preserves '\n '
line = line + l
else :
# non-continued line
if line == " " :
line = l
if l == " " :
# eof, definitely won't be folded
break
else :
# marks end of a folded line
# line contains the now unfolded line
# buffer contains the start of the next possibly folded line
buffer = l
break
return ( line , buffer )
2018-07-30 09:21:29 +03:00
2009-09-02 12:20:50 +04:00
# Only compile regexp once.
# Will not match options after the attribute type.
attr_type_re = re . compile ( " ^([A-Za-z][A-Za-z0-9-]*): " )
2018-07-30 09:20:39 +03:00
2009-09-02 12:20:50 +04:00
def __read_raw_entries ( f ) :
""" Read an LDIF entry, only unfolding lines """
buffer = " "
while True :
entry = [ ]
while True :
( l , buffer ) = __read_folded_line ( f , buffer )
if l [ : 1 ] == " # " :
continue
if l == " \n " or l == " " :
break
m = attr_type_re . match ( l )
if m :
if l [ - 1 : ] == " \n " :
l = l [ : - 1 ]
entry . append ( l )
else :
2018-03-09 16:53:45 +03:00
print ( " Invalid line: %s " % l , end = ' ' , file = sys . stderr )
2009-09-02 12:20:50 +04:00
sys . exit ( 1 )
if len ( entry ) :
yield entry
if l == " " :
break
2018-07-30 09:20:39 +03:00
2009-09-02 12:20:50 +04:00
def fix_dn ( dn ) :
""" Fix a string DN to use $ {CONFIGDN} """
if dn . find ( " <Configuration NC Distinguished Name> " ) != - 1 :
dn = dn . replace ( " \n " , " " )
return dn . replace ( " <Configuration NC Distinguished Name> " , " $ {CONFIGDN} " )
else :
return dn
2018-07-30 09:20:39 +03:00
2009-09-02 12:20:50 +04:00
def __write_ldif_one ( entry ) :
""" Write out entry as LDIF """
out = [ ]
for l in entry :
if l [ 2 ] == 0 :
out . append ( " %s : %s " % ( l [ 0 ] , l [ 1 ] ) )
else :
# This is a base64-encoded value
out . append ( " %s :: %s " % ( l [ 0 ] , l [ 1 ] ) )
return " \n " . join ( out )
2018-07-30 09:20:39 +03:00
2009-09-02 12:20:50 +04:00
def __transform_entry ( entry ) :
""" Perform required transformations to the Microsoft-provided LDIF """
temp_entry = [ ]
for l in entry :
t = [ ]
if l . find ( " :: " ) != - 1 :
# This is a base64-encoded value
t = l . split ( " :: " , 1 )
t . append ( 1 )
else :
t = l . split ( " : " , 1 )
t . append ( 0 )
key = t [ 0 ] . lower ( )
if key == " changetype " :
continue
if key == " distinguishedname " :
continue
if key == " instancetype " :
continue
if key == " name " :
continue
if key == " cn " :
continue
if key == " objectcategory " :
continue
if key == " showinadvancedviewonly " :
value = t [ 1 ] . upper ( ) . lstrip ( ) . rstrip ( )
if value == " TRUE " :
# Remove showInAdvancedViewOnly attribute if it is set to the
# default value of TRUE
continue
t [ 1 ] = fix_dn ( t [ 1 ] )
temp_entry . append ( t )
entry = temp_entry
return entry
2018-07-30 09:20:39 +03:00
2009-09-02 12:20:50 +04:00
def read_ms_ldif ( filename ) :
""" Read and transform Microsoft-provided LDIF file. """
out = [ ]
2018-08-08 18:52:35 +03:00
from io import open
2023-02-21 01:42:27 +03:00
with open ( filename , " r " , encoding = ' latin-1 ' ) as f :
for entry in __read_raw_entries ( f ) :
out . append ( __write_ldif_one ( __transform_entry ( entry ) ) )
2009-09-02 12:20:50 +04:00
return " \n \n " . join ( out ) + " \n \n "
2018-07-30 09:21:29 +03:00
2009-09-02 12:20:50 +04:00
if __name__ == ' __main__ ' :
import sys
try :
display_specifiers_file = sys . argv [ 1 ]
except IndexError :
2018-03-09 16:53:45 +03:00
print ( " Usage: %s display-specifiers-ldif-file.txt " % ( sys . argv [ 0 ] ) , file = sys . stderr )
2009-09-02 12:20:50 +04:00
sys . exit ( 1 )
2018-03-09 16:53:45 +03:00
print ( read_ms_ldif ( display_specifiers_file ) )