Current File : //sbin/nsdb-convert
#!/bin/ksh

#
# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
#

function convert_ldif
{
	#
	# The meat of the script.
	#
	# Read each line of LDIF output from a FedFS draft-11 NSDB
	# and convert it to a draft-15 format.  We need to:
	#
	# - convert NCE entries from fedfsNcePrefix to fedfsNceDN
	# - convert # fedfsFslHost/fedfsNfsPath to fedfsNfsURI
	# - convert # fedfsFslHost/fedfsSmbPath to fedfsSmbURI
	# - delete fedfsNsdb{Name,Port}, fedfsNfs{Major,Minor}Ver
	#
	# We also need to deal with slapcat's continuation lines.
	#
	is_fsl=false
	while read line
	do
		# An empty line separates different entries, and is a reset
		if [ "$line" == "" ]; then
			dn=""
			host=""
			path=""
			share=""
			echo ""
			continue
		fi

		# LDIF continues long lines with a space, which FSL DNs trip
		if [ "$is_fsl" == "true" ]; then
			echo " $line"
			is_fsl=false
			continue
		fi

		# Get lower-case key and value
		key=`echo $line | sed -e 's/:.*//' | tr '[A-Z]' '[a-z]'`
		value=`echo $line | sed -e 's/.*://' -e 's/.* //'`

		# These just go away completely
		if [ "$key" == "fedfsnsdbname" -o \
		    "$key" == "fedfsnsdbport" -o \
		    "$key" == "fedfsnfsmajorver" -o \
		    "$key" == "fedfsnfsminorver" -o \
		    "$key" == "fedfsfslttl" ]; then
			continue;
		fi

		# Save DN and see if it's an FSL for continuation above
		if [ "$key" == "dn" ]; then
			dn=$value
			type=`echo $value | grep fedfsFslUuid`
			if [ ! -z "$type" ]; then
				is_fsl=true;
			fi
		fi

		# Convert fedfsNcePrefix to a full fedfsNceDN
		if [ "$key" == "fedfsnceprefix" ]; then
			if [ -z "$value" ]; then
				echo "fedfsNceDN: $dn"
			else
				echo "fedfsNceDN: $value,$dn"
			fi
			continue
		fi

		# Add a default TTL to FSN
		if [ "$key" == "structuralobjectclass" -a \
		    "$value" == "fedfsFsn" ]; then
			echo "fedfsFsnTTL: 300"
		fi

		# Convert host+path to NFS URI, host+share to SMB URI
		if [ "$key" == "fedfsfslhost" ]; then
			host=$value
			continue
		fi

		if [ "$key" == "fedfsnfspath" ]; then
			echo $value | $base64 -d > /tmp/xdr$$
			path=`$xdr2path /tmp/xdr$$`
			rm /tmp/xdr$$
			continue
		fi

		if [ "$key" == "fedfssmbshare" ]; then
			share=$value
			continue
		fi

		if [ "$host" != "" -a "$path" != "" ]; then
			echo "fedfsNfsURI: nfs://$host/$path"
			host=
			path=
		fi

		if [ "$host" != "" -a "$share" != "" ]; then
			echo "fedfsSmbURI: smb://$host//$share"
			host=
			share=
		fi

		# Most other lines we just pass through
		echo "$line"

	done
}

#
# Get the config file
#
conf=/etc/openldap/slapd.conf

if [ "$1" == "-f" ]; then
	shift
	conf=$1
	shift
fi

if [ ! -f $conf ]; then
	echo "Invalid path to slapd.conf file $conf"
	exit 1;
fi

# Verify that old and new schema are present
spath=/usr/lib/fs/nfs
schema1=`grep fedfs-11 $conf | awk - '{print $2}'`
schema2=`echo $schema1 | sed -e 's/fedfs-11/fedfs-15/'`
schema3=`echo $schema1 | sed -e 's/fedfs-11/smb-15/'`
sdir=`dirname $schema1`

if [ ! -f $schema1 ]; then
	echo "Invalid path to schema $schema1 in $conf"
	exit 1;
fi

if [ ! -f $schema2 ]; then
	cp $spath/`basename $schema2` $sdir
	if  [ ! -f $schema2 ]; then
		echo "Invalid path to expected schema $schema2"
		exit 1;
	fi
fi

if [ ! -f $schema3 ]; then
	cp $spath/`basename $schema3` $sdir
	if  [ ! -f $schema3 ]; then
		echo "Invalid path to expected schema $schema3"
		exit 1;
	fi
fi

#
# Verify a couple of useful binaries that aren't everywhere
#
base64=`which base64 2>/dev/null`
if [ "$?" == "1" ]; then
	base64=`which akbase64 2>/dev/null`
	if [ "$?" == "1" ]; then
		echo 'Need base64 in $PATH'
		exit 1
	fi
fi

xdr2path=`which xdr2path 2>/dev/null`
if [ "$?" == "1" ]; then
	echo 'Need xdr2path in $PATH'
	exit 1
fi

#
# Get a backup directory
#
backup=/tmp/nsdb_preconversion
rm -rf $backup
mkdir $backup
echo "Backup directory with original LDAP data in $backup"

#
# Extract and convert LDIF
#
slapcat -f $conf > $backup/nsdb.old 2> /dev/null
if [ "$?" != "0" ]; then
	echo "Extraction failed."
	exit 1
fi
cat $backup/nsdb.old | convert_ldif > $backup/nsdb.new
if [ "$?" != "0" ]; then
	echo "Conversion failed."
	exit 1
fi

#
# Edit config file for new schema
#
cp -p $conf $backup
rm -f $conf
touch $conf
cat $backup/`basename $conf` | while read line
do
	if [ -z "`echo $line | grep fedfs-11`" ]; then
		echo "$line" >> $conf
	else
		echo "`echo $line | sed -e 's/fedfs-11/fedfs-15/'`" >> $conf
		echo "`echo $line | sed -e 's/fedfs-11/smb-15/'`" >> $conf
	fi
done

#
# Backup and clear LDAP data
#
dbdir=`grep ^directory $conf | awk - '{print $2}'`
mv $dbdir/__db.00* $dbdir/*.bdb $dbdir/log.* $dbdir/alock $backup

#
# Import converted data
#
/bin/su openldap -c "slapadd -f $conf -c -l $backup/nsdb.new" \
    > /tmp/slapadd.out 2>&1
if [ "$?" != "0" ]; then
	echo "Reinsertion failed, errors follow."
	cat /tmp/slapadd.out
	exit 1
fi

echo "Conversion complete."