File: migrate_common.sh

package info (click to toggle)
migrationtools 48-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 364 kB
  • sloc: perl: 2,583; sh: 614; makefile: 15
file content (499 lines) | stat: -rw-r--r-- 12,653 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
#!/bin/sh
#
# $Id: migrate_common.sh,v 1.0 2020/07/01 11:40:12 lukeh Exp $
#
# Copyright (c) 1997-2003 Luke Howard.
# Copyright (c) 2020 Tanya.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#        This product includes software developed by Luke Howard.
# 4. The name of the other may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE LUKE HOWARD ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL LUKE HOWARD BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# Migrate all entities from flat files. 
#
# Make sure that you configure migrate_common.ph to suit
# your site's X.500 naming context and DNS mail domain;
# the defaults may not be correct.
#
# Luke Howard <lukeh@padl.com> April 1997
# Tanya <tanyadegurechaff@waifu.club> July 2020
#

# Defaults
[ -f "/etc/os-release" ] && . /etc/os-release
[ -z "$dirname" ] && dirname=$(dirname "$0")
[ -z "$MIGRATION_TYPE" ] && MIGRATION_TYPE='full'

perlset () {
	# saves having to change #! path in each script
	if [ "X$PERL" = "X" ]; then
		if [ -x /usr/local/bin/perl ]; then
			PERL="/usr/local/bin/perl"
		elif [ -x /usr/bin/perl ]; then
			PERL="/usr/bin/perl"
		else
			echo "Can't find Perl!"
			exit 1
		fi
	fi
}

perlexec () {
	spath=$1
	shift
	if [ -f "$dirname/$spath" ]; then
		$PERL "$dirname/$spath" $@
	elif [ -f "$spath" ]; then
		$PERL "$spath" $@
	else
		ppath=$(which "$spath")
		[ "x$ppath" != 'x' ] && $PERL "$ppath" $@
	fi
	return $?
}

of_getopts () {
	# Usage
	usage="Usage: $(basename "$_") [options]"
	usage=$usage'\n  -s\tExclude suffix'
	usage=$usage'\n  -m\tMinimal import'
	while getopts ':hsm' arg; do
		case $arg in
			h)
			echo "$usage"
			exit 0
			;;
			s)
			INCLUDE_SUFFIX='false'
			;;
			m)
			MIGRATION_TYPE='min'
			;;
			*)
			echo 'Not recognized option' >&2
			echo "$usage"
			exit 1
		esac
	done
}

on_getopts () {
	# Usage
	usage="Usage: $(basename "$_") [options]"
	usage=$usage'\n  -s\tInclude suffix'
	usage=$usage'\n  -a\tAuthentication'
	usage=$usage'\n  -m\tMinimal import'
	while getopts ':hsa:m' arg; do
		case $arg in
			h)
			echo "$usage"
			exit 0
			;;
			s)
			INCLUDE_SUFFIX='true'
			;;
			a)
			SASL_MECH=${OPTARG}
			;;
			m)
			MIGRATION_TYPE='min'
			;;
			*)
			echo 'Not recognized option' >&2
			echo "$usage"
			exit 1
		esac
	done
}

readldapconf () {
	if [ -f "$1" ]; then
		while IFS= read -r line; do
			if printf %s "$line" | grep -E -q '^[A-Z\_]+[ ].*$' 2>/dev/null; then 
				llkey=$(echo "$line" | awk '{print $1}')
				case $llkey in
					BASE)
					[ -z "$LDAP_BASEDN" ] && LDAP_BASEDN=$(echo "$line" | awk '{print $2}')
					;;
					URI)
					[ -z "$LDAPHOST" ] && LDAPHOST=$(echo "$line" | awk '{print $2}')
					;;
					SASL_MECH)
					[ -z "$SASL_MECH" ] && SASL_MECH=$(echo "$line" | awk '{print $2}')
					;;
				esac
            fi
		done < "$1"
	fi
}

dbgen () {
	DB="$(mktemp -t nis.ldif.XXXXXXXXXX)" || {
		echo "Can't create temporary file" >&2
		exit 1
	}
}

setvars_min () {
	if [ "X$ETC_GROUP" = "X" ]; then
		ETC_GROUP=/etc/group
	fi
	if [ "X$ETC_PASSWD" = "X" ]; then
		ETC_PASSWD=/etc/passwd
	fi
}

