From 0b73e7782c7c0f21499294349a5c56ff193fb018 Mon Sep 17 00:00:00 2001 From: Ossi Salmi Date: Sat, 3 Aug 2013 03:41:20 +0300 Subject: [PATCH] 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"