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)
IMPLEMENT_TEST_FILE_SNAPSHOT(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
compare_passwd(struct passwd * pwd1,struct passwd * pwd2,void * mdata __unused)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
free_passwd(struct passwd * pwd)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
sdump_passwd(struct passwd * pwd,char * buffer,size_t buflen)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
dump_passwd(struct passwd * pwd)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
passwd_read_snapshot_func(struct passwd * pwd,char * line)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
passwd_fill_test_data(struct passwd_test_data * td,int (* cb)(struct passwd *,void *))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
passwd_test_correctness(struct passwd * pwd,void * mdata __unused)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
passwd_check_ambiguity(struct passwd_test_data * td,struct passwd * pwd)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
passwd_test_getpwnam(struct passwd * pwd_model,void * mdata)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
passwd_test_getpwuid(struct passwd * pwd_model,void * mdata)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
passwd_test_getpwent(struct passwd * pwd,void * mdata __unused)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
run_tests(const char * snapshot_file,enum test_methods method)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);
ATF_TC_BODY(getpwent,tc)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);
ATF_TC_BODY(getpwent_with_snapshot,tc)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);
ATF_TC_BODY(getpwent_with_two_pass,tc)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);
ATF_TC_BODY(getpwnam,tc)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);
ATF_TC_BODY(getpwnam_with_snapshot,tc)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);
ATF_TC_BODY(getpwuid,tc)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);
ATF_TC_BODY(getpwuid_with_snapshot,tc)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);
ATF_TC_BODY(getpwent_interleaved_getpwnam,tc)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);
ATF_TC_BODY(getpwent_interleaved_getpwuid,tc)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
ATF_TP_ADD_TCS(tp)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