1 /* $NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jukka Ruohonen. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 2009, Stathis Kamperis 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 48 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 49 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 51 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 52 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 53 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 */ 58 #include <sys/cdefs.h> 59 __RCSID("$NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $"); 60 61 #include <sys/wait.h> 62 63 #include <atf-c.h> 64 #include <grp.h> 65 #include <stdlib.h> 66 #include <unistd.h> 67 68 ATF_TC(getgrent_loop); 69 ATF_TC_HEAD(getgrent_loop, tc) 70 { 71 atf_tc_set_md_var(tc, "descr", "Test sequential getgrent(2)"); 72 } 73 74 ATF_TC_BODY(getgrent_loop, tc) 75 { 76 struct group *gr; 77 size_t i, j; 78 79 /* 80 * Loop over the group database. The first 81 * call returns the first entry and subsequent 82 * calls return the rest of the entries. 83 */ 84 i = j = 0; 85 86 while((gr = getgrent()) != NULL) 87 i++; 88 89 /* 90 * Rewind the database to the beginning 91 * and loop over again until the end. 92 */ 93 setgrent(); 94 95 while((gr = getgrent()) != NULL) 96 j++; 97 98 if (i != j) 99 atf_tc_fail("sequential getgrent(3) failed"); 100 101 /* 102 * Close the database and reopen it. 103 * The getgrent(3) call should always 104 * automatically rewind the database. 105 */ 106 endgrent(); 107 108 j = 0; 109 110 while((gr = getgrent()) != NULL) 111 j++; 112 113 if (i != j) 114 atf_tc_fail("getgrent(3) did not rewind"); 115 } 116 117 ATF_TC(getgrent_setgid); 118 ATF_TC_HEAD(getgrent_setgid, tc) 119 { 120 atf_tc_set_md_var(tc, "descr", "Test consistency of the group db"); 121 atf_tc_set_md_var(tc, "require.user", "root"); 122 } 123 124 ATF_TC_BODY(getgrent_setgid, tc) 125 { 126 struct group *gr, *gr1, *gr2; 127 int rv, sta; 128 pid_t pid; 129 130 /* 131 * Verify that the database is consistent. 132 * 133 * Note that because of the static buffers 134 * used by getgrent(3), fork(2) is required, 135 * even without the setgid(2) check. 136 */ 137 while((gr = getgrent()) != NULL) { 138 139 pid = fork(); 140 ATF_REQUIRE(pid >= 0); 141 142 if (pid == 0) { 143 144 gr1 = getgrgid(gr->gr_gid); 145 146 if (gr1 == NULL) 147 _exit(EXIT_FAILURE); 148 149 gr2 = getgrnam(gr->gr_name); 150 151 if (gr2 == NULL) 152 _exit(EXIT_FAILURE); 153 154 rv = setgid(gr->gr_gid); 155 156 if (rv != 0) 157 _exit(EXIT_FAILURE); 158 159 _exit(EXIT_SUCCESS); 160 } 161 162 (void)wait(&sta); 163 164 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) 165 goto fail; 166 } 167 168 return; 169 170 fail: 171 atf_tc_fail("group database is inconsistent"); 172 } 173 174 ATF_TP_ADD_TCS(tp) 175 { 176 177 ATF_TP_ADD_TC(tp, getgrent_loop); 178 ATF_TP_ADD_TC(tp, getgrent_setgid); 179 180 return atf_no_error(); 181 } 182