help-cfengine
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bootstrapping


From: Luke A. Kanies
Subject: Re: Bootstrapping
Date: Wed, 18 Feb 2004 17:37:28 -0600 (CST)

On Wed, 18 Feb 2004, John Sechrest wrote:

> "Luke A. Kanies" <luke@madstop.com> writes:
>
>  % Yep.  It's just a pretty simple ldapsearch, wrapped in a cfengine
>  % statement.  Written in ruby. :)
>
>  I would love to look at it and see how it works.

require 'digest/md5'

file = "/var/cfengine/inputs/cfclients.cf"
command = "/usr/local/bin/ldapsearch"
ldapbase = "dc=domain,dc=com"
server = "ldap"
query = "objectclass=iphost"
attrs = "iphostnumber"

extras = %w{
  192.168.0.x
}

string = "control:\n" +
    "\tAllowConnectionsFrom = (\n\t\t" +
    %x{#{command} -b #{ldapbase} -h #{server} #{query} \
#{attrs}}.split("\n").collect{ |line|
        next if line =~ /^#/
        if line =~ /iphostnumber/i
            var, value = line.split
        end
        value
    }.reject { |ip|
        ! defined? ip or ip !~ /^[0-9.]+$/
    }.push(*extras).sort {|ip1,ip2|
        ip1 <=> ip2
    }.uniq.join("\n\t\t") +
    "\t)"

curmd5 = String.new

if File.exists?(file)
    curmd5 = Digest::MD5.hexdigest(File.new(file).read)
else
    curmd5 = ""
end
newmd5 = Digest::MD5.hexdigest(string)

if curmd5 != newmd5
    File.open(file, File::CREAT|File::TRUNC|File::RDWR, 0644) { |file|
        file.print(string)
    }
end

---------------

This is just an external script run out of cfagent.

>  I spent some time talking to mark about that. And I think we decided
>  to try to write some modules first, to see how it would work.
>
>  If you had a module for accessing LDAP,
>
>
> And you say:
>
>  Ldapexists = ( PrepModule(module:getdatafromldap,"${myldapserver} 
> ${myldappaswd}  ${$myldapquery} ") )
>
>  And this module went and got the data you wanted and set it up into
>  various classes and variables.....
>
>  Would this do what you want?

No, because cfservd doesn't have any facilities for evaluate-on-connection
instead of evaluate-on-parse.  There is a significant difference between
them, and without evaluate-on-connection we can't ever really do live
checks from LDAP.

Basically, we need a way to store a reference to code, instead of just a
list.  Something like:

# in perl
my $ip = shift;
if (ref($allowed) == 'ARRAY') {
  return grep $ip, @$allowed;
} else {
  return $allowed->($ip);
}

Really, you'd want caching and stuff in here, but that'd be in the ldap
code portions, not this little snippet.  Cfengine doesn't have the above
ability, though, because it's meant to be interpreted just once and run
through.

Or am I wrong Mark?  Would the above be possible?  I don't know a way to
tell cfservd or cfagent "evaluate this on X condition or at Y time".


>  If so, what is an example of an ldapsearch that you make that would
>  work for setting things up?
>
>  What types of classes would you want to set?
>  What types of variables would you wish were filled in?

I expect it to look something like this:

control:
ldapbase = ( dc=domain,dc=com )
ldapserver = ( ldap.domain.com )
ldapscope = ( sub )
ldapssl = ( true )

AllowConnectionsFrom = (
  SaveCode( |ip| # this is from ruby; i don't know another good method
    LdapSearch(objectclass=iphost&iphostnumber=${ip})
  )
)

Ruby excels at this, but...

>  hhmmmm. In this case, could you force things to go by using:
>
>        - Stuff things into ldap (you have to trust the input into ldap)
>        - run cfagent -I -K -q

Yeah, it's easy to force, but forcing it definitely involves a leaky
abstraction.

Luke

-- 
'Fire them. Fire every single person who ever worked on [Microsoft] Word. If
they're no longer in Redmond, find out where they work and make their boss
fire them. TP their houses. Take away their stock options and hack into
their 401(k) accounts, changing all their long-range holdings into Overseas
Tech Investments.'  --Wired online




reply via email to

[Prev in Thread] Current Thread [Next in Thread]