setvars_full () {
	if [ "X$ETC_ALIASES" = "X" ]; then
		ETC_ALIASES=/etc/aliases
	fi
	if [ "X$ETC_FSTAB" = "X" ]; then
		ETC_FSTAB=/etc/fstab
	fi
	if [ "X$ETC_HOSTS" = "X" ]; then
		ETC_HOSTS=/etc/hosts
	fi
	if [ "X$ETC_NETWORKS" = "X" ]; then
		ETC_NETWORKS=/etc/networks
	fi
	setvars_min
	if [ "X$ETC_SERVICES" = "X" ]; then
		ETC_SERVICES=/etc/services
	fi
	if [ "X$ETC_PROTOCOLS" = "X" ]; then
		ETC_PROTOCOLS=/etc/protocols
	fi
	if [ "X$ETC_RPC" = "X" ]; then
		ETC_RPC=/etc/rpc
	fi
	if [ "X$ETC_NETGROUP" = "X" ]; then
		ETC_NETGROUP=/etc/netgroup
	fi
}

of_setexecs () {
	if [ "X$LDIF2LDBM" = "X" ]; then
		if [ -x /usr/local/etc/ldif2ldbm ]; then
			LDIF2LDBM="/usr/local/etc/ldif2ldbm"
		elif [ -x /usr/local/sbin/ldif2ldbm ]; then
			LDIF2LDBM="/usr/local/sbin/ldif2ldbm"
		elif [ -x /usr/sbin/ldif2ldbm ]; then
			LDIF2LDBM="/usr/sbin/ldif2ldbm"
		elif [ -x "$NSHOME/bin/slapd/server/ns-slapd" ]; then
			LDIF2LDBM="$NSHOME/bin/slapd/server/ns-slapd ldif2db -f $NSHOME/slapd-$serverID"
		elif [ -x /usr/iplanet/servers/bin/slapd/server/dsimport ]; then
			LDIF2LDBM="/usr/iplanet/servers/bin/slapd/server/dsimport"
		fi
	fi
	if [ "X$SLAPADD" = "X" ]; then
		if [ -x /usr/local/sbin/slapadd ]; then
			SLAPADD="/usr/local/sbin/slapadd"
		elif [ -x /usr/sbin/slapadd ]; then
			SLAPADD="/usr/sbin/slapadd"
		fi
	fi
	if [ "X$LDIF2LDBM" = "X" ] && [ "X$SLAPADD" = "X" ]; then
		echo "Can't find ldif2ldbm or slapadd!"
		exit 2
	fi
}

on_setexecs () {
	if [ "X$LDAPADD" = "X" ]; then
		if [ -x ldapadd ]; then
			LDAPADD="ldapadd -c"
		elif [ -x /usr/local/bin/ldapadd ]; then
			LDAPADD="/usr/local/bin/ldapadd -c"
		elif [ -x /usr/bin/ldapadd ]; then
			LDAPADD="/usr/bin/ldapadd -c"
		elif [ -x "$NSHOME/bin/slapd/server/ldapmodify" ]; then
			LDAPADD="$NSHOME/bin/slapd/server/ldapmodify -a -c"
		elif [ -x /usr/iplanet/servers/shared/bin/ldapmodify ]; then
			LDAPADD="/usr/iplanet/servers/shared/bin/ldapmodify -a -c"
		fi
	fi

	if [ "X$LDAPADD" = "X" ]; then
		echo "Please set the LDAPADD environment variable to point to ldapadd."
		echo
		exit 1
	fi
}

