Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

building structure from /etc/passwd files deux

by tux242 (Acolyte)
on Nov 04, 2003 at 19:40 UTC ( [id://304520]=perlquestion: print w/replies, xml ) Need Help??

tux242 has asked for the wisdom of the Perl Monks concerning the following question:

Basically, what I am trying to do is merge the 2/etc/passwd related scripts below un and deux. I am looking for an end result of a : (csv type) delimited file, and an iteration of uniqueid: original gcos or pulled ldap information:every server that this unique id is on, which I will eventually pull or push into a excel file later on, once I figure out how. So I need present in the final file a listing like this:

yyn4532:Jim Brown(from $gecos):server1:server2:server3... zzx9911:Jake Black(from LDAP):BNOC (from LDAP):Gary(from LDAP):IN(from + LDAP):Manager=Trudy Farret(from LDAP):server 1:server2:server5...
Thanks

Tux242

script un:

#! /usr/bin/perl #@files=('passwd.server1','passwd.server2','passwd.server3','passw +d.server4','passwd.server5','passwd.server6','passwd.server7','passwd +.server8','passwd.server9'); foreach my $file (<passwd.*>){ open (PASSWD,"$file"); $nf="splitstrx"; open (NEWFILE, ">$nf"); while (<PASSWD>) { ($login, $passwd, $uid, $gid, $gcos, $home, $shell) = split(/:/); $USERS{$login} = $gcos; } close (PASSWD); } foreach $login (sort keys %USERS) { $gcos = $USERS{$login}; print NEWFILE "$login\n"; } close (NEWFILE); use Net::LDAP; use Net::LDAP::LDIF; use Net::LDAP::Entry; # Set $use_credentials to 0 to bind anonymously. # When anonymous access is used, restricted data including uid can not + be accessed. $use_credentials = 0; # If $use_credentials is set to any non-zero value to use $bind_dn and + $bind_pw $bind_dn = 'anonymous'; # login ID for server $bind_pw = 'nopassword'; # password $ldap_server = 'mycorp.com'; # host name of ldap server $ldap_base = 'ou=People,o=Newco,c=US'; # DN of search base # The following defines what attributes will be included in the outpu +t # enter one attribute name per line in lower case inside 'single quot +es' # and followed by a comma. @attr_list = ( 'cn', 'fonDeptName', 'telephoneNumber', 'l', 'st', ); # print column header print "$_|InputValue|cn|fonDeptName|telephoneNumber|l|st\n"; # ************** End of configuration section *********************** # ******************************************************************* # ************** Initialization ****************** # Set up a search pattern that will recognize any attribute. $attrs = join('|', @attr_list); # Create the global variables with an assignment to null. foreach $attr (@attr_list) { ${$attr} = ""; } #print "Bind using server $ldap_server and ID of $bind_dn\n"; # establish LDAP connection $ldap = Net::LDAP->new($ldap_server); unless ($ldap){ my $errmsg = $@; print STDERR "Failed to open LDAP session. Error = $errmsg\n"; exit; } #log in if ($use_credentials) { $mesg = $ldap->bind($bind_dn, password => $bind_pw); if (scalar $mesg->code){ my $errmsg = $mesg->error; my $errcode = $mesg->code; print STDERR "Failed to bind as $bind_pw, Error = $errcode ($e +rrmsg)\n"; $ldap->unbind; exit; } } else { # print STDERR "Warning: Not using credentials. Some attributes m +ay not be available.\n"; } # ***************** main ***************** $nf="splitstrx"; open (NEWFILE, "$nf"); $af="endstrx"; open (LDAPFILE, ">$af"); my $strip=$file; $strip =~ s/passwd\.//; while (<NEWFILE>) { chomp; #remove newline in input string if(exists $USERS{$login}) { push(@{$USERS{$login}},$strip); } # search for any attribute matching the input string $srchresult = searchPeople($ldap,"(zcanyattribute=$_)"); # Warn if not found if ($srchresult->count == 0) { $login = $_; $gcos = $USERS{$login}; print LDAPFILE "$login|$gcos\n"; #print NEWFILE "$login\n"; #print "$_|Not found\n"; } # Warn if not unique elsif ($srchresult->count > 1) { print LDAPFILE "$_|Yields more than 1 result\n"; } # otherwise generte the output else { my $entry = $srchresult->entry(0); my $dn = $entry->dn; $outline = ""; foreach $attr (@attr_list) { # for perl-ldap .22 $$attr = $entry->get_value($attr); $outline .= "$$attr\|"; # for older versions #my @vals = $entry->get($attr); #$outline .= "$vals[0]\,"; } #print "$_: $outline\n"; #print "$_|$outline\n"; print LDAPFILE "$_|$outline\n"; } } close LDAPFILE; $ldap->unbind; # ********************************************** sub searchPeople # ********************************************** # Search the people branch of the tree with a designated search filter +. # { my ($ldap, $searchfilter) = @_; # Assign the search base and list of attributes that interest us my $base = $ldap_base; # call the search method and return the result my $result = $ldap->search ( base => "$base", scope => "sub", filter => "$searchfilter", attrs => \@attr_list ); } ## End of searchPeople ##

script deux:

#!/usr/bin/perl -w use strict; my %USERS; foreach my $file (<passwd.*>) { open(PASSWD,$file); my $strip=$file; $strip =~ s/passwd\.//; while(<PASSWD>) { my($login,$gcos) = (split(':',$_))[0,4]; if(exists $USERS{$login}) { push(@{$USERS{$login}},$strip); } else { $USERS{$login} = [$gcos,$strip]; } } close(PASSWD); } open(NEWFILE,">servup") || print "Can't open servup: $!\n"; foreach my $login (sort keys %USERS) { print NEWFILE "$login:".shift(@{$USERS{$login}}).":"; print NEWFILE join(':',@{$USERS{$login}})."\n"; } close(NEWFILE);
Edit by castaway added p and code tags.

Replies are listed 'Best First'.
Re: building structure from /etc/passwd files deux
by jeffa (Bishop) on Nov 04, 2003 at 20:21 UTC
    I would definitely bring DBD::AnyData along for the ride. From the docs:
    # SELECT DATA FROM A PASSWD FILE $dbh->func( 'users', 'Passwd', '/etc/passwd', 'ad_catalog'); my $sth = $dbh->prepare("SELECT username,homedir,GID FROM users');

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: building structure from /etc/passwd files deux
by jZed (Prior) on Nov 05, 2003 at 23:15 UTC
    Here's the entire script using DBD::AnyData -
    #!/usr/bin/perl -w $|=1; use strict; use DBI; my $dbh=DBI->connect('dbi:AnyData(RaiseError=1):'); $dbh->func( 'users', 'Passwd', '/etc/passwd', 'ad_catalog'); $dbh->func( 'servers', 'CSV', '/etc/servers', {sep_char=>':',col_names +=>'username,s1,s2,s3'},'ad_catalog'); my $sth = $dbh->prepare(" SELECT users.username, homedir, shell, s1, s2, s3 FROM users NATURAL JOIN servers "); $sth->execute; while (my $r = $sth->fetch) { print "@$r\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://304520]
Approved by particle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-04-20 00:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found