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..f64c232 100755 --- a/user/scripts/update-classes.rb +++ b/user/scripts/update-classes.rb @@ -1,32 +1,26 @@ +require "set" +require "uri" +require "ldap" -require 'ldap' -require 'uri' +conn = nil +basedn = nil -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? 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.port - uri.port = 636 - end + if uri.scheme == "ldaps" + 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 +31,52 @@ f.readlines.each do |line| end end end -f.close -user_classes = [] -group_classes = [] +groups = {} +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" +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 + + dn = entry.get_dn + gidnumber = entry["gidNumber"].first + + gids = Set.new + + # find primary group + 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 - 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=#{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 - 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::#{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 { |uid| group_pp << " include user::user::#{uid}\n" } + 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..e3e8271 100755 --- a/user/scripts/update-virtual.rb +++ b/user/scripts/update-virtual.rb @@ -1,32 +1,26 @@ +require "set" +require "uri" +require "ldap" -require 'ldap' -require 'uri' +conn = nil +basedn = nil -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? 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.port - uri.port = 636 - end + if uri.scheme == "ldaps" + 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 +31,74 @@ f.readlines.each do |line| end end end -f.close -print "class user::virtual {\n" +virtual = "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" +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"].first + uidnumber = entry["uidNumber"].first + gidnumber = entry["gidNumber"].first + + primarygroup = nil + groups = Set.new + + 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=#{dn})(memberUid=#{uid})))" + conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| + groups << group["cn"].first + 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? + 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 + virtual << " require => [\n" + virtual << " Group[\"#{primarygroup}\"],\n" + groups.each { |group| virtual << " Group[\"#{group}\"],\n" } + virtual << " ],\n }\n" +end + +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" - print " @user::newuser { '%s':\n" % entry['uid'][0] - print " uid => '%s',\n" % entry['uidNumber'][0] - print " gid => '%s',\n" % entry['gidNumber'][0] - 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 - 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" - end - print " requiregroups => [ 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" +puts virtual, "\n}"