on_questions () {
	if [ "X$LDAP_BASEDN" = "X" ]; then
		question="Enter the X.500 naming context you wish to import into: [$defaultcontext]"
		echo "$question " | tr -d '\012' > /dev/tty
		read LDAP_BASEDN
		if [ "X$LDAP_BASEDN" = "X" ]; then
			if [ "X$defaultcontext" = "X" ]; then
				echo "You must specify a default context."
				exit 2
			else
				LDAP_BASEDN=$defaultcontext
			fi
		fi
	fi
	export LDAP_BASEDN

	if [ "X$LDAPHOST" = "X" ]; then
		question="Enter the hostname or URI of your LDAP server [ldap://localhost]:"
		echo "$question " | tr -d '\012' > /dev/tty
		read LDAPHOST
	fi

	if [ "X$LDAPHOST" = "X" ]; then
		LDAPHOST="ldap://localhost"
		ldap_uri=1
	elif printf %s "$LDAPHOST" | grep -E -q '^[a-z]+://.*$' 2>/dev/null; then 
		ldap_uri=1
	else
		ldap_uri=0
	fi

	if [ "X$LDAP_BINDDN" = "X" ] && [ "X$SASL_MECH" != 'XEXTERNAL' ]; then
		defdn="cn=manager,$LDAP_BASEDN"
		[ "x$ID_LIKE" = "xdebian" ] && defdn="cn=admin,$LDAP_BASEDN"
		question="Enter the manager DN: [$defdn]:"
		echo "$question " | tr -d '\012' > /dev/tty
		read LDAP_BINDDN
		if [ "X$LDAP_BINDDN" = "X" ]; then
			LDAP_BINDDN="$defdn"
		fi
	fi
	export LDAP_BINDDN

	if [ "X$LDAP_BINDCRED" = "X" ] && [ "X$SASL_MECH" != 'XEXTERNAL' ]; then
		question="Enter the credentials to bind with:"
		echo "$question " | tr -d '\012' > /dev/tty
		stty -echo
		read LDAP_BINDCRED
		stty echo
		echo
	fi

	if [ "X$LDAP_PROFILE" = "X" ]; then
		question="Do you wish to generate a DUAConfigProfile [yes|no]?"
		echo "$question " | tr -d '\012' > /dev/tty
		read LDAP_PROFILE
		if [ "X$LDAP_PROFILE" = "X" ]; then
			LDAP_PROFILE="no"
		fi
	fi
}

all_mig_min () {
	echo "Migrating groups..."
	perlexec migrate_group.pl		$ETC_GROUP >> $DB
	echo "Migrating users..."
	perlexec migrate_passwd.pl		$ETC_PASSWD >> $DB
}

all_mig_full () {
	# Don't migrate aliases if it's specified to not do so
	if [ "X$MIGRATE_ALIASES" != 'Xfalse' ]; then
		echo "Migrating aliases..."
		perlexec migrate_aliases.pl 	$ETC_ALIASES >> $DB
	fi
	# Migrate fstab only if specifically asked
	if [ "X$MIGRATE_FSTAB" = 'Xtrue' ]; then
		echo "Migrating fstab..."
		perlexec migrate_fstab.pl		$ETC_FSTAB >> $DB
	fi
	echo "Migrating hosts..."
	perlexec migrate_hosts.pl		$ETC_HOSTS >> $DB
	echo "Migrating networks..."
	perlexec migrate_networks.pl	$ETC_NETWORKS >> $DB
	all_mig_min
	echo "Migrating protocols..."
	perlexec migrate_protocols.pl	$ETC_PROTOCOLS >> $DB
	echo "Migrating rpcs..."
	perlexec migrate_rpc.pl		$ETC_RPC >> $DB
	echo "Migrating services..."
	perlexec migrate_services.pl	$ETC_SERVICES >> $DB
	echo "Migrating netgroups..."
	perlexec migrate_netgroup.pl	$ETC_NETGROUP >> $DB
	echo "Importing into LDAP..."
	echo "Migrating netgroups (by user)..."
	perlexec migrate_netgroup_byuser.pl	$ETC_NETGROUP >> $DB
	echo "Migrating netgroups (by host)..."
	perlexec migrate_netgroup_byhost.pl	$ETC_NETGROUP >> $DB
}

of_all_mig () {
	echo "Creating naming context entries..."
	[ -z "$INCLUDE_SUFFIX" ] && INCLUDE_SUFFIX=true
	if [ "x$INCLUDE_SUFFIX" = 'xfalse' ]; then
		perlexec migrate_base.pl -n		> $DB
	else
		perlexec migrate_base.pl		> $DB
	fi
	[ "$MIGRATION_TYPE" = 'min' ] && all_mig_min || all_mig_full
	echo "Preparing LDAP database..."
}

on_all_mig () {
	echo
	echo "Importing into $LDAP_BASEDN..."
	echo
	echo "Creating naming context entries..."
	[ -z "$INCLUDE_SUFFIX" ] && INCLUDE_SUFFIX=false
	if [ "x$INCLUDE_SUFFIX" = 'xtrue' ]; then
		perlexec migrate_base.pl		> $DB
	else
		perlexec migrate_base.pl -n		> $DB
	fi
	[ "$MIGRATION_TYPE" = 'min' ] && all_mig_min || all_mig_full
	echo "Importing into LDAP..."
}

