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 <errno.h> 2908ca345cSEnji Cooper #include <pwd.h> 3008ca345cSEnji Cooper #include <stdio.h> 3108ca345cSEnji Cooper #include <stdlib.h> 3208ca345cSEnji Cooper #include <string.h> 3308ca345cSEnji Cooper #include <unistd.h> 3408ca345cSEnji Cooper 3508ca345cSEnji Cooper #include <atf-c.h> 3608ca345cSEnji Cooper 3708ca345cSEnji Cooper #include "testutil.h" 3808ca345cSEnji Cooper 3908ca345cSEnji Cooper enum test_methods { 4008ca345cSEnji Cooper TEST_GETPWENT, 416e411d8bSMark Johnston TEST_GETPWENT_INTERLEAVED_GETPWNAM, 426e411d8bSMark Johnston TEST_GETPWENT_INTERLEAVED_GETPWUID, 4308ca345cSEnji Cooper TEST_GETPWNAM, 4408ca345cSEnji Cooper TEST_GETPWUID, 4508ca345cSEnji Cooper TEST_GETPWENT_2PASS, 4608ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 4708ca345cSEnji Cooper }; 4808ca345cSEnji Cooper 4908ca345cSEnji Cooper DECLARE_TEST_DATA(passwd) 5008ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(passwd) 5108ca345cSEnji Cooper DECLARE_1PASS_TEST(passwd) 5208ca345cSEnji Cooper DECLARE_2PASS_TEST(passwd) 5308ca345cSEnji Cooper 5408ca345cSEnji Cooper static void clone_passwd(struct passwd *, struct passwd const *); 5508ca345cSEnji Cooper static int compare_passwd(struct passwd *, struct passwd *, void *); 5608ca345cSEnji Cooper static void free_passwd(struct passwd *); 5708ca345cSEnji Cooper 5808ca345cSEnji Cooper static void sdump_passwd(struct passwd *, char *, size_t); 5987a9deedSEnji Cooper #ifdef DEBUG 6008ca345cSEnji Cooper static void dump_passwd(struct passwd *); 6187a9deedSEnji Cooper #endif 6208ca345cSEnji Cooper 6308ca345cSEnji Cooper static int passwd_read_snapshot_func(struct passwd *, char *); 6408ca345cSEnji Cooper 6508ca345cSEnji Cooper static int passwd_check_ambiguity(struct passwd_test_data *, struct passwd *); 666e411d8bSMark Johnston static int passwd_fill_test_data(struct passwd_test_data *, 676e411d8bSMark Johnston int (*cb)(struct passwd *, void *)); 6808ca345cSEnji Cooper static int passwd_test_correctness(struct passwd *, void *); 6908ca345cSEnji Cooper static int passwd_test_getpwnam(struct passwd *, void *); 7008ca345cSEnji Cooper static int passwd_test_getpwuid(struct passwd *, void *); 7108ca345cSEnji Cooper static int passwd_test_getpwent(struct passwd *, void *); 7208ca345cSEnji Cooper 7308ca345cSEnji Cooper IMPLEMENT_TEST_DATA(passwd) 7408ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(passwd) 7508ca345cSEnji Cooper IMPLEMENT_1PASS_TEST(passwd) 7608ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(passwd) 7708ca345cSEnji Cooper 7808ca345cSEnji Cooper static void 7908ca345cSEnji Cooper clone_passwd(struct passwd *dest, struct passwd const *src) 8008ca345cSEnji Cooper { 8108ca345cSEnji Cooper ATF_REQUIRE(dest != NULL); 8208ca345cSEnji Cooper ATF_REQUIRE(src != NULL); 8308ca345cSEnji Cooper 8408ca345cSEnji Cooper memcpy(dest, src, sizeof(struct passwd)); 8508ca345cSEnji Cooper if (src->pw_name != NULL) 8608ca345cSEnji Cooper dest->pw_name = strdup(src->pw_name); 8708ca345cSEnji Cooper if (src->pw_passwd != NULL) 8808ca345cSEnji Cooper dest->pw_passwd = strdup(src->pw_passwd); 8908ca345cSEnji Cooper if (src->pw_class != NULL) 9008ca345cSEnji Cooper dest->pw_class = strdup(src->pw_class); 9108ca345cSEnji Cooper if (src->pw_gecos != NULL) 9208ca345cSEnji Cooper dest->pw_gecos = strdup(src->pw_gecos); 9308ca345cSEnji Cooper if (src->pw_dir != NULL) 9408ca345cSEnji Cooper dest->pw_dir = strdup(src->pw_dir); 9508ca345cSEnji Cooper if (src->pw_shell != NULL) 9608ca345cSEnji Cooper dest->pw_shell = strdup(dest->pw_shell); 9708ca345cSEnji Cooper } 9808ca345cSEnji Cooper 9908ca345cSEnji Cooper static int 10087a9deedSEnji Cooper compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata __unused) 10108ca345cSEnji Cooper { 10208ca345cSEnji Cooper ATF_REQUIRE(pwd1 != NULL); 10308ca345cSEnji Cooper ATF_REQUIRE(pwd2 != NULL); 10408ca345cSEnji Cooper 10508ca345cSEnji Cooper if (pwd1 == pwd2) 10608ca345cSEnji Cooper return (0); 10708ca345cSEnji Cooper 10808ca345cSEnji Cooper if (pwd1->pw_uid != pwd2->pw_uid || 10908ca345cSEnji Cooper pwd1->pw_gid != pwd2->pw_gid || 11008ca345cSEnji Cooper pwd1->pw_change != pwd2->pw_change || 11108ca345cSEnji Cooper pwd1->pw_expire != pwd2->pw_expire || 11208ca345cSEnji Cooper pwd1->pw_fields != pwd2->pw_fields || 11308ca345cSEnji Cooper strcmp(pwd1->pw_name, pwd2->pw_name) != 0 || 11408ca345cSEnji Cooper strcmp(pwd1->pw_passwd, pwd2->pw_passwd) != 0 || 11508ca345cSEnji Cooper strcmp(pwd1->pw_class, pwd2->pw_class) != 0 || 11608ca345cSEnji Cooper strcmp(pwd1->pw_gecos, pwd2->pw_gecos) != 0 || 11708ca345cSEnji Cooper strcmp(pwd1->pw_dir, pwd2->pw_dir) != 0 || 11808ca345cSEnji Cooper strcmp(pwd1->pw_shell, pwd2->pw_shell) != 0) 11908ca345cSEnji Cooper return (-1); 12008ca345cSEnji Cooper else 12108ca345cSEnji Cooper return (0); 12208ca345cSEnji Cooper } 12308ca345cSEnji Cooper 12408ca345cSEnji Cooper static void 12508ca345cSEnji Cooper free_passwd(struct passwd *pwd) 12608ca345cSEnji Cooper { 12708ca345cSEnji Cooper free(pwd->pw_name); 12808ca345cSEnji Cooper free(pwd->pw_passwd); 12908ca345cSEnji Cooper free(pwd->pw_class); 13008ca345cSEnji Cooper free(pwd->pw_gecos); 13108ca345cSEnji Cooper free(pwd->pw_dir); 13208ca345cSEnji Cooper free(pwd->pw_shell); 13308ca345cSEnji Cooper } 13408ca345cSEnji Cooper 13508ca345cSEnji Cooper static void 13608ca345cSEnji Cooper sdump_passwd(struct passwd *pwd, char *buffer, size_t buflen) 13708ca345cSEnji Cooper { 13808ca345cSEnji Cooper snprintf(buffer, buflen, "%s:%s:%d:%d:%jd:%s:%s:%s:%s:%jd:%d", 13908ca345cSEnji Cooper pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, 14008ca345cSEnji Cooper (uintmax_t)pwd->pw_change, pwd->pw_class, pwd->pw_gecos, 14108ca345cSEnji Cooper pwd->pw_dir, pwd->pw_shell, (uintmax_t)pwd->pw_expire, 14208ca345cSEnji Cooper pwd->pw_fields); 14308ca345cSEnji Cooper } 14408ca345cSEnji Cooper 14587a9deedSEnji Cooper #ifdef DEBUG 14608ca345cSEnji Cooper static void 14708ca345cSEnji Cooper dump_passwd(struct passwd *pwd) 14808ca345cSEnji Cooper { 14908ca345cSEnji Cooper if (pwd != NULL) { 15008ca345cSEnji Cooper char buffer[2048]; 15108ca345cSEnji Cooper sdump_passwd(pwd, buffer, sizeof(buffer)); 15208ca345cSEnji Cooper printf("%s\n", buffer); 15308ca345cSEnji Cooper } else 15408ca345cSEnji Cooper printf("(null)\n"); 15508ca345cSEnji Cooper } 15687a9deedSEnji Cooper #endif 15708ca345cSEnji Cooper 15808ca345cSEnji Cooper static int 15908ca345cSEnji Cooper passwd_read_snapshot_func(struct passwd *pwd, char *line) 16008ca345cSEnji Cooper { 16108ca345cSEnji Cooper char *s, *ps, *ts; 16208ca345cSEnji Cooper int i; 16308ca345cSEnji Cooper 16408ca345cSEnji Cooper #ifdef DEBUG 16508ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 16608ca345cSEnji Cooper #endif 16708ca345cSEnji Cooper 16808ca345cSEnji Cooper i = 0; 16908ca345cSEnji Cooper ps = line; 17008ca345cSEnji Cooper memset(pwd, 0, sizeof(struct passwd)); 17108ca345cSEnji Cooper while ((s = strsep(&ps, ":")) != NULL) { 17208ca345cSEnji Cooper switch (i) { 17308ca345cSEnji Cooper case 0: 17408ca345cSEnji Cooper pwd->pw_name = strdup(s); 17508ca345cSEnji Cooper ATF_REQUIRE(pwd->pw_name != NULL); 17608ca345cSEnji Cooper break; 17708ca345cSEnji Cooper case 1: 17808ca345cSEnji Cooper pwd->pw_passwd = strdup(s); 17908ca345cSEnji Cooper ATF_REQUIRE(pwd->pw_passwd != NULL); 18008ca345cSEnji Cooper break; 18108ca345cSEnji Cooper case 2: 18208ca345cSEnji Cooper pwd->pw_uid = (uid_t)strtol(s, &ts, 10); 18308ca345cSEnji Cooper if (*ts != '\0') 18408ca345cSEnji Cooper goto fin; 18508ca345cSEnji Cooper break; 18608ca345cSEnji Cooper case 3: 18708ca345cSEnji Cooper pwd->pw_gid = (gid_t)strtol(s, &ts, 10); 18808ca345cSEnji Cooper if (*ts != '\0') 18908ca345cSEnji Cooper goto fin; 19008ca345cSEnji Cooper break; 19108ca345cSEnji Cooper case 4: 19208ca345cSEnji Cooper pwd->pw_change = (time_t)strtol(s, &ts, 10); 19308ca345cSEnji Cooper if (*ts != '\0') 19408ca345cSEnji Cooper goto fin; 19508ca345cSEnji Cooper break; 19608ca345cSEnji Cooper case 5: 19708ca345cSEnji Cooper pwd->pw_class = strdup(s); 19808ca345cSEnji Cooper ATF_REQUIRE(pwd->pw_class != NULL); 19908ca345cSEnji Cooper break; 20008ca345cSEnji Cooper case 6: 20108ca345cSEnji Cooper pwd->pw_gecos = strdup(s); 20208ca345cSEnji Cooper ATF_REQUIRE(pwd->pw_gecos != NULL); 20308ca345cSEnji Cooper break; 20408ca345cSEnji Cooper case 7: 20508ca345cSEnji Cooper pwd->pw_dir = strdup(s); 20608ca345cSEnji Cooper ATF_REQUIRE(pwd->pw_dir != NULL); 20708ca345cSEnji Cooper break; 20808ca345cSEnji Cooper case 8: 20908ca345cSEnji Cooper pwd->pw_shell = strdup(s); 21008ca345cSEnji Cooper ATF_REQUIRE(pwd->pw_shell != NULL); 21108ca345cSEnji Cooper break; 21208ca345cSEnji Cooper case 9: 21308ca345cSEnji Cooper pwd->pw_expire = (time_t)strtol(s, &ts, 10); 21408ca345cSEnji Cooper if (*ts != '\0') 21508ca345cSEnji Cooper goto fin; 21608ca345cSEnji Cooper break; 21708ca345cSEnji Cooper case 10: 21808ca345cSEnji Cooper pwd->pw_fields = (int)strtol(s, &ts, 10); 21908ca345cSEnji Cooper if (*ts != '\0') 22008ca345cSEnji Cooper goto fin; 22108ca345cSEnji Cooper break; 22208ca345cSEnji Cooper default: 22308ca345cSEnji Cooper break; 22408ca345cSEnji Cooper } 22508ca345cSEnji Cooper ++i; 22608ca345cSEnji Cooper } 22708ca345cSEnji Cooper 22808ca345cSEnji Cooper fin: 22908ca345cSEnji Cooper if (i != 11) { 23008ca345cSEnji Cooper free_passwd(pwd); 23108ca345cSEnji Cooper memset(pwd, 0, sizeof(struct passwd)); 23208ca345cSEnji Cooper return (-1); 23308ca345cSEnji Cooper } 23408ca345cSEnji Cooper 23508ca345cSEnji Cooper return (0); 23608ca345cSEnji Cooper } 23708ca345cSEnji Cooper 23808ca345cSEnji Cooper static int 2396e411d8bSMark Johnston passwd_fill_test_data(struct passwd_test_data *td, 2406e411d8bSMark Johnston int (*cb)(struct passwd *, void *)) 24108ca345cSEnji Cooper { 24208ca345cSEnji Cooper struct passwd *pwd; 243*d11904b3SAlan Somers const int limit = 1024; 244*d11904b3SAlan Somers int count = 0; 24508ca345cSEnji Cooper 24608ca345cSEnji Cooper setpassent(1); 24708ca345cSEnji Cooper while ((pwd = getpwent()) != NULL) { 2486e411d8bSMark Johnston if (passwd_test_correctness(pwd, NULL) == 0) { 24908ca345cSEnji Cooper TEST_DATA_APPEND(passwd, td, pwd); 2506e411d8bSMark Johnston if (cb != NULL && cb(pwd, td) != 0) 25108ca345cSEnji Cooper return (-1); 2526e411d8bSMark Johnston } else { 2536e411d8bSMark Johnston return (-1); 2546e411d8bSMark Johnston } 255*d11904b3SAlan Somers if (++count >= limit) 256*d11904b3SAlan Somers break; 25708ca345cSEnji Cooper } 25808ca345cSEnji Cooper endpwent(); 25908ca345cSEnji Cooper 26008ca345cSEnji Cooper return (0); 26108ca345cSEnji Cooper } 26208ca345cSEnji Cooper 26308ca345cSEnji Cooper static int 26487a9deedSEnji Cooper passwd_test_correctness(struct passwd *pwd, void *mdata __unused) 26508ca345cSEnji Cooper { 26608ca345cSEnji Cooper 26708ca345cSEnji Cooper #ifdef DEBUG 26808ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 26908ca345cSEnji Cooper dump_passwd(pwd); 27008ca345cSEnji Cooper #endif 27108ca345cSEnji Cooper 27208ca345cSEnji Cooper if (pwd == NULL) 27308ca345cSEnji Cooper return (-1); 27408ca345cSEnji Cooper 27508ca345cSEnji Cooper if (pwd->pw_name == NULL) 27608ca345cSEnji Cooper goto errfin; 27708ca345cSEnji Cooper 27808ca345cSEnji Cooper if (pwd->pw_passwd == NULL) 27908ca345cSEnji Cooper goto errfin; 28008ca345cSEnji Cooper 28108ca345cSEnji Cooper if (pwd->pw_class == NULL) 28208ca345cSEnji Cooper goto errfin; 28308ca345cSEnji Cooper 28408ca345cSEnji Cooper if (pwd->pw_gecos == NULL) 28508ca345cSEnji Cooper goto errfin; 28608ca345cSEnji Cooper 28708ca345cSEnji Cooper if (pwd->pw_dir == NULL) 28808ca345cSEnji Cooper goto errfin; 28908ca345cSEnji Cooper 29008ca345cSEnji Cooper if (pwd->pw_shell == NULL) 29108ca345cSEnji Cooper goto errfin; 29208ca345cSEnji Cooper 29308ca345cSEnji Cooper #ifdef DEBUG 29408ca345cSEnji Cooper printf("correct\n"); 29508ca345cSEnji Cooper #endif 29608ca345cSEnji Cooper 29708ca345cSEnji Cooper return (0); 29808ca345cSEnji Cooper errfin: 29908ca345cSEnji Cooper #ifdef DEBUG 30008ca345cSEnji Cooper printf("incorrect\n"); 30108ca345cSEnji Cooper #endif 30208ca345cSEnji Cooper 30308ca345cSEnji Cooper return (-1); 30408ca345cSEnji Cooper } 30508ca345cSEnji Cooper 30608ca345cSEnji Cooper /* passwd_check_ambiguity() is needed here because when doing the getpwent() 30708ca345cSEnji Cooper * calls sequence, records from different nsswitch sources can be different, 30808ca345cSEnji Cooper * though having the same pw_name/pw_uid */ 30908ca345cSEnji Cooper static int 31008ca345cSEnji Cooper passwd_check_ambiguity(struct passwd_test_data *td, struct passwd *pwd) 31108ca345cSEnji Cooper { 31208ca345cSEnji Cooper 313ed14c69dSMark Johnston return (TEST_DATA_FIND(passwd, td, pwd, compare_passwd, NULL) != 314ed14c69dSMark Johnston NULL ? 0 : -1); 31508ca345cSEnji Cooper } 31608ca345cSEnji Cooper 31708ca345cSEnji Cooper static int 31808ca345cSEnji Cooper passwd_test_getpwnam(struct passwd *pwd_model, void *mdata) 31908ca345cSEnji Cooper { 32008ca345cSEnji Cooper struct passwd *pwd; 32108ca345cSEnji Cooper 32208ca345cSEnji Cooper #ifdef DEBUG 32308ca345cSEnji Cooper printf("testing getpwnam() with the following data:\n"); 32408ca345cSEnji Cooper dump_passwd(pwd_model); 32508ca345cSEnji Cooper #endif 32608ca345cSEnji Cooper 32708ca345cSEnji Cooper pwd = getpwnam(pwd_model->pw_name); 32808ca345cSEnji Cooper if (passwd_test_correctness(pwd, NULL) != 0) 32908ca345cSEnji Cooper goto errfin; 33008ca345cSEnji Cooper 331ed14c69dSMark Johnston if (compare_passwd(pwd, pwd_model, NULL) != 0 && 332ed14c69dSMark Johnston passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) != 0) 33308ca345cSEnji Cooper goto errfin; 33408ca345cSEnji Cooper 33508ca345cSEnji Cooper #ifdef DEBUG 33608ca345cSEnji Cooper printf("ok\n"); 33708ca345cSEnji Cooper #endif 33808ca345cSEnji Cooper return (0); 33908ca345cSEnji Cooper 34008ca345cSEnji Cooper errfin: 34108ca345cSEnji Cooper #ifdef DEBUG 34208ca345cSEnji Cooper printf("not ok\n"); 34308ca345cSEnji Cooper #endif 34408ca345cSEnji Cooper return (-1); 34508ca345cSEnji Cooper } 34608ca345cSEnji Cooper 34708ca345cSEnji Cooper static int 34808ca345cSEnji Cooper passwd_test_getpwuid(struct passwd *pwd_model, void *mdata) 34908ca345cSEnji Cooper { 35008ca345cSEnji Cooper struct passwd *pwd; 35108ca345cSEnji Cooper 35208ca345cSEnji Cooper #ifdef DEBUG 35308ca345cSEnji Cooper printf("testing getpwuid() with the following data...\n"); 35408ca345cSEnji Cooper dump_passwd(pwd_model); 35508ca345cSEnji Cooper #endif 35608ca345cSEnji Cooper 35708ca345cSEnji Cooper pwd = getpwuid(pwd_model->pw_uid); 358ed14c69dSMark Johnston if (passwd_test_correctness(pwd, NULL) != 0 || 359ed14c69dSMark Johnston (compare_passwd(pwd, pwd_model, NULL) != 0 && 360ed14c69dSMark Johnston passwd_check_ambiguity((struct passwd_test_data *)mdata, 361ed14c69dSMark Johnston pwd) != 0)) { 36208ca345cSEnji Cooper #ifdef DEBUG 36308ca345cSEnji Cooper printf("not ok\n"); 36408ca345cSEnji Cooper #endif 36508ca345cSEnji Cooper return (-1); 36608ca345cSEnji Cooper } else { 36708ca345cSEnji Cooper #ifdef DEBUG 36808ca345cSEnji Cooper printf("ok\n"); 36908ca345cSEnji Cooper #endif 37008ca345cSEnji Cooper return (0); 37108ca345cSEnji Cooper } 37208ca345cSEnji Cooper } 37308ca345cSEnji Cooper 37408ca345cSEnji Cooper static int 37587a9deedSEnji Cooper passwd_test_getpwent(struct passwd *pwd, void *mdata __unused) 37608ca345cSEnji Cooper { 377ed14c69dSMark Johnston /* 378ed14c69dSMark Johnston * Only correctness can be checked when doing 1-pass test for 379ed14c69dSMark Johnston * getpwent(). 380ed14c69dSMark Johnston */ 38108ca345cSEnji Cooper return (passwd_test_correctness(pwd, NULL)); 38208ca345cSEnji Cooper } 38308ca345cSEnji Cooper 38408ca345cSEnji Cooper static int 38508ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 38608ca345cSEnji Cooper { 3876e411d8bSMark Johnston struct passwd_test_data td, td_snap, td_2pass, td_interleaved; 38808ca345cSEnji Cooper int rv; 38908ca345cSEnji Cooper 39008ca345cSEnji Cooper TEST_DATA_INIT(passwd, &td, clone_passwd, free_passwd); 39108ca345cSEnji Cooper TEST_DATA_INIT(passwd, &td_snap, clone_passwd, free_passwd); 39208ca345cSEnji Cooper if (snapshot_file != NULL) { 39308ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 39408ca345cSEnji Cooper if (errno == ENOENT) 39508ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 39608ca345cSEnji Cooper else { 39708ca345cSEnji Cooper printf("can't access the file %s\n", 39808ca345cSEnji Cooper snapshot_file); 39908ca345cSEnji Cooper rv = -1; 40008ca345cSEnji Cooper goto fin; 40108ca345cSEnji Cooper } 40208ca345cSEnji Cooper } else { 40308ca345cSEnji Cooper if (method == TEST_BUILD_SNAPSHOT) { 40408ca345cSEnji Cooper rv = 0; 40508ca345cSEnji Cooper goto fin; 40608ca345cSEnji Cooper } 40708ca345cSEnji Cooper 40808ca345cSEnji Cooper TEST_SNAPSHOT_FILE_READ(passwd, snapshot_file, 40908ca345cSEnji Cooper &td_snap, passwd_read_snapshot_func); 41008ca345cSEnji Cooper } 41108ca345cSEnji Cooper } 41208ca345cSEnji Cooper 4136e411d8bSMark Johnston rv = passwd_fill_test_data(&td, NULL); 41408ca345cSEnji Cooper if (rv == -1) 41508ca345cSEnji Cooper return (-1); 41608ca345cSEnji Cooper 41708ca345cSEnji Cooper switch (method) { 41808ca345cSEnji Cooper case TEST_GETPWNAM: 41908ca345cSEnji Cooper if (snapshot_file == NULL) 42008ca345cSEnji Cooper rv = DO_1PASS_TEST(passwd, &td, 42108ca345cSEnji Cooper passwd_test_getpwnam, (void *)&td); 42208ca345cSEnji Cooper else 42308ca345cSEnji Cooper rv = DO_1PASS_TEST(passwd, &td_snap, 42408ca345cSEnji Cooper passwd_test_getpwnam, (void *)&td_snap); 42508ca345cSEnji Cooper break; 42608ca345cSEnji Cooper case TEST_GETPWUID: 42708ca345cSEnji Cooper if (snapshot_file == NULL) 42808ca345cSEnji Cooper rv = DO_1PASS_TEST(passwd, &td, 42908ca345cSEnji Cooper passwd_test_getpwuid, (void *)&td); 43008ca345cSEnji Cooper else 43108ca345cSEnji Cooper rv = DO_1PASS_TEST(passwd, &td_snap, 43208ca345cSEnji Cooper passwd_test_getpwuid, (void *)&td_snap); 43308ca345cSEnji Cooper break; 43408ca345cSEnji Cooper case TEST_GETPWENT: 43508ca345cSEnji Cooper if (snapshot_file == NULL) 43608ca345cSEnji Cooper rv = DO_1PASS_TEST(passwd, &td, passwd_test_getpwent, 43708ca345cSEnji Cooper (void *)&td); 43808ca345cSEnji Cooper else 43908ca345cSEnji Cooper rv = DO_2PASS_TEST(passwd, &td, &td_snap, 44008ca345cSEnji Cooper compare_passwd, NULL); 44108ca345cSEnji Cooper break; 44208ca345cSEnji Cooper case TEST_GETPWENT_2PASS: 44308ca345cSEnji Cooper TEST_DATA_INIT(passwd, &td_2pass, clone_passwd, free_passwd); 4446e411d8bSMark Johnston rv = passwd_fill_test_data(&td_2pass, NULL); 44508ca345cSEnji Cooper if (rv != -1) 44608ca345cSEnji Cooper rv = DO_2PASS_TEST(passwd, &td, &td_2pass, 44708ca345cSEnji Cooper compare_passwd, NULL); 44808ca345cSEnji Cooper TEST_DATA_DESTROY(passwd, &td_2pass); 44908ca345cSEnji Cooper break; 4506e411d8bSMark Johnston case TEST_GETPWENT_INTERLEAVED_GETPWNAM: 4516e411d8bSMark Johnston TEST_DATA_INIT(passwd, &td_interleaved, clone_passwd, free_passwd); 4526e411d8bSMark Johnston rv = passwd_fill_test_data(&td_interleaved, passwd_test_getpwnam); 4536e411d8bSMark Johnston if (rv != -1) 4546e411d8bSMark Johnston rv = DO_2PASS_TEST(passwd, &td, &td_interleaved, 4556e411d8bSMark Johnston compare_passwd, NULL); 4566e411d8bSMark Johnston TEST_DATA_DESTROY(passwd, &td_interleaved); 4576e411d8bSMark Johnston break; 4586e411d8bSMark Johnston case TEST_GETPWENT_INTERLEAVED_GETPWUID: 4596e411d8bSMark Johnston TEST_DATA_INIT(passwd, &td_interleaved, clone_passwd, free_passwd); 4606e411d8bSMark Johnston rv = passwd_fill_test_data(&td_interleaved, passwd_test_getpwuid); 4616e411d8bSMark Johnston if (rv != -1) 4626e411d8bSMark Johnston rv = DO_2PASS_TEST(passwd, &td, &td_interleaved, 4636e411d8bSMark Johnston compare_passwd, NULL); 4646e411d8bSMark Johnston TEST_DATA_DESTROY(passwd, &td_interleaved); 4656e411d8bSMark Johnston break; 46608ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 46708ca345cSEnji Cooper if (snapshot_file != NULL) 46808ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(passwd, snapshot_file, 46908ca345cSEnji Cooper &td, sdump_passwd); 47008ca345cSEnji Cooper break; 47108ca345cSEnji Cooper default: 47208ca345cSEnji Cooper rv = 0; 47308ca345cSEnji Cooper break; 47408ca345cSEnji Cooper } 47508ca345cSEnji Cooper 47608ca345cSEnji Cooper fin: 47708ca345cSEnji Cooper TEST_DATA_DESTROY(passwd, &td_snap); 47808ca345cSEnji Cooper TEST_DATA_DESTROY(passwd, &td); 47908ca345cSEnji Cooper 48008ca345cSEnji Cooper return (rv); 48108ca345cSEnji Cooper } 48208ca345cSEnji Cooper 48308ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_pwd" 48408ca345cSEnji Cooper 48508ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwent); 48608ca345cSEnji Cooper ATF_TC_BODY(getpwent, tc) 48708ca345cSEnji Cooper { 4887abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETPWENT) == 0); 48908ca345cSEnji Cooper } 49008ca345cSEnji Cooper 49108ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwent_with_snapshot); 49208ca345cSEnji Cooper ATF_TC_BODY(getpwent_with_snapshot, tc) 49308ca345cSEnji Cooper { 49408ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 49508ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT) == 0); 49608ca345cSEnji Cooper } 49708ca345cSEnji Cooper 49808ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwent_with_two_pass); 49908ca345cSEnji Cooper ATF_TC_BODY(getpwent_with_two_pass, tc) 50008ca345cSEnji Cooper { 5017abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETPWENT_2PASS) == 0); 50208ca345cSEnji Cooper } 50308ca345cSEnji Cooper 50408ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwnam); 50508ca345cSEnji Cooper ATF_TC_BODY(getpwnam, tc) 50608ca345cSEnji Cooper { 5077abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETPWNAM) == 0); 50808ca345cSEnji Cooper } 50908ca345cSEnji Cooper 51008ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwnam_with_snapshot); 51108ca345cSEnji Cooper ATF_TC_BODY(getpwnam_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_GETPWNAM) == 0); 51508ca345cSEnji Cooper } 51608ca345cSEnji Cooper 51708ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwuid); 51808ca345cSEnji Cooper ATF_TC_BODY(getpwuid, tc) 51908ca345cSEnji Cooper { 5207abc1009SMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETPWUID) == 0); 52108ca345cSEnji Cooper } 52208ca345cSEnji Cooper 52308ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getpwuid_with_snapshot); 52408ca345cSEnji Cooper ATF_TC_BODY(getpwuid_with_snapshot, tc) 52508ca345cSEnji Cooper { 52608ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 52708ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWUID) == 0); 52808ca345cSEnji Cooper } 52908ca345cSEnji Cooper 5306e411d8bSMark Johnston ATF_TC_WITHOUT_HEAD(getpwent_interleaved_getpwnam); 5316e411d8bSMark Johnston ATF_TC_BODY(getpwent_interleaved_getpwnam, tc) 5326e411d8bSMark Johnston { 5336e411d8bSMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETPWENT_INTERLEAVED_GETPWNAM) == 0); 5346e411d8bSMark Johnston } 5356e411d8bSMark Johnston 5366e411d8bSMark Johnston ATF_TC_WITHOUT_HEAD(getpwent_interleaved_getpwuid); 5376e411d8bSMark Johnston ATF_TC_BODY(getpwent_interleaved_getpwuid, tc) 5386e411d8bSMark Johnston { 5396e411d8bSMark Johnston ATF_REQUIRE(run_tests(NULL, TEST_GETPWENT_INTERLEAVED_GETPWUID) == 0); 5406e411d8bSMark Johnston } 5416e411d8bSMark Johnston 54208ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 54308ca345cSEnji Cooper { 54408ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwent); 54508ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwent_with_snapshot); 54608ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwent_with_two_pass); 54708ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwnam); 54808ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwnam_with_snapshot); 54908ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwuid); 55008ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getpwuid_with_snapshot); 5516e411d8bSMark Johnston ATF_TP_ADD_TC(tp, getpwent_interleaved_getpwnam); 5526e411d8bSMark Johnston ATF_TP_ADD_TC(tp, getpwent_interleaved_getpwuid); 55308ca345cSEnji Cooper 55408ca345cSEnji Cooper return (atf_no_error()); 55508ca345cSEnji Cooper } 556