#!/usr/bin/ruby # # Copyright (c) 2004, 2006 Peter Palfrader # # All rights reserved. # require "ldap" require "getoptlong" require "myldap" require "yaml" config = YAML::load( File.open( '/etc/noreply/config' ) ) def usage puts "Usage: "+$0+" --help | --client [--password ] [--description ]" end print_usage = false client = nil password = [File.new("/dev/urandom").read(config['module']['client']['pwlen'])].pack("m").chomp.delete('=') description = nil begin GetoptLong.new( [ "--help" , "-h", GetoptLong::NO_ARGUMENT ], [ "--client" , "-c", GetoptLong::REQUIRED_ARGUMENT ], [ "--password" , "-p", GetoptLong::REQUIRED_ARGUMENT ], [ "--description" , "-D", GetoptLong::REQUIRED_ARGUMENT ] ).each { |option, argument| case option when "--help" print_usage = true when "--client" client = argument when "--password" password = argument when "--description" description = argument else raise("Unexpected option "+option); end } rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument, GetoptLong::NeedlessArgument usage exit 1; end if print_usage or (ARGV.length > 0) or (!client) or (!password) usage exit 0 if print_usage exit 1 end ldap = MyLDAP.new(config) # searching new uids newuid = config['module']['client']['minuid'] begin ldap.conn.search(config['basedn'], LDAP::LDAP_SCOPE_SUBTREE, '(objectclass=tnClient)') {|e| thiscn = e.vals("cn").pop; thisuid = e.vals("uidNumber").pop.to_i; thisgid = e.vals("gidNumber").pop.to_i; STDERR.puts("warning: uid/gid mismatch for client "+thiscn) unless thisuid == thisgid; thisuid = thisuid > thisgid ? thisuid : thisgid newuid = newuid > thisuid ? newuid : thisuid; } rescue LDAP::ResultError => msg $stderr.print(msg) exit 1; end newuid += 1 data = { 'objectclass' => ['top', 'tnClient', 'posixAccount', 'posixGroup'], 'o' => [client], 'userPassword' => [password], 'homeDirectory' => [ config['module']['client']['basehome'] + '/' + client ], 'cn' => [ 'W' + client ], 'uid' => [ 'W' + client ], 'uidNumber' => [ newuid.to_s ], 'gidNumber' => [ newuid.to_s ] } data['description'] = [description] if description dn = "o=%s,ou=hosting,%s"%[client, config['basedn']] ldap.add(dn, data) %w(mail vhosts ftp dns).each{ |ou| ldap.add("ou="+ou+","+dn, { 'objectclass' => ['top', 'organizationalUnit'], 'ou' => [ou]}) } %w(people domains uucp).each{ |ou| ldap.add("ou="+ou+",ou=mail,"+dn, { 'objectclass' => ['top', 'organizationalUnit'], 'ou' => [ou]}) } #ldap.add("ou=postgresql,"+dn, { # 'objectclass' => ['top', 'organizationalUnit', 'tnPostgreSQLdatabase'], # 'ou' => ['postgresql'], # 'cn' => [client] })