of_update () {
	if [ "X$SLAPADD" = "X" ]; then
		$LDIF2LDBM -i $DB
	else
		$SLAPADD -l $DB
	fi
	EXITCODE=$?

	if [ $EXITCODE -ne 0 ]; then
		echo "Migration failed: saving failed LDIF to $DB"
	else
		rm -f $DB
	fi

	if [ "X$EXIT" != "Xno" ]; then
		exit $EXITCODE
	fi

	echo "Done."
}

on_update () {
	case $LDAPADD in
		*'ldapadd'*)
		[ $ldap_uri = 1 ] && ldaphostcmd="-H $LDAPHOST" || ldaphostcmd="-h $LDAPHOST"
		ldapcmd="$LDAPADD $ldaphostcmd"
		if [ "x$SASL_MECH" != 'x' ]; then
			ldapendcmd="-Y $SASL_MECH -f $DB"
		else
			ldapendcmd="-f $DB"
		fi
		if [ "x$SASL_MECH" != 'xEXTERNAL' ] && [ "x$LDAP_BINDCRED" = 'x' ]; then
			$ldapcmd -D "$LDAP_BINDDN" $ldapendcmd
		elif [ "x$SASL_MECH" != 'xEXTERNAL' ]; then
			$ldapcmd -D "$LDAP_BINDDN" -w "$LDAP_BINDCRED" $ldapendcmd
		else
			$ldapcmd $ldapendcmd
		fi
		;;
		*)
		false
		;;
	esac

	if [ $? -ne 0 ]; then
		echo "$LDAPADD: returned non-zero exit status: saving failed LDIF to $DB"
		e=$?
	else
		echo "$LDAPADD: succeeded"
		e=$?
		rm -f $DB
	fi

	if [ "X$EXIT" != "Xno" ]; then
		exit $e
	fi
}

tmpfd_gen () {
	TEMP_DIR="$(mktemp -dt)" || {
		echo "Can't create temporary directory" >&2
		exit 1
	}
	ETC_PASSWD="$TEMP_DIR/passwd.ldap"
	ETC_GROUP="$TEMP_DIR/group.ldap"
	if [ "$MIGRATION_TYPE" != 'min' ]; then
		ETC_SERVICES="$TEMP_DIR/services.ldap"
		ETC_PROTOCOLS="$TEMP_DIR/protocols.ldap"
		[ ! -z "$(echo "$@" | grep 'fstab')" ] && ETC_FSTAB="$TEMP_DIR/fstab.ldap"
		ETC_RPC="$TEMP_DIR/rpc.ldap"
		ETC_HOSTS="$TEMP_DIR/hosts.ldap"
		ETC_NETWORKS="$TEMP_DIR/networks.ldap"
		[ ! -z "$(echo "$@" | grep 'netgroup')" ] && ETC_NETGROUP="$TEMP_DIR/netgroup.ldap"
		ETC_ALIASES="$TEMP_DIR/aliases.ldap"
	fi
	EXIT=no
}

tmpfd_destroy () {
	rm -f $ETC_PASSWD
	rm -f $ETC_GROUP
	if [ "$MIGRATION_TYPE" != 'min' ]; then
		rm -f $ETC_SERVICES
		rm -f $ETC_PROTOCOLS
		[ ! -z "$(echo "$@" | grep 'fstab')" ] && rm -f $ETC_FSTAB
		rm -f $ETC_RPC
		rm -f $ETC_HOSTS
		rm -f $ETC_NETWORKS
		[ ! -z "$(echo "$@" | grep 'netgroup')" ] && rm -f $ETC_NETGROUP
		rm -f $ETC_ALIASES
	fi
	rm -d $TEMP_DIR
}

common_main () {
	if [ ! -z "$LDAP_EXTENDED_SCHEMA" ] && command -v net >/dev/null; then
		SAMBA_DOMAIN_SID=$(net getlocalsid)
		export SAMBA_DOMAIN_SID=${SAMBA_DOMAIN_SID#*: }
	fi
	# Generate LDIF temporary file
	dbgen
	# Set files positions
	[ "$MIGRATION_TYPE" = 'min' ] && setvars_min || setvars_full
}

of_main () {
	common_main
	# Set executables positions
	of_setexecs
	# Migrate data
	of_all_mig
	# Bump data
	of_update
}

on_main () {
	common_main
	# Set executables positions
	on_setexecs
	# Ask questions for online push
	on_questions
	# Migrate data
	on_all_mig
	# Bump data
	on_update
}