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