summaryrefslogtreecommitdiff
path: root/bin/ldap2passwd
blob: 0e325b31d1355070c8cbe8656bd4f7f27b839a11 (plain)
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
#!/usr/bin/ruby

#
# Copyright (c) 2004 Peter Palfrader <peter@palfrader.org>
#
# All rights reserved.
#

require "ldap"
require "yaml"

@config = YAML::load( File.open( '/etc/noreply/config' ) )

VALIDATION_REGEX = {
	'uid' => /^[Wa-z.-]+$/,
	'cn' => /^[Wa-z-]+$/,
	'uidNumber' => /^[1-9][0-9]+$/,
	'gidNumber' => /^[1-9][0-9]+$/,
	'gecos' => /^[a-zA-Z0-9,. -]+$/,
	'homeDirectory' => /^\/[a-zA-Z0-9.\/-]+$/,
	'loginShell' => /^\/[a-zA-Z0-9\/-]+$/
}


5.times{
	begin
		@conn = LDAP::Conn.new(@config['ldapserver'], @config['ldapport'] )
		break if @conn
	rescue LDAP::ResultError
		sleep 3
	end
};
unless @conn.bind(@config['credentials']['ldap2passwd']['binddn'],
                  @config['credentials']['ldap2passwd']['bindpw'])
	throw @conn.perror("bind")
end

def passwd_line(entry)
	l = {}
	%w(uid uidNumber gidNumber gecos homeDirectory loginShell).each{ |key|
		next if ['gecos', 'loginShell'].include?(key) and not entry[key]
		throw "key #{key} missing in #{entry['dn']}" unless entry[key]
		throw "no validation regex for #{key}" unless VALIDATION_REGEX[key]

		l[key] = entry[key].to_s
		throw "value for #{key} (#{l[key]}) in #{entry['dn']} fails validation regex #{VALIDATION_REGEX[key]}" unless l[key] =~ VALIDATION_REGEX[key]
	};
	l['gecos'] = '' unless l['gecos']
	l['loginShell'] = '/bin/false' unless l['loginShell']
	sprintf "%s:x:%s:%s:%s:%s:%s\n", l['uid'], l['uidNumber'], l['gidNumber'], l['gecos'], l['homeDirectory'], l['loginShell']
end
def group_line(entry)
	l = {}
	%w(cn gidNumber).each{ |key|
		throw "key #{key} missing in #{entry['dn']}" unless entry[key]
		throw "no validation regex for #{key}" unless VALIDATION_REGEX[key]

		l[key] = entry[key].to_s
		throw "value for #{key} (#{l[key]}) in #{entry['dn']} fails validation regex #{VALIDATION_REGEX[key]}" unless l[key] =~ VALIDATION_REGEX[key]
	};
	members = []
	if entry['memberUid']
		entry['memberUid'].each{ |member|
			throw "empty member value in group #{entry['dn']}" unless member
			m = member.to_s
			throw "member of group #{entry['dn']} fails UID validiation test" unless m =~ VALIDATION_REGEX['uid']
			members << m
		}
	end
	sprintf "%s:x:%s:%s\n", l['cn'], l['gidNumber'], members.join(',')
end


passwd_lines = []
passwd = @conn.search2(@config['basedn'], LDAP::LDAP_SCOPE_SUBTREE, '(objectClass=posixAccount)')
passwd.each{ |line|
	passwd_lines << passwd_line(line)
}

group_lines = []
group = @conn.search2(@config['basedn'], LDAP::LDAP_SCOPE_SUBTREE, '(objectClass=posixGroup)')
group.each{ |line|
	group_lines << group_line(line)
}

unless File.exists?('passwd') && (File.read('passwd') == passwd_lines.join())
	f = File.new('passwd', 'w')
	f.print passwd_lines.join
end

unless File.exists?('group') && (File.read('group') == group_lines.join())
	f = File.new('group', 'w')
	f.print group_lines.join
end