108ca345cSEnji Cooper /*- 208ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 308ca345cSEnji Cooper * All rights reserved. 408ca345cSEnji Cooper * 508ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 608ca345cSEnji Cooper * modification, are permitted provided that the following conditions 708ca345cSEnji Cooper * are met: 808ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 908ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 1008ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1108ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 1208ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 1308ca345cSEnji Cooper * 1408ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1508ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1608ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1708ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1808ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1908ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2008ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2108ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2208ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2308ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2408ca345cSEnji Cooper * SUCH DAMAGE. 2508ca345cSEnji Cooper * 2608ca345cSEnji Cooper */ 2708ca345cSEnji Cooper 2808ca345cSEnji Cooper #include <arpa/inet.h> 2908ca345cSEnji Cooper #include <errno.h> 3008ca345cSEnji Cooper #include <grp.h> 3108ca345cSEnji Cooper #include <stdio.h> 3208ca345cSEnji Cooper #include <stdlib.h> 3308ca345cSEnji Cooper #include <string.h> 3408ca345cSEnji Cooper #include <stringlist.h> 3508ca345cSEnji Cooper #include <unistd.h> 3608ca345cSEnji Cooper 3708ca345cSEnji Cooper #include <atf-c.h> 3808ca345cSEnji Cooper 3908ca345cSEnji Cooper #include "testutil.h" 4008ca345cSEnji Cooper 4108ca345cSEnji Cooper enum test_methods { 426e411d8bSMark Johnston TEST_GETGRENT, 436e411d8bSMark Johnston TEST_GETGRNAM, 446e411d8bSMark Johnston TEST_GETGRGID, 456e411d8bSMark Johnston TEST_GETGRENT_2PASS, 466e411d8bSMark Johnston TEST_GETGRENT_INTERLEAVED_GETGRNAM, 476e411d8bSMark Johnston TEST_GETGRENT_INTERLEAVED_GETGRGID, 486e411d8bSMark Johnston TEST_BUILD_SNAPSHOT, 4908ca345cSEnji Cooper }; 5008ca345cSEnji Cooper 5108ca345cSEnji Cooper DECLARE_TEST_DATA(group) 5208ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(group) 5308ca345cSEnji Cooper DECLARE_1PASS_TEST(group) 5408ca345cSEnji Cooper DECLARE_2PASS_TEST(group) 5508ca345cSEnji Cooper 5608ca345cSEnji Cooper static void clone_group(struct group *, struct group const *); 5708ca345cSEnji Cooper static int compare_group(struct group *, struct group *, void *); 5808ca345cSEnji Cooper static void dump_group(struct group *); 5908ca345cSEnji Cooper static void free_group(struct group *); 6008ca345cSEnji Cooper 6108ca345cSEnji Cooper static void sdump_group(struct group *, char *, size_t); 6208ca345cSEnji Cooper static int group_read_snapshot_func(struct group *, char *); 6308ca345cSEnji Cooper 64ed14c69dSMark Johnston static int group_check_ambiguity(struct group_test_data *, struct group *); 656e411d8bSMark Johnston static int group_fill_test_data(struct group_test_data *, 666e411d8bSMark Johnston int (*cb)(struct group *, void *)); 6708ca345cSEnji Cooper static int group_test_correctness(struct group *, void *); 6808ca345cSEnji Cooper static int group_test_getgrnam(struct group *, void *); 6908ca345cSEnji Cooper static int group_test_getgrgid(struct group *, void *); 7008ca345cSEnji Cooper static int group_test_getgrent(struct group *, void *); 7108ca345cSEnji Cooper 7208ca345cSEnji Cooper IMPLEMENT_TEST_DATA(group) 7308ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(group) 7408ca345cSEnji Cooper IMPLEMENT_1PASS_TEST(group) 7508ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(group) 7608ca345cSEnji Cooper 7708ca345cSEnji Cooper static void 7808ca345cSEnji Cooper clone_group(struct group *dest, struct group const *src) 7908ca345cSEnji Cooper { 8008ca345cSEnji Cooper ATF_REQUIRE(dest != NULL); 8108ca345cSEnji Cooper ATF_REQUIRE(src != NULL); 8208ca345cSEnji Cooper 8308ca345cSEnji Cooper char **cp; 8408ca345cSEnji Cooper int members_num; 8508ca345cSEnji Cooper 8608ca345cSEnji Cooper memset(dest, 0, sizeof(struct group)); 8708ca345cSEnji Cooper 8808ca345cSEnji Cooper if (src->gr_name != NULL) { 8908ca345cSEnji Cooper dest->gr_name = strdup(src->gr_name); 9008ca345cSEnji Cooper ATF_REQUIRE(dest->gr_name != NULL); 9108ca345cSEnji Cooper } 9208ca345cSEnji Cooper 9308ca345cSEnji Cooper if (src->gr_passwd != NULL) { 9408ca345cSEnji Cooper dest->gr_passwd = strdup(src->gr_passwd); 9508ca345cSEnji Cooper ATF_REQUIRE(dest->gr_passwd != NULL); 9608ca345cSEnji Cooper } 9708ca345cSEnji Cooper dest->gr_gid = src->gr_gid; 9808ca345cSEnji Cooper 9908ca345cSEnji Cooper if (src->gr_mem != NULL) { 10008ca345cSEnji Cooper members_num = 0; 10108ca345cSEnji Cooper for (cp = src->gr_mem; *cp; ++cp) 10208ca345cSEnji Cooper ++members_num; 10308ca345cSEnji Cooper 1043bdd6cf0SEnji Cooper dest->gr_mem = calloc(members_num + 1, sizeof(char *)); 10508ca345cSEnji Cooper ATF_REQUIRE(dest->gr_mem != NULL); 10608ca345cSEnji Cooper 10708ca345cSEnji Cooper for (cp = src->gr_mem; *cp; ++cp) { 10808ca345cSEnji Cooper dest->gr_mem[cp - src->gr_mem] = strdup(*cp); 10908ca345cSEnji Cooper ATF_REQUIRE(dest->gr_mem[cp - src->gr_mem] != NULL); 11008ca345cSEnji Cooper } 11108ca345cSEnji Cooper } 11208ca345cSEnji Cooper } 11308ca345cSEnji Cooper 11408ca345cSEnji Cooper static void 11508ca345cSEnji Cooper free_group(struct group *grp) 11608ca345cSEnji Cooper { 11708ca345cSEnji Cooper char **cp; 11808ca345cSEnji Cooper 11908ca345cSEnji Cooper ATF_REQUIRE(grp != NULL); 12008ca345cSEnji Cooper 12108ca345cSEnji Cooper free(grp->gr_name); 12208ca345cSEnji Cooper free(grp->gr_passwd); 12308ca345cSEnji Cooper 12408ca345cSEnji Cooper for (cp = grp->gr_mem; *cp; ++cp) 12508ca345cSEnji Cooper free(*cp); 12608ca345cSEnji Cooper free(grp->gr_mem); 12708ca345cSEnji Cooper } 12808ca345cSEnji Cooper 12908ca345cSEnji Cooper static int 13008ca345cSEnji Cooper compare_group(struct group *grp1, struct group *grp2, void *mdata) 13108ca345cSEnji Cooper { 13208ca345cSEnji Cooper char **c1, **c2; 13308ca345cSEnji Cooper 13408ca345cSEnji Cooper if (grp1 == grp2) 13508ca345cSEnji Cooper return (0); 13608ca345cSEnji Cooper 13708ca345cSEnji Cooper if (grp1 == NULL || grp2 == NULL) 13808ca345cSEnji Cooper goto errfin; 13908ca345cSEnji Cooper 14008ca345cSEnji Cooper if (strcmp(grp1->gr_name, grp2->gr_name) != 0 || 14108ca345cSEnji Cooper strcmp(grp1->gr_passwd, grp2->gr_passwd) != 0 || 14208ca345cSEnji Cooper grp1->gr_gid != grp2->gr_gid) 14308ca345cSEnji Cooper goto errfin; 14408ca345cSEnji Cooper 14508ca345cSEnji Cooper c1 = grp1->gr_mem; 14608ca345cSEnji Cooper c2 = grp2->gr_mem; 14708ca345cSEnji Cooper 14808ca345cSEnji Cooper if (grp1->gr_mem == NULL || grp2->gr_mem == NULL) 14908ca345cSEnji Cooper goto errfin; 15008ca345cSEnji Cooper 15108ca345cSEnji Cooper for (; *c1 && *c2; ++c1, ++c2) 15208ca345cSEnji Cooper if (strcmp(*c1, *c2) != 0) 15308ca345cSEnji Cooper goto errfin; 15408ca345cSEnji Cooper 155f1897613SBrooks Davis if (*c1 != NULL || *c2 != NULL) 15608ca345cSEnji Cooper goto errfin; 15708ca345cSEnji Cooper 15808ca345cSEnji Cooper return 0; 15908ca345cSEnji Cooper 16008ca345cSEnji Cooper errfin: 16108ca345cSEnji Cooper if (mdata == NULL) { 16208ca345cSEnji Cooper printf("following structures are not equal:\n"); 16308ca345cSEnji Cooper dump_group(grp1); 16408ca345cSEnji Cooper dump_group(grp2); 16508ca345cSEnji Cooper } 16608ca345cSEnji Cooper 16708ca345cSEnji Cooper return (-1); 16808ca345cSEnji Cooper } 16908ca345cSEnji Cooper 17008ca345cSEnji Cooper static void 17108ca345cSEnji Cooper sdump_group(struct group *grp, char *buffer, size_t buflen) 17208ca345cSEnji Cooper { 17308ca345cSEnji Cooper char **cp; 17408ca345cSEnji Cooper int written; 17508ca345cSEnji Cooper 1762d22bf63SBryan Drewery written = snprintf(buffer, buflen, "%s:%s:%d:", 17708ca345cSEnji Cooper grp->gr_name, grp->gr_passwd, grp->gr_gid); 17808ca345cSEnji Cooper buffer += written; 1794a9a8952SEnji Cooper if (written > (int)buflen) 18008ca345cSEnji Cooper return; 18108ca345cSEnji Cooper buflen -= written; 18208ca345cSEnji Cooper 18308ca345cSEnji Cooper if (grp->gr_mem != NULL) { 184f1897613SBrooks Davis if (*(grp->gr_mem) != NULL) { 18508ca345cSEnji Cooper for (cp = grp->gr_mem; *cp; ++cp) { 1862d22bf63SBryan Drewery written = snprintf(buffer, buflen, "%s%s", 1872d22bf63SBryan Drewery cp == grp->gr_mem ? "" : ",", *cp); 18808ca345cSEnji Cooper buffer += written; 1894a9a8952SEnji Cooper if (written > (int)buflen) 19008ca345cSEnji Cooper return; 19108ca345cSEnji Cooper buflen -= written; 19208ca345cSEnji Cooper 19308ca345cSEnji Cooper if (buflen == 0) 19408ca345cSEnji Cooper return; 19508ca345cSEnji Cooper } 19608ca345cSEnji Cooper } else 19708ca345cSEnji Cooper snprintf(buffer, buflen, "nomem"); 19808ca345cSEnji Cooper } else 19908ca345cSEnji Cooper snprintf(buffer, buflen, "(null)"); 20008ca345cSEnji Cooper } 20108ca345cSEnji Cooper 20208ca345cSEnji Cooper static int 20308ca345cSEnji Cooper group_read_snapshot_func(struct group *grp, char *line) 20408ca345cSEnji Cooper { 20508ca345cSEnji Cooper StringList *sl; 20608ca345cSEnji Cooper char *s, *ps, *ts; 2072d22bf63SBryan Drewery const char *sep; 20808ca345cSEnji Cooper int i; 20908ca345cSEnji Cooper 21008ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 21108ca345cSEnji Cooper 21208ca345cSEnji Cooper i = 0; 21308ca345cSEnji Cooper sl = NULL; 21408ca345cSEnji Cooper ps = line; 2152d22bf63SBryan Drewery sep = ":"; 21608ca345cSEnji Cooper memset(grp, 0, sizeof(struct group)); 2172d22bf63SBryan Drewery while ((s = strsep(&ps, sep)) != NULL) { 21808ca345cSEnji Cooper switch (i) { 21908ca345cSEnji Cooper case 0: 22008ca345cSEnji Cooper grp->gr_name = strdup(s); 22108ca345cSEnji Cooper ATF_REQUIRE(grp->gr_name != NULL); 22208ca345cSEnji Cooper break; 22308ca345cSEnji Cooper 22408ca345cSEnji Cooper case 1: 22508ca345cSEnji Cooper grp->gr_passwd = strdup(s); 22608ca345cSEnji Cooper ATF_REQUIRE(grp->gr_passwd != NULL); 22708ca345cSEnji Cooper break; 22808ca345cSEnji Cooper 22908ca345cSEnji Cooper case 2: 23008ca345cSEnji Cooper grp->gr_gid = (gid_t)strtol(s, &ts, 10); 23108ca345cSEnji Cooper if (*ts != '\0') { 23208ca345cSEnji Cooper free(grp->gr_name); 23308ca345cSEnji Cooper free(grp->gr_passwd); 23408ca345cSEnji Cooper grp->gr_name = NULL; 23508ca345cSEnji Cooper grp->gr_passwd = NULL; 23608ca345cSEnji Cooper return (-1); 23708ca345cSEnji Cooper } 2382d22bf63SBryan Drewery /* Change to parsing groups. */ 2392d22bf63SBryan Drewery sep = ","; 24008ca345cSEnji Cooper break; 24108ca345cSEnji Cooper 24208ca345cSEnji Cooper default: 24308ca345cSEnji Cooper if (sl == NULL) { 24408ca345cSEnji Cooper if (strcmp(s, "(null)") == 0) 24508ca345cSEnji Cooper return (0); 24608ca345cSEnji Cooper 24708ca345cSEnji Cooper sl = sl_init(); 24808ca345cSEnji Cooper ATF_REQUIRE(sl != NULL); 24908ca345cSEnji Cooper 25008ca345cSEnji Cooper if (strcmp(s, "nomem") != 0) { 25108ca345cSEnji Cooper ts = strdup(s); 25208ca345cSEnji Cooper ATF_REQUIRE(ts != NULL); 25308ca345cSEnji Cooper sl_add(sl, ts); 25408ca345cSEnji Cooper } 25508ca345cSEnji Cooper } else { 25608ca345cSEnji Cooper ts = strdup(s); 25708ca345cSEnji Cooper ATF_REQUIRE(ts != NULL); 25808ca345cSEnji Cooper sl_add(sl, ts); 25908ca345cSEnji Cooper } 26008ca345cSEnji Cooper break; 26108ca345cSEnji Cooper } 26208ca345cSEnji Cooper ++i; 26308ca345cSEnji Cooper } 26408ca345cSEnji Cooper 26508ca345cSEnji Cooper if (i < 3) { 26608ca345cSEnji Cooper free(grp->gr_name); 26708ca345cSEnji Cooper free(grp->gr_passwd); 26808ca345cSEnji Cooper memset(grp, 0, sizeof(struct group)); 26908ca345cSEnji Cooper return (-1); 27008ca345cSEnji Cooper } 27108ca345cSEnji Cooper 27208ca345cSEnji Cooper sl_add(sl, NULL); 27308ca345cSEnji Cooper grp->gr_mem = sl->sl_str; 27408ca345cSEnji Cooper 27508ca345cSEnji Cooper /* NOTE: is it a dirty hack or not? */ 27608ca345cSEnji Cooper free(sl); 27708ca345cSEnji Cooper return (0); 27808ca345cSEnji Cooper } 27908ca345cSEnji Cooper 28008ca345cSEnji Cooper static void 28108ca345cSEnji Cooper dump_group(struct group *result) 28208ca345cSEnji Cooper { 28308ca345cSEnji Cooper if (result != NULL) { 28408ca345cSEnji Cooper char buffer[1024]; 28508ca345cSEnji Cooper sdump_group(result, buffer, sizeof(buffer)); 28608ca345cSEnji Cooper printf("%s\n", buffer); 28708ca345cSEnji Cooper } else 28808ca345cSEnji Cooper printf("(null)\n"); 28908ca345cSEnji Cooper } 29008ca345cSEnji Cooper 29108ca345cSEnji Cooper static int 2926e411d8bSMark Johnston group_fill_test_data(struct group_test_data *td, 2936e411d8bSMark Johnston int (*cb)(struct group *, void *)) 29408ca345cSEnji Cooper { 29508ca345cSEnji Cooper struct group *grp; 296*d11904b3SAlan Somers const int limit = 1024; 297*d11904b3SAlan Somers int count = 0; 29808ca345cSEnji Cooper 29908ca345cSEnji Cooper setgroupent(1); 30008ca345cSEnji Cooper while ((grp = getgrent()) != NULL) { 3016e411d8bSMark Johnston if (group_test_correctness(grp, NULL) == 0) { 30208ca345cSEnji Cooper TEST_DATA_APPEND(group, td, grp); 3036e411d8bSMark Johnston if (cb != NULL && cb(grp, td) != 0) 30408ca345cSEnji Cooper return (-1); 3056e411d8bSMark Johnston } else { 3066e411d8bSMark Johnston return (-1); 3076e411d8bSMark Johnston } 308*d11904b3SAlan Somers if (++count >= limit) 309*d11904b3SAlan Somers break; 31008ca345cSEnji Cooper } 31108ca345cSEnji Cooper endgrent(); 31208ca345cSEnji Cooper 31308ca345cSEnji Cooper return (0); 31408ca345cSEnji Cooper } 31508ca345cSEnji Cooper 31608ca345cSEnji Cooper static int 31791c53523SEnji Cooper group_test_correctness(struct group *grp, void *mdata __unused) 31808ca345cSEnji Cooper { 31908ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 32008ca345cSEnji Cooper dump_group(grp); 32108ca345cSEnji Cooper 32208ca345cSEnji Cooper if (grp == NULL) 32308ca345cSEnji Cooper goto errfin; 32408ca345cSEnji Cooper 32508ca345cSEnji Cooper if (grp->gr_name == NULL) 32608ca345cSEnji Cooper goto errfin; 32708ca345cSEnji Cooper 32808ca345cSEnji Cooper if (grp->gr_passwd == NULL) 32908ca345cSEnji Cooper goto errfin; 33008ca345cSEnji Cooper 33108ca345cSEnji Cooper if (grp->gr_mem == NULL) 33208ca345cSEnji Cooper goto errfin; 33308ca345cSEnji Cooper 33408ca345cSEnji Cooper printf("correct\n"); 33508ca345cSEnji Cooper 33608ca345cSEnji Cooper return (0); 33708ca345cSEnji Cooper errfin: 33808ca345cSEnji Cooper printf("incorrect\n"); 33908ca345cSEnji Cooper 34008ca345cSEnji Cooper return (-1); 34108ca345cSEnji Cooper } 34208ca345cSEnji Cooper 34308ca345cSEnji Cooper /* group_check_ambiguity() is needed here because when doing the getgrent() 34408ca345cSEnji Cooper * calls sequence, records from different nsswitch sources can be different, 34508ca345cSEnji Cooper * though having the same pw_name/pw_uid */ 34608ca345cSEnji Cooper static int 34708ca345cSEnji Cooper group_check_ambiguity(struct group_test_data *td, struct group *pwd) 34808ca345cSEnji Cooper { 34908ca345cSEnji Cooper 350ed14c69dSMark Johnston return (TEST_DATA_FIND(group, td, pwd, compare_group, NULL) != 351ed14c69dSMark Johnston NULL ? 0 : -1); 35208ca345cSEnji Cooper } 35308ca345cSEnji Cooper 35408ca345cSEnji Cooper static int 35508ca345cSEnji Cooper group_test_getgrnam(struct group *grp_model, void *mdata) 35608ca345cSEnji Cooper { 35708ca345cSEnji Cooper struct group *grp; 35808ca345cSEnji Cooper 35908ca345cSEnji Cooper printf("testing getgrnam() with the following data:\n"); 36008ca345cSEnji Cooper dump_group(grp_model); 36108ca345cSEnji Cooper 36208ca345cSEnji Cooper grp = getgrnam(grp_model->gr_name); 36308ca345cSEnji Cooper if (group_test_correctness(grp, NULL) != 0) 36408ca345cSEnji Cooper goto errfin; 36508ca345cSEnji Cooper 36608ca345cSEnji Cooper if (compare_group(grp, grp_model, NULL) != 0 && 36708ca345cSEnji Cooper group_check_ambiguity((struct group_test_data *)mdata, grp) != 0) 36808ca345cSEnji Cooper goto errfin; 36908ca345cSEnji Cooper 37008ca345cSEnji Cooper return (0); 37108ca345cSEnji Cooper 37208ca345cSEnji Cooper errfin: 37308ca345cSEnji Cooper return (-1); 37408ca345cSEnji Cooper } 37508ca345cSEnji Cooper 37608ca345cSEnji Cooper static int 37708ca345cSEnji Cooper group_test_getgrgid(struct group *grp_model, void *mdata) 37808ca345cSEnji Cooper { 37908ca345cSEnji Cooper struct group *grp; 38008ca345cSEnji Cooper 38108ca345cSEnji Cooper printf("testing getgrgid() with the following data...\n"); 38208ca345cSEnji Cooper dump_group(grp_model); 38308ca345cSEnji Cooper 38408ca345cSEnji Cooper grp = getgrgid(grp_model->gr_gid); 38508ca345cSEnji Cooper if (group_test_correctness(grp, NULL) != 0 || 38608ca345cSEnji Cooper (compare_group(grp, grp_model, NULL) != 0 && 387ed14c69dSMark Johnston group_check_ambiguity((struct group_test_data *)mdata, grp) != 0)) 38808ca345cSEnji Cooper return (-1); 389ed14c69dSMark Johnston else 39008ca345cSEnji Cooper return (0); 39108ca345cSEnji Cooper } 39208ca345cSEnji Cooper 39308ca345cSEnji Cooper static int 39491c53523SEnji Cooper group_test_getgrent(struct group *grp, void *mdata __unused) 39508ca345cSEnji Cooper { 396ed14c69dSMark Johnston /* 397ed14c69dSMark Johnston * Only correctness can be checked when doing 1-pass test for 398ed14c69dSMark Johnston * getgrent(). 399ed14c69dSMark Johnston */ 40008ca345cSEnji Cooper return (group_test_correctness(grp, NULL)); 40108ca345cSEnji Cooper } 40208ca345cSEnji Cooper 40308ca345cSEnji Cooper static int 40408ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 40508ca345cSEnji Cooper { 4066e411d8bSMark Johnston struct group_test_data td, td_snap, td_2pass, td_interleaved; 40708ca345cSEnji Cooper int rv; 40808ca345cSEnji Cooper 40908ca345cSEnji Cooper TEST_DATA_INIT(group, &td, clone_group, free_group); 41008ca345cSEnji Cooper TEST_DATA_INIT(group, &td_snap, clone_group, free_group); 41108ca345cSEnji Cooper if (snapshot_file != NULL) { 41208ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 41308ca345cSEnji Cooper if (errno == ENOENT) 41408ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 41508ca345cSEnji Cooper else { 41608ca345cSEnji Cooper printf("can't access the file %s\n", 41708ca345cSEnji Cooper snapshot_file); 41808ca345cSEnji Cooper 41908ca345cSEnji Cooper rv = -1; 42008ca345cSEnji Cooper goto fin; 42108ca345cSEnji Cooper } 42208ca345cSEnji Cooper } else { 42308ca345cSEnji Cooper if (method == TEST_BUILD_SNAPSHOT) { 42408ca345cSEnji Cooper rv = 0; 42508ca345cSEnji Cooper goto fin; 42608ca345cSEnji Cooper } 42708ca345cSEnji Cooper 42808ca345cSEnji Cooper TEST_SNAPSHOT_FILE_READ(group, snapshot_file, 42908ca345cSEnji Cooper &td_snap, group_read_snapshot_func); 43008ca345cSEnji Cooper } 43108ca345cSEnji Cooper } 43208ca345cSEnji Cooper 4336e411d8bSMark Johnston rv = group_fill_test_data(&td, NULL); 43408ca345cSEnji Cooper if (rv == -1) 43508ca345cSEnji Cooper return (-1); 43608ca345cSEnji Cooper switch (method) { 43708ca345cSEnji Cooper case TEST_GETGRNAM: 43808ca345cSEnji Cooper if (snapshot_file == NULL) 43908ca345cSEnji Cooper rv = DO_1PASS_TEST(group, &td, 44008ca345cSEnji Cooper group_test_getgrnam, (void *)&td); 44108ca345cSEnji Cooper else 44208ca345cSEnji Cooper rv = DO_1PASS_TEST(group, &td_snap, 44308ca345cSEnji Cooper group_test_getgrnam, (void *)&td_snap); 44408ca345cSEnji Cooper break; 44508ca345cSEnji Cooper case TEST_GETGRGID: 44608ca345cSEnji Cooper if (snapshot_file == NULL) 44708ca345cSEnji Cooper rv = DO_1PASS_TEST(group, &td, 44808ca345cSEnji Cooper group_test_getgrgid, (void *)&td); 44908ca345cSEnji Cooper else 45008ca345cSEnji Cooper rv = DO_1PASS_TEST(group, &td_snap, 45108ca345cSEnji Cooper group_test_getgrgid, (void *)&td_snap); 45208ca345cSEnji Cooper break; 45308ca345cSEnji Cooper case TEST_GETGRENT: 45408ca345cSEnji Cooper if (snapshot_file == NULL) 45508ca345cSEnji Cooper rv = DO_1PASS_TEST(group, &td, group_test_getgrent, 45608ca345cSEnji Cooper (void *)&td); 45708ca345cSEnji Cooper else 45808ca345cSEnji Cooper rv = DO_2PASS_TEST(group, &td, &td_snap, 45908ca345cSEnji Cooper compare_group, NULL); 46008ca345cSEnji Cooper break; 46108ca345cSEnji Cooper case TEST_GETGRENT_2PASS: 46208ca345cSEnji Cooper TEST_DATA_INIT(group, &td_2pass, clone_group, free_group); 4636e411d8bSMark Johnston rv = group_fill_test_data(&td_2pass, NULL); 46408ca345cSEnji Cooper if (rv != -1) 46508ca345cSEnji Cooper rv = DO_2PASS_TEST(group, &td, &td_2pass, 46608ca345cSEnji Cooper compare_group, NULL); 46708ca345cSEnji Cooper TEST_DATA_DESTROY(group, &td_2pass); 46808ca345cSEnji Cooper break; 4696e411d8bSMark Johnston case TEST_GETGRENT_INTERLEAVED_GETGRNAM: 4706e411d8bSMark Johnston TEST_DATA_INIT(group, &td_interleaved, clone_group, free_group); 4716e411d8bSMark Johnston rv = group_fill_test_data(&td_interleaved, group_test_getgrnam); 4726e411d8bSMark Johnston if (rv != -1) 4736e411d8bSMark Johnston rv = DO_2PASS_TEST(group, &td, &td_interleaved, 4746e411d8bSMark Johnston compare_group, NULL); 4756e411d8bSMark Johnston TEST_DATA_DESTROY(group, &td_interleaved); 4766e411d8bSMark Johnston break; 4776e411d8bSMark Johnston case TEST_GETGRENT_INTERLEAVED_GETGRGID: 4786e411d8bSMark Johnston TEST_DATA_INIT(group, &td_interleaved, clone_group, free_group); 4796e411d8bSMark Johnston rv = group_fill_test_data(&td_interleaved, group_test_getgrgid); 4806e411d8bSMark Johnston if (rv != -1) 4816e411d8bSMark Johnston rv = DO_2PASS_TEST(group, &td, &td_interleaved, 4826e411d8bSMark Johnston compare_group, NULL); 4836e411d8bSMark Johnston TEST_DATA_DESTROY(group, &td_interleaved); 4846e411d8bSMark Johnston break; 48508ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 48608ca345cSEnji Cooper if (snapshot_file != NULL) 48708ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(group, snapshot_file, &td, 48808ca345cSEnji Cooper sdump_group); 48908ca345cSEnji Cooper break; 49008ca345cSEnji Cooper default: 49108ca345cSEnji Cooper rv = 0; 49208ca345cSEnji Cooper break; 49308ca345cSEnji Cooper } 49408ca345cSEnji Cooper 49508ca345cSEnji Cooper fin: 49608ca345cSEnji Cooper TEST_DATA_DESTROY(group, &td_snap); 49708ca345cSEnji Cooper TEST_DATA_DESTROY(group, &td); 49808ca345cSEnji Cooper 49908ca345cSEnji Cooper return (rv); 50008ca345cSEnji Cooper } 50108ca345cSEnji Cooper 50208ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_grp" 50308ca345cSEnji Cooper 5047532a657SEnji Cooper ATF_TC_WITHOUT_HEAD(getgrent); 50508ca345cSEnji Cooper ATF_TC_BODY(getgrent, tc) 50608ca345cSEnji Cooper { 5077abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETGRENT) == 0); 50808ca345cSEnji Cooper } 50908ca345cSEnji Cooper 51008ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getgrent_with_snapshot); 51108ca345cSEnji Cooper ATF_TC_BODY(getgrent_with_snapshot, tc) 51208ca345cSEnji Cooper { 51308ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 51408ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT) == 0); 51508ca345cSEnji Cooper } 51608ca345cSEnji Cooper 51708ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getgrent_with_two_pass); 51808ca345cSEnji Cooper ATF_TC_BODY(getgrent_with_two_pass, tc) 51908ca345cSEnji Cooper { 5207abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETGRENT_2PASS) == 0); 52108ca345cSEnji Cooper } 52208ca345cSEnji Cooper 52308ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getgrgid); 52408ca345cSEnji Cooper ATF_TC_BODY(getgrgid, tc) 52508ca345cSEnji Cooper { 5267abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETGRGID) == 0); 52708ca345cSEnji Cooper } 52808ca345cSEnji Cooper 52908ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getgrgid_with_snapshot); 53008ca345cSEnji Cooper ATF_TC_BODY(getgrgid_with_snapshot, tc) 53108ca345cSEnji Cooper { 53208ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 53308ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRGID) == 0); 53408ca345cSEnji Cooper } 53508ca345cSEnji Cooper 53608ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getgrnam); 53708ca345cSEnji Cooper ATF_TC_BODY(getgrnam, tc) 53808ca345cSEnji Cooper { 5397abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETGRNAM) == 0); 54008ca345cSEnji Cooper } 54108ca345cSEnji Cooper 54208ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getgrnam_with_snapshot); 54308ca345cSEnji Cooper ATF_TC_BODY(getgrnam_with_snapshot, tc) 54408ca345cSEnji Cooper { 54508ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 54608ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRNAM) == 0); 54708ca345cSEnji Cooper } 54808ca345cSEnji Cooper 5496e411d8bSMark Johnston ATF_TC_WITHOUT_HEAD(getgrent_interleaved_getgrnam); 5506e411d8bSMark Johnston ATF_TC_BODY(getgrent_interleaved_getgrnam, tc) 5516e411d8bSMark Johnston { 5526e411d8bSMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETGRENT_INTERLEAVED_GETGRNAM) == 0); 5536e411d8bSMark Johnston } 5546e411d8bSMark Johnston 5556e411d8bSMark Johnston ATF_TC_WITHOUT_HEAD(getgrent_interleaved_getgrgid); 5566e411d8bSMark Johnston ATF_TC_BODY(getgrent_interleaved_getgrgid, tc) 5576e411d8bSMark Johnston { 5586e411d8bSMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETGRENT_INTERLEAVED_GETGRGID) == 0); 5596e411d8bSMark Johnston } 5606e411d8bSMark Johnston 56108ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 56208ca345cSEnji Cooper { 56308ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrent); 56408ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrent_with_snapshot); 56508ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrent_with_two_pass); 56608ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrgid); 56708ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrgid_with_snapshot); 56808ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrnam); 56908ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getgrnam_with_snapshot); 5706e411d8bSMark Johnston ATF_TP_ADD_TC(tp, getgrent_interleaved_getgrnam); 5716e411d8bSMark Johnston ATF_TP_ADD_TC(tp, getgrent_interleaved_getgrgid); 57208ca345cSEnji Cooper 57308ca345cSEnji Cooper return (atf_no_error()); 57408ca345cSEnji Cooper } 575