1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateBEGIN { 4*0Sstevel@tonic-gate chdir 't' if -d 't'; 5*0Sstevel@tonic-gate @INC = '../lib'; 6*0Sstevel@tonic-gate require './test.pl'; 7*0Sstevel@tonic-gate} 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gateeval {my @n = getgrgid 0}; 10*0Sstevel@tonic-gateif ($@ =~ /(The \w+ function is unimplemented)/) { 11*0Sstevel@tonic-gate skip_all "getgrgid unimplemented"; 12*0Sstevel@tonic-gate} 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gateeval { require Config; import Config; }; 15*0Sstevel@tonic-gatemy $reason; 16*0Sstevel@tonic-gateif ($Config{'i_grp'} ne 'define') { 17*0Sstevel@tonic-gate $reason = '$Config{i_grp} not defined'; 18*0Sstevel@tonic-gate} 19*0Sstevel@tonic-gateelsif (not -f "/etc/group" ) { # Play safe. 20*0Sstevel@tonic-gate $reason = 'no /etc/group file'; 21*0Sstevel@tonic-gate} 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gateif (not defined $where) { # Try NIS. 24*0Sstevel@tonic-gate foreach my $ypcat (qw(/usr/bin/ypcat /bin/ypcat /etc/ypcat)) { 25*0Sstevel@tonic-gate if (-x $ypcat && 26*0Sstevel@tonic-gate open(GR, "$ypcat group 2>/dev/null |") && 27*0Sstevel@tonic-gate defined(<GR>)) 28*0Sstevel@tonic-gate { 29*0Sstevel@tonic-gate print "# `ypcat group` worked\n"; 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate # Check to make sure we're really using NIS. 32*0Sstevel@tonic-gate if( open(NSSW, "/etc/nsswitch.conf" ) ) { 33*0Sstevel@tonic-gate my($group) = grep /^\s*group:/, <NSSW>; 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate # If there's no group line, assume it default to compat. 36*0Sstevel@tonic-gate if( !$group || $group !~ /(nis|compat)/ ) { 37*0Sstevel@tonic-gate print "# Doesn't look like you're using NIS in ". 38*0Sstevel@tonic-gate "/etc/nsswitch.conf\n"; 39*0Sstevel@tonic-gate last; 40*0Sstevel@tonic-gate } 41*0Sstevel@tonic-gate } 42*0Sstevel@tonic-gate $where = "NIS group - $ypcat"; 43*0Sstevel@tonic-gate undef $reason; 44*0Sstevel@tonic-gate last; 45*0Sstevel@tonic-gate } 46*0Sstevel@tonic-gate } 47*0Sstevel@tonic-gate} 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gateif (not defined $where) { # Try NetInfo. 50*0Sstevel@tonic-gate foreach my $nidump (qw(/usr/bin/nidump)) { 51*0Sstevel@tonic-gate if (-x $nidump && 52*0Sstevel@tonic-gate open(GR, "$nidump group . 2>/dev/null |") && 53*0Sstevel@tonic-gate defined(<GR>)) 54*0Sstevel@tonic-gate { 55*0Sstevel@tonic-gate $where = "NetInfo group - $nidump"; 56*0Sstevel@tonic-gate undef $reason; 57*0Sstevel@tonic-gate last; 58*0Sstevel@tonic-gate } 59*0Sstevel@tonic-gate } 60*0Sstevel@tonic-gate} 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gateif (not defined $where) { # Try local. 63*0Sstevel@tonic-gate my $GR = "/etc/group"; 64*0Sstevel@tonic-gate if (-f $GR && open(GR, $GR) && defined(<GR>)) { 65*0Sstevel@tonic-gate undef $reason; 66*0Sstevel@tonic-gate $where = "local $GR"; 67*0Sstevel@tonic-gate } 68*0Sstevel@tonic-gate} 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gateif ($reason) { 71*0Sstevel@tonic-gate skip_all $reason; 72*0Sstevel@tonic-gate} 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate# By now the GR filehandle should be open and full of juicy group entries. 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gateplan tests => 3; 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate# Go through at most this many groups. 80*0Sstevel@tonic-gate# (note that the first entry has been read away by now) 81*0Sstevel@tonic-gatemy $max = 25; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gatemy $n = 0; 84*0Sstevel@tonic-gatemy $tst = 1; 85*0Sstevel@tonic-gatemy %perfect; 86*0Sstevel@tonic-gatemy %seen; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gateprint "# where $where\n"; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gateok( setgrent(), 'setgrent' ) || print "# $!\n"; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gatewhile (<GR>) { 93*0Sstevel@tonic-gate chomp; 94*0Sstevel@tonic-gate # LIMIT -1 so that groups with no users don't fall off 95*0Sstevel@tonic-gate my @s = split /:/, $_, -1; 96*0Sstevel@tonic-gate my ($name_s,$passwd_s,$gid_s,$members_s) = @s; 97*0Sstevel@tonic-gate if (@s) { 98*0Sstevel@tonic-gate push @{ $seen{$name_s} }, $.; 99*0Sstevel@tonic-gate } else { 100*0Sstevel@tonic-gate warn "# Your $where line $. is empty.\n"; 101*0Sstevel@tonic-gate next; 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate if ($n == $max) { 104*0Sstevel@tonic-gate local $/; 105*0Sstevel@tonic-gate my $junk = <GR>; 106*0Sstevel@tonic-gate last; 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate # In principle we could whine if @s != 4 but do we know enough 109*0Sstevel@tonic-gate # of group file formats everywhere? 110*0Sstevel@tonic-gate if (@s == 4) { 111*0Sstevel@tonic-gate $members_s =~ s/\s*,\s*/,/g; 112*0Sstevel@tonic-gate $members_s =~ s/\s+$//; 113*0Sstevel@tonic-gate $members_s =~ s/^\s+//; 114*0Sstevel@tonic-gate @n = getgrgid($gid_s); 115*0Sstevel@tonic-gate # 'nogroup' et al. 116*0Sstevel@tonic-gate next unless @n; 117*0Sstevel@tonic-gate my ($name,$passwd,$gid,$members) = @n; 118*0Sstevel@tonic-gate # Protect against one-to-many and many-to-one mappings. 119*0Sstevel@tonic-gate if ($name_s ne $name) { 120*0Sstevel@tonic-gate @n = getgrnam($name_s); 121*0Sstevel@tonic-gate ($name,$passwd,$gid,$members) = @n; 122*0Sstevel@tonic-gate next if $name_s ne $name; 123*0Sstevel@tonic-gate } 124*0Sstevel@tonic-gate # NOTE: group names *CAN* contain whitespace. 125*0Sstevel@tonic-gate $members =~ s/\s+/,/g; 126*0Sstevel@tonic-gate # what about different orders of members? 127*0Sstevel@tonic-gate $perfect{$name_s}++ 128*0Sstevel@tonic-gate if $name eq $name_s and 129*0Sstevel@tonic-gate# Do not compare passwords: think shadow passwords. 130*0Sstevel@tonic-gate# Not that group passwords are used much but better not assume anything. 131*0Sstevel@tonic-gate $gid eq $gid_s and 132*0Sstevel@tonic-gate $members eq $members_s; 133*0Sstevel@tonic-gate } 134*0Sstevel@tonic-gate $n++; 135*0Sstevel@tonic-gate} 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gateendgrent(); 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gateprint "# max = $max, n = $n, perfect = ", scalar keys %perfect, "\n"; 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gateif (keys %perfect == 0 && $n) { 142*0Sstevel@tonic-gate $max++; 143*0Sstevel@tonic-gate print <<EOEX; 144*0Sstevel@tonic-gate# 145*0Sstevel@tonic-gate# The failure of op/grent test is not necessarily serious. 146*0Sstevel@tonic-gate# It may fail due to local group administration conventions. 147*0Sstevel@tonic-gate# If you are for example using both NIS and local groups, 148*0Sstevel@tonic-gate# test failure is possible. Any distributed group scheme 149*0Sstevel@tonic-gate# can cause such failures. 150*0Sstevel@tonic-gate# 151*0Sstevel@tonic-gate# What the grent test is doing is that it compares the $max first 152*0Sstevel@tonic-gate# entries of $where 153*0Sstevel@tonic-gate# with the results of getgrgid() and getgrnam() call. If it finds no 154*0Sstevel@tonic-gate# matches at all, it suspects something is wrong. 155*0Sstevel@tonic-gate# 156*0Sstevel@tonic-gateEOEX 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate fail(); 159*0Sstevel@tonic-gate print "#\t (not necessarily serious: run t/op/grent.t by itself)\n"; 160*0Sstevel@tonic-gate} else { 161*0Sstevel@tonic-gate pass(); 162*0Sstevel@tonic-gate} 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate# Test both the scalar and list contexts. 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gatemy @gr1; 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gatesetgrent(); 169*0Sstevel@tonic-gatefor (1..$max) { 170*0Sstevel@tonic-gate my $gr = scalar getgrent(); 171*0Sstevel@tonic-gate last unless defined $gr; 172*0Sstevel@tonic-gate push @gr1, $gr; 173*0Sstevel@tonic-gate} 174*0Sstevel@tonic-gateendgrent(); 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gatemy @gr2; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gatesetgrent(); 179*0Sstevel@tonic-gatefor (1..$max) { 180*0Sstevel@tonic-gate my ($gr) = (getgrent()); 181*0Sstevel@tonic-gate last unless defined $gr; 182*0Sstevel@tonic-gate push @gr2, $gr; 183*0Sstevel@tonic-gate} 184*0Sstevel@tonic-gateendgrent(); 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gateis("@gr1", "@gr2"); 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gateclose(GR); 189