From 0b73e7782c7c0f21499294349a5c56ff193fb018 Mon Sep 17 00:00:00 2001 From: Ossi Salmi Date: Sat, 3 Aug 2013 03:41:20 +0300 Subject: [PATCH 1/3] user: LDAP user management refactoring --- user/manifests/init.pp | 45 ++++------- user/scripts/update-classes.rb | 124 +++++++++++++---------------- user/scripts/update-virtual.rb | 137 ++++++++++++++++++--------------- 3 files changed, 144 insertions(+), 162 deletions(-) diff --git a/user/manifests/init.pp b/user/manifests/init.pp index f3ad30c..81d3605 100644 --- a/user/manifests/init.pp +++ b/user/manifests/init.pp @@ -355,37 +355,26 @@ class user::system { # Add local user account. # -define user::newuser($uid, $gid, $comment, $home, $shell, $groups=undef, $requiregroups=undef) { +define user::add($uid, $gid, $comment, $home, $shell, $groups=undef) { user { $name: - ensure => present, - uid => $uid, - gid => $gid, - comment => $comment, - home => $home, - shell => $shell, - groups => $groups, - require => $requiregroups, - notify => $::operatingsystem ? { - OpenBSD => [ Exec["user-mod-${name}"], - Exec["user-home-${name}"], ], - default => undef, + ensure => present, + managehome => true, + uid => $uid, + gid => $gid, + comment => $comment, + home => $home, + shell => $shell, + groups => $groups, + } + + if $::operatingsystem == "OpenBSD" { + exec { "usermod -L ldap ${name}": + refreshonly => true, + path => "/sbin:/usr/sbin:/bin:/usr/bin", + subscribe => User[$name], + require => File["/etc/login.conf"], } } - exec { "user-mod-${name}": - command => "usermod -L ldap ${name}", - path => "/sbin:/usr/sbin:/bin:/usr/bin", - refreshonly => true, - require => File["/etc/login.conf"], - } - - exec { "user-home-${name}": - command => "/bin/sh -c 'umask 077; mkdir -p ${home} && tar cf - . | tar xf - -C ${home} && chown -R ${uid}:${gid} ${home}'", - cwd => "/etc/skel", - path => "/sbin:/usr/sbin:/bin:/usr/bin", - creates => $home, - refreshonly => true, - } - } diff --git a/user/scripts/update-classes.rb b/user/scripts/update-classes.rb index 516c987..f4742ca 100755 --- a/user/scripts/update-classes.rb +++ b/user/scripts/update-classes.rb @@ -1,15 +1,14 @@ - -require 'ldap' +require 'set' require 'uri' +require 'ldap' basedn = '' conn = '' -f = File.new('/etc/openldap/ldap.conf', 'r') -f.readlines.each do |line| +File.readlines('/etc/openldap/ldap.conf').each do |line| line = line.strip - next if line =~ /^#/ - next if line == '' + next if line.empty? + next if line.start_with?('#') line = line.split if line[0] == 'BASE' basedn = line[1] @@ -19,14 +18,10 @@ f.readlines.each do |line| uri = URI.parse(uri) begin if uri.scheme == 'ldaps' - if ! uri.port - uri.port = 636 - end + uri.port = 636 unless uri.port conn = LDAP::SSLConn.new(uri.host, uri.port) else - if ! uri.port - uri.port = 389 - end + uri.port = 389 unless uri.port conn = LDAP::Conn.new(uri.host, uri.port) end conn.bind @@ -37,67 +32,56 @@ f.readlines.each do |line| end end end -f.close -user_classes = [] -group_classes = [] +user_pp = [] +group_pp = [] -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] !~ /.*\$.*/ - user_classes << "class user::user::" + entry['uid'][0] + " inherits user::virtual {\n" - user_classes << " realize(User::Newuser['" + entry['uid'][0] + "'])\n" - groups.each do |group| - user_classes << " realize(Group['" + group + "'])\n" - end - user_classes << "}\n\n" +groups = {} + +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, + 'objectClass=posixAccount', ['uid', 'gidNumber']) do |entry| + dn = entry.get_dn + uid = entry['uid'][0] + + # skip samba machine accounts + next if uid.include?('?') + + gids = Set.new + + # find primary group + filter = '(&(objectClass=posixGroup)(gidNumber=%s))' % entry['gidNumber'][0] + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| + gid = group['cn'][0] + gids << gid + groups[gid] = Set.new unless groups.has_key?(gid) + groups[gid] << uid 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 + # find supplementary groups + filter = '(&(objectClass=posixGroup)(|(uniqueMember=%s)(memberUid=%s)))' % [ dn, uid ] + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| + gid = group['cn'][0] + gids << gid + groups[gid] = Set.new unless groups.has_key?(gid) + groups[gid] << uid 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 - group_classes << "class user::group::" + entry['cn'][0] + " {\n" - members.uniq.sort.each do |member| - group_classes << " include user::user::" + member + "\n" - end - group_classes << "}\n\n" - end -} -puts user_classes if ARGV.include?("-u") -puts group_classes if ARGV.include?("-g") + user_pp << "class user::user::%s inherits user::virtual {\n\n" % uid + user_pp << " realize(User::Add[\"%s\"])\n" % uid + gids.sort.each do |gid| + user_pp << " realize(Group[\"%s\"])\n" % gid + end + user_pp << "\n}\n\n" +end + +groups.each do |gid, uids| + next if uids.length == 1 and uids.include?(gid) + group_pp << "class user::group::%s {\n\n" % gid + uids.sort.each do |uid| + group_pp << " include user::user::%s\n" % uid + end + group_pp << "\n}\n\n" +end + +puts user_pp if ARGV.include?("-u") +puts group_pp if ARGV.include?("-g") diff --git a/user/scripts/update-virtual.rb b/user/scripts/update-virtual.rb index 7df89a8..fa3480e 100755 --- a/user/scripts/update-virtual.rb +++ b/user/scripts/update-virtual.rb @@ -1,15 +1,14 @@ - -require 'ldap' +require 'set' require 'uri' +require 'ldap' basedn = '' conn = '' -f = File.new('/etc/openldap/ldap.conf', 'r') -f.readlines.each do |line| +File.readlines('/etc/openldap/ldap.conf').each do |line| line = line.strip - next if line =~ /^#/ - next if line == '' + next if line.empty? + next if line.start_with?('#') line = line.split if line[0] == 'BASE' basedn = line[1] @@ -19,14 +18,10 @@ f.readlines.each do |line| uri = URI.parse(uri) begin if uri.scheme == 'ldaps' - if ! uri.port - uri.port = 636 - end + uri.port = 636 unless uri.port conn = LDAP::SSLConn.new(uri.host, uri.port) else - if ! uri.port - uri.port = 389 - end + uri.port = 389 unless uri.port conn = LDAP::Conn.new(uri.host, uri.port) end conn.bind @@ -37,76 +32,90 @@ f.readlines.each do |line| 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] - } +filter = 'objectClass=posixAccount' +attrs = [ + 'uid', + 'uidNumber', + 'gidNumber', + 'gecos', + 'homeDirectory', + 'loginShell', +] +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrs) do |entry| + dn = entry.get_dn + uid = entry['uid'][0] + uidnumber=entry['uidNumber'][0] + gidnumber=entry['gidNumber'][0] + + primarygroup = nil + groups = Set.new + + filter = '(&(objectClass=posixGroup)(gidNumber=%s))' % gidnumber + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| + primarygroup = group['cn'][0] + end + + continue if primarygroup.nil? + + filter = '(&(objectClass=posixGroup)(|(uniqueMember=%s)(memberUid=%s)))' % [ dn, uid ] + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| + groups << group['cn'][0] + end print "\n" - print " @user::newuser { '%s':\n" % entry['uid'][0] - print " uid => '%s',\n" % entry['uidNumber'][0] - print " gid => '%s',\n" % entry['gidNumber'][0] + print " @user::add { \"%s\":\n" % uid + print " uid => \"%s\",\n" % uidnumber + print " gid => \"%s\",\n" % gidnumber begin - print " comment => '%s',\n" % entry['gecos'][0] + print " comment => \"%s\",\n" % entry['gecos'][0] rescue - print " comment => '%s',\n" % entry['uid'][0] + print " comment => \"%s\",\n" % entry['uid'][0] end - print " home => '%s',\n" % entry['homeDirectory'][0] + print " home => \"%s\",\n" % entry['homeDirectory'][0] begin - print " shell => '%s',\n" % entry['loginShell'][0] + print " shell => \"%s\",\n" % entry['loginShell'][0] rescue - print " shell => '%s',\n" % "/bin/bash" + print " shell => \"%s\",\n" % "/bin/bash" end - if groups.length > 0 - print " groups => $operatingsystem ? {\n" - print " openbsd => [ " - groups.each do |group| - print "'" + group + "', " - end - print "'wheel', " if groups.include?('sysadm') - print "],\n" - print " default => [ " - groups.each do |group| - print "'" + group + "', " - end - print "],\n },\n" + unless groups.empty? + print " groups => $::operatingsystem ? {\n" + print " \"openbsd\" => [ " + groups.each do |group| + print "\"%s\", " % group + end + print "\"wheel\", " if groups.include?('sysadm') + print "],\n" + print " default => [ " + groups.each do |group| + print "\"%s\", " % group + end + print "],\n },\n" end - print " requiregroups => [ Group['" + prigroup + "']," + print " require => [\n" + print " Group[\"%s\"],\n" % primarygroup groups.each do |group| - print "\n Group['" + group + "']," + print " Group[\"%s\"],\n" % group end - print " ],\n" + print " ],\n" print " }\n" +end -} - - -conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, 'objectClass=posixGroup', - ['cn', 'gidNumber', 'memberUid', 'uniqueMember']) { |entry| - - # generate virtual group entry +filter = 'objectClass=posixGroup' +attrs = [ + 'cn', + 'gidNumber', + 'memberUid', + 'uniqueMember', +] +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrs) do |entry| print "\n" - print " @group { '" + entry['cn'][0] + "':\n" + print " @group { \"%s\":\n" % entry['cn'][0] print " ensure => present,\n" - print " gid => '" + entry['gidNumber'][0] + "',\n" + print " gid => %s,\n" % entry['gidNumber'][0] print " }\n" - -} - +end print "\n}\n" From 528df05aea1d8a3d5598ef2b7c407b2c8a24fbd7 Mon Sep 17 00:00:00 2001 From: Ossi Salmi Date: Sat, 3 Aug 2013 21:46:14 +0300 Subject: [PATCH 2/3] user: More refactoring --- user/scripts/update-classes.rb | 59 +++++++------- user/scripts/update-virtual.rb | 141 +++++++++++++++------------------ 2 files changed, 89 insertions(+), 111 deletions(-) diff --git a/user/scripts/update-classes.rb b/user/scripts/update-classes.rb index f4742ca..f64c232 100755 --- a/user/scripts/update-classes.rb +++ b/user/scripts/update-classes.rb @@ -1,23 +1,22 @@ -require 'set' -require 'uri' -require 'ldap' +require "set" +require "uri" +require "ldap" -basedn = '' -conn = '' +conn = nil +basedn = nil -File.readlines('/etc/openldap/ldap.conf').each do |line| +File.readlines("/etc/openldap/ldap.conf").each do |line| line = line.strip - next if line.empty? - next if line.start_with?('#') + next if line.empty? or line.start_with?("#") line = line.split - if line[0] == 'BASE' + if line[0] == "BASE" basedn = line[1] - elsif line[0] == 'URI' + elsif line[0] == "URI" line.shift line.each do |uri| uri = URI.parse(uri) begin - if uri.scheme == 'ldaps' + if uri.scheme == "ldaps" uri.port = 636 unless uri.port conn = LDAP::SSLConn.new(uri.host, uri.port) else @@ -33,53 +32,49 @@ File.readlines('/etc/openldap/ldap.conf').each do |line| end end +groups = {} user_pp = [] group_pp = [] -groups = {} +filter = "objectClass=posixAccount" +attrib = %w(uid gidNumber) +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry| + uid = entry["uid"].first + next if uid.include?("$") # skip samba machine accounts -conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, - 'objectClass=posixAccount', ['uid', 'gidNumber']) do |entry| dn = entry.get_dn - uid = entry['uid'][0] - - # skip samba machine accounts - next if uid.include?('?') + gidnumber = entry["gidNumber"].first gids = Set.new # find primary group - filter = '(&(objectClass=posixGroup)(gidNumber=%s))' % entry['gidNumber'][0] - conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| - gid = group['cn'][0] + filter = "(&(objectClass=posixGroup)(gidNumber=#{gidnumber}))" + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| + gid = group["cn"].first gids << gid groups[gid] = Set.new unless groups.has_key?(gid) groups[gid] << uid end # find supplementary groups - filter = '(&(objectClass=posixGroup)(|(uniqueMember=%s)(memberUid=%s)))' % [ dn, uid ] - conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| - gid = group['cn'][0] + filter = "(&(objectClass=posixGroup)(|(uniqueMember=#{dn})(memberUid=#{uid})))" + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| + gid = group["cn"].first gids << gid groups[gid] = Set.new unless groups.has_key?(gid) groups[gid] << uid end - user_pp << "class user::user::%s inherits user::virtual {\n\n" % uid - user_pp << " realize(User::Add[\"%s\"])\n" % uid - gids.sort.each do |gid| - user_pp << " realize(Group[\"%s\"])\n" % gid - end + user_pp << "class user::user::#{uid} inherits user::virtual {\n\n" + user_pp << " realize(User::Add[\"#{uid}\"])\n" + gids.sort.each { |gid| user_pp << " realize(Group[\"#{gid}\"])\n" } user_pp << "\n}\n\n" end groups.each do |gid, uids| next if uids.length == 1 and uids.include?(gid) group_pp << "class user::group::%s {\n\n" % gid - uids.sort.each do |uid| - group_pp << " include user::user::%s\n" % uid - end + uids.sort.each { |uid| group_pp << " include user::user::#{uid}\n" } group_pp << "\n}\n\n" end diff --git a/user/scripts/update-virtual.rb b/user/scripts/update-virtual.rb index fa3480e..fe60c5f 100755 --- a/user/scripts/update-virtual.rb +++ b/user/scripts/update-virtual.rb @@ -1,23 +1,22 @@ -require 'set' -require 'uri' -require 'ldap' +require "set" +require "uri" +require "ldap" -basedn = '' -conn = '' +conn = nil +basedn = nil -File.readlines('/etc/openldap/ldap.conf').each do |line| +File.readlines("/etc/openldap/ldap.conf").each do |line| line = line.strip - next if line.empty? - next if line.start_with?('#') + next if line.empty? or line.start_with?("#") line = line.split - if line[0] == 'BASE' + if line[0] == "BASE" basedn = line[1] - elsif line[0] == 'URI' + elsif line[0] == "URI" line.shift line.each do |uri| uri = URI.parse(uri) begin - if uri.scheme == 'ldaps' + if uri.scheme == "ldaps" uri.port = 636 unless uri.port conn = LDAP::SSLConn.new(uri.host, uri.port) else @@ -33,89 +32,73 @@ File.readlines('/etc/openldap/ldap.conf').each do |line| end end -print "class user::virtual {\n" +virtual = "class user::virtual {\n" -filter = 'objectClass=posixAccount' -attrs = [ - 'uid', - 'uidNumber', - 'gidNumber', - 'gecos', - 'homeDirectory', - 'loginShell', -] -conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrs) do |entry| +filter = "objectClass=posixAccount" +attrib = %w(uid uidNumber gidNumber gecos homeDirectory loginShell) +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry| dn = entry.get_dn - uid = entry['uid'][0] - uidnumber=entry['uidNumber'][0] - gidnumber=entry['gidNumber'][0] + uid = entry["uid"].first + uidnumber = entry["uidNumber"].first + gidnumber = entry["gidNumber"].first primarygroup = nil groups = Set.new - filter = '(&(objectClass=posixGroup)(gidNumber=%s))' % gidnumber - conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| - primarygroup = group['cn'][0] + filter = "(&(objectClass=posixGroup)(gidNumber=#{gidnumber}))" + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| + primarygroup = group["cn"].first end continue if primarygroup.nil? - filter = '(&(objectClass=posixGroup)(|(uniqueMember=%s)(memberUid=%s)))' % [ dn, uid ] - conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ['cn']) do |group| - groups << group['cn'][0] + filter = "(&(objectClass=posixGroup)(|(uniqueMember=#{dn})(memberUid=#{uid})))" + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| + groups << group["cn"].first end - print "\n" - print " @user::add { \"%s\":\n" % uid - print " uid => \"%s\",\n" % uidnumber - print " gid => \"%s\",\n" % gidnumber - begin - print " comment => \"%s\",\n" % entry['gecos'][0] - rescue - print " comment => \"%s\",\n" % entry['uid'][0] - end - print " home => \"%s\",\n" % entry['homeDirectory'][0] - begin - print " shell => \"%s\",\n" % entry['loginShell'][0] - rescue - print " shell => \"%s\",\n" % "/bin/bash" - end + comment = entry["gecos"] ? entry["gecos"].first : entry["uid"].first + shell = entry["loginShell"] ? entry["loginShell"].first : "/bin/bash" + home = entry["homeDirectory"].first + + virtual << <<-EOF + + @user::add { "#{uid}": + uid => "#{uidnumber}", + gid => "#{gidnumber}", + comment => "#{comment}", + home => "#{home}", + shell => "#{shell}", + EOF + unless groups.empty? - print " groups => $::operatingsystem ? {\n" - print " \"openbsd\" => [ " - groups.each do |group| - print "\"%s\", " % group - end - print "\"wheel\", " if groups.include?('sysadm') - print "],\n" - print " default => [ " - groups.each do |group| - print "\"%s\", " % group - end - print "],\n },\n" + virtual << " groups => $::operatingsystem ? {\n" + virtual << " \"openbsd\" => [ " + groups.each { |group| virtual << "\"#{group}\", " } + virtual << "\"wheel\", " if groups.include?("sysadm") + virtual << "},\n default => [ " + groups.each { |group| virtual << "\"#{group}\", " } + virtual << "],\n },\n" end - print " require => [\n" - print " Group[\"%s\"],\n" % primarygroup - groups.each do |group| - print " Group[\"%s\"],\n" % group - end - print " ],\n" - print " }\n" + virtual << " require => [\n" + virtual << " Group[\"#{primarygroup}\"],\n" + groups.each { |group| virtual << " Group[\"#{group}\"],\n" } + virtual << " ],\n }\n" end -filter = 'objectClass=posixGroup' -attrs = [ - 'cn', - 'gidNumber', - 'memberUid', - 'uniqueMember', -] -conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrs) do |entry| - print "\n" - print " @group { \"%s\":\n" % entry['cn'][0] - print " ensure => present,\n" - print " gid => %s,\n" % entry['gidNumber'][0] - print " }\n" +filter = "objectClass=posixGroup" +attrib = %w(cn gidNumber memberUid uniqueMember) +conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry| + cn = entry["cn"].first + gid = entry["gidNumber"].first + + virtual << <<-EOF + + @group { "#{cn}": + ensure => present, + gid => "#{gid}", + } + EOF end -print "\n}\n" +puts virtual, "\n}" From 76c2ebb3600dd29b9ec941329ddbcb6cbf0f3268 Mon Sep 17 00:00:00 2001 From: Ossi Salmi Date: Sun, 4 Aug 2013 00:40:19 +0300 Subject: [PATCH 3/3] user: Typofix --- user/scripts/update-virtual.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/scripts/update-virtual.rb b/user/scripts/update-virtual.rb index fe60c5f..e3e8271 100755 --- a/user/scripts/update-virtual.rb +++ b/user/scripts/update-virtual.rb @@ -76,7 +76,7 @@ conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry| virtual << " \"openbsd\" => [ " groups.each { |group| virtual << "\"#{group}\", " } virtual << "\"wheel\", " if groups.include?("sysadm") - virtual << "},\n default => [ " + virtual << "],\n default => [ " groups.each { |group| virtual << "\"#{group}\", " } virtual << "],\n },\n" end