diff --git a/user/Makefile b/user/Makefile new file mode 100644 index 0000000..812e137 --- /dev/null +++ b/user/Makefile @@ -0,0 +1,14 @@ + +all: cron + +cron: manifests/classes.pp manifests/virtual.pp + +manifests/virtual.pp: + @echo "Creating virtual.pp ..." + ruby scripts/update-virtual.rb > $@ + +manifests/classes.pp: manifests/virtual.pp + @echo "Creating classes.pp ..." + ruby scripts/update-classes.rb > $@ + +.PHONY: manifests/virtual.pp diff --git a/user/scripts/update-classes.rb b/user/scripts/update-classes.rb new file mode 100755 index 0000000..915c600 --- /dev/null +++ b/user/scripts/update-classes.rb @@ -0,0 +1,99 @@ + +require 'ldap' +require 'uri' + +basedn = '' +conn = '' + +f = File.new('/etc/openldap/ldap.conf', 'r') +f.readlines.each do |line| + line = line.strip + next if line =~ /^#/ + next if line == '' + line = line.split + if line[0] == 'BASE' + basedn = line[1] + elsif line[0] == 'URI' + line.shift + line.each do |uri| + uri = URI.parse(uri) + begin + if uri.scheme == 'ldaps' + if ! uri.port + uri.port = 636 + end + conn = LDAP::SSLConn.new(uri.host, uri.port) + else + if ! uri.port + uri.port = 389 + end + conn = LDAP::Conn.new(uri.host, uri.port) + end + conn.bind + break + rescue LDAP::ResultError + next + end + end + end +end +f.close + + +userlist = {} +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, 'objectClass=posixAccount', + ['uid', 'gidNumber']) { |entry| + groups = [] + filter = '(&(objectClass=posixGroup)(|(uniqueMember=' + entry.get_dn + \ + ')(memberUid=' + entry['uid'][0] + ')))' + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) { |group| + groups << group['cn'][0] + } + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, \ + '(&(objectClass=posixGroup)(gidNumber=' + \ + entry['gidNumber'][0] + '))', \ + ['cn']) { |group| + groups << group['cn'][0] + } + + # create user class + if entry['uid'][0] !~ /.*\$.*/ + print "class user::" + entry['uid'][0] + " {\n" + print " include user::virtual\n" + print " realize(User['" + entry['uid'][0] + "'])\n" + groups.each do |group| + print " realize(Group['" + group + "'])\n" + end + print "}\n\n" + end + + userlist[entry.get_dn()] = entry['uid'][0] +} + + +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, 'objectClass=posixGroup', + ['cn', 'gidNumber', 'memberUid', 'uniqueMember']) { |entry| + + members = [] + if entry.attrs.index('memberUid') + entry['memberUid'].each do |member| + if userlist.has_value?(member) + members << member + end + end + end + if entry.attrs.index('uniqueMember') + entry['uniqueMember'].each do |member| + if userlist.has_key?(member) + members << userlist[member] + end + end + end + if members.length > 0 + print "class user::group::" + entry['cn'][0] + " {\n" + members.each do |member| + print " include user::" + member + "\n" + end + print "}\n\n" + end +} diff --git a/user/scripts/update-virtual.rb b/user/scripts/update-virtual.rb new file mode 100755 index 0000000..9a73745 --- /dev/null +++ b/user/scripts/update-virtual.rb @@ -0,0 +1,108 @@ + +require 'ldap' +require 'uri' + +basedn = '' +conn = '' + +f = File.new('/etc/openldap/ldap.conf', 'r') +f.readlines.each do |line| + line = line.strip + next if line =~ /^#/ + next if line == '' + line = line.split + if line[0] == 'BASE' + basedn = line[1] + elsif line[0] == 'URI' + line.shift + line.each do |uri| + uri = URI.parse(uri) + begin + if uri.scheme == 'ldaps' + if ! uri.port + uri.port = 636 + end + conn = LDAP::SSLConn.new(uri.host, uri.port) + else + if ! uri.port + uri.port = 389 + end + conn = LDAP::Conn.new(uri.host, uri.port) + end + conn.bind + break + rescue LDAP::ResultError + next + end + end + end +end +f.close + + +print "class user::virtual {\n" + + +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, 'objectClass=posixAccount', + ['uid', 'uidNumber', 'gidNumber', 'gecos', 'homeDirectory', + 'loginShell' ]) { |entry| + groups = [] + filter = '(&(objectClass=posixGroup)(|(uniqueMember=' + entry.get_dn \ + + ')(memberUid=' + entry['uid'][0] + ')))' + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) { |group| + groups << group['cn'][0] + } + prigroup = nil + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, \ + '(&(objectClass=posixGroup)(gidNumber=' + entry['gidNumber'][0] + '))', \ + ['cn']) { |group| + prigroup = group['cn'][0] + } + + print "\n" + print " @user { '" + entry['uid'][0] + "':\n" + print " ensure => present,\n" + print " uid => '" + entry['uidNumber'][0] + "',\n" + print " gid => '" + entry['gidNumber'][0] + "',\n" + begin + print " comment => '" + entry['gecos'][0] + "',\n" + rescue + print " comment => '" + entry['uid'][0] + "',\n" + end + print " home => '" + entry['homeDirectory'][0] + "',\n" + begin + print " shell => '" + entry['loginShell'][0] + "',\n" + rescue + print " shell => '/bin/false',\n" + end + if groups.length > 0 + print " groups => [ " + groups.each do |group| + print "'" + group + "', " + end + print "],\n" + end + print " require => [ Group['" + prigroup + "']," + groups.each do |group| + print "\n Group['" + group + "']," + end + print " ],\n" + print " }\n" + +} + + +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, 'objectClass=posixGroup', + ['cn', 'gidNumber', 'memberUid', 'uniqueMember']) { |entry| + + # generate virtual group entry + print "\n" + print " @group { '" + entry['cn'][0] + "':\n" + print " ensure => present,\n" + print " gid => '" + entry['gidNumber'][0] + "',\n" + print " }\n" + +} + + +print "\n}\n"