#!/usr/local/bin/perl # # Listgroup module # # $Id: Listgroup.pm,v 1.16 2003-01-21 12:24:09-05 mprewitt Exp $ # # ----- =head1 NAME B - Lists hosts/users in a netgroup group. =head1 SYNOPSIS use Listgroup; $array_ref_groups = listgroup(); $array_ref_groups = listgroups(); $array_ref_users_or_groups = listgroup({groupname}); $array_ref_users_or_groups = listgroup_user({groupname1}, [ [-]{groupname2}, [-]{gropuname3} ]); $array_ref_users_or_groups = listgroup_host({groupname1}, [ [-]{groupname2}, [-]{gropuname3} ]); =head1 DESCRIPTION A library used to get groups or members of a netgroup NIS map. B without any parameters or B lists all the available netgroup groups. With groupname parameters B will recusively list the members of the named groups. If the groupname is preceded with a B<-> members of that group will be excluded from the returned list. Each member in a group is a triplet of (host,user,domain). The host portion or user portion of the members is returned by B and B, the user portion of the members is returned by B. =head1 REQUIRES Net::NIS =head1 SEE ALSO L, L, L =head1 AUTHOR Original unknown Major rewrite by Marc Prewitt Copyright (C) 2003 Chelsea Networks, under the GNU GPL. listgroup comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the COPYING file for details. listgroup is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. listgroup is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA =head1 PUBLIC METHODS =cut package Net::NIS::Listgroup; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(listgroup); use strict; use Net::NIS qw( :all ); use vars qw( $VERSION $DOMAIN ); $DOMAIN = Net::NIS::yp_get_default_domain(); my $YPCAT = '/usr/bin/ypcat'; $VERSION = (qw $Revision: 1.16 $)[1]; =head2 listgroups $array_ref_groups = listgroups(); Returns a reference to an array of groups from the netgroup nis map. =cut sub listgroups { my %netgroup; tie %netgroup, 'Net::NIS', 'netgroup'; return [ sort keys %netgroup ]; } =head2 listgroup_host, listgroup $array_ref_users_or_groups = listgroup({groupname1}, [ [-]{groupname2}, [-]{gropuname3} ]); $array_ref_users_or_groups = listgroup_host({groupname1}, [ [-]{groupname2}, [-]{gropuname3} ]); Returns a reference to an array of the host portion of the members of the provided groups. Members of groupnames preceded by a B<-> will be excluded from the returned list. Groups are processed in the order they appear in the parameter list. If the NIS map 'netgroup' does not exist or another fatal NIS error occurs, die will be called. Wrap this call in an eval if you want to catch that type of error. =cut sub listgroup_host { my $r = Net::NIS::Listgroup::Request->new(); $r->setHost(); return $r->_listgroup(@_); } sub listgroup { my $r = Net::NIS::Listgroup::Request->new(); $r->setHost(); return $r->_listgroup(@_); } =head2 listgroup_user $array_ref_users_or_groups = listgroup_user({groupname1}, [ [-]{groupname2}, [-]{gropuname3} ]); Returns a reference to an array of the user portion of the members of the provided groups. Members of groupnames preceded by a B<-> will be excluded from the returned list. Groups are processed in the order they appear in the parameter list. If the NIS map 'netgroup' does not exist or another fatal NIS error occurs, die will be called. Wrap this call in an eval if you want to catch that type of error. =cut sub listgroup_user { my $r = Net::NIS::Listgroup::Request->new(); $r->setUser(); return $r->_listgroup(@_); } #====================================================================== package Net::NIS::Listgroup::Request; use Net::NIS qw( :all ); my $YPMATCH = '/usr/bin/ypmatch'; # # new returns an object used to encapsulate options passed in the # original request. # sub new { my $type = shift; $type = ref($type) if ref($type); return bless {}, $type; } # # $request->setHost() # # This requset will return host information # sub setHost { my $self = shift; $self->{user} = 0; return $self->{host} = 1; } # # $request->setUser() # # This request will return user information # sub setUser { my $self = shift; $self->{host} = 0; return $self->{user} = 1; } # # $want_user = $request->getUser() # # Whether the user field is wanted in the request. # sub getUser { my $self = shift; return $self->{user}; } # # $request->_listgroup( @groups ) # # Returns a arrayref of members contained or not contained # in @groups. If a group starts with a '-' it's members # will be excluded from the list. # sub _listgroup { my $r = shift; my @args = @_; my ( %returns ); foreach my $netgroup (@args) { my $subtract; if ( $netgroup =~ s/^-// ) { $subtract = 1; } my ($status, $members) = Net::NIS::yp_match($Net::NIS::Listgroup::DOMAIN, 'netgroup', $netgroup); die "Unknown netgroup: $netgroup [$Net::NIS::yperr]\n" unless $status == YPERR_SUCCESS; $members =~ s/#.*//; # remove comments foreach my $member ( split(/\s+/, $members) ) { if ($member =~ s/^\(//) { $member =~ s/\)$//; my ($host, $user, $domain) = split(/,/, $member); if ($r->getUser()) { if ($subtract) { delete $returns{$user}; } else { $returns{$user} = $user if $user; } } else { if ($subtract) { delete $returns{$host}; } else { $returns{$host} = $host if $host; } } } else { foreach my $thing (@{$r->_listgroup($member) || []}) { if ($subtract) { delete $returns{$thing}; } else { $returns{$thing} = $thing if $thing; } } } } } return [sort keys %returns]; } 1;