xref: /freebsd/lib/libc/tests/nss/getusershell_test.c (revision 08ca345cfd1353f8b9f3603782e59edf79683c84)
1*08ca345cSEnji Cooper /*-
2*08ca345cSEnji Cooper  * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
3*08ca345cSEnji Cooper  * All rights reserved.
4*08ca345cSEnji Cooper  *
5*08ca345cSEnji Cooper  * Redistribution and use in source and binary forms, with or without
6*08ca345cSEnji Cooper  * modification, are permitted provided that the following conditions
7*08ca345cSEnji Cooper  * are met:
8*08ca345cSEnji Cooper  * 1. Redistributions of source code must retain the above copyright
9*08ca345cSEnji Cooper  *    notice, this list of conditions and the following disclaimer.
10*08ca345cSEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
11*08ca345cSEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
12*08ca345cSEnji Cooper  *    documentation and/or other materials provided with the distribution.
13*08ca345cSEnji Cooper  *
14*08ca345cSEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*08ca345cSEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*08ca345cSEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*08ca345cSEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*08ca345cSEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*08ca345cSEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*08ca345cSEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*08ca345cSEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*08ca345cSEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*08ca345cSEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*08ca345cSEnji Cooper  * SUCH DAMAGE.
25*08ca345cSEnji Cooper  *
26*08ca345cSEnji Cooper  */
27*08ca345cSEnji Cooper 
28*08ca345cSEnji Cooper #include <sys/cdefs.h>
29*08ca345cSEnji Cooper __FBSDID("$FreeBSD$");
30*08ca345cSEnji Cooper 
31*08ca345cSEnji Cooper #include <assert.h>
32*08ca345cSEnji Cooper #include <errno.h>
33*08ca345cSEnji Cooper #include <stdio.h>
34*08ca345cSEnji Cooper #include <stdlib.h>
35*08ca345cSEnji Cooper #include <string.h>
36*08ca345cSEnji Cooper #include <unistd.h>
37*08ca345cSEnji Cooper 
38*08ca345cSEnji Cooper #include <atf-c.h>
39*08ca345cSEnji Cooper 
40*08ca345cSEnji Cooper #include "testutil.h"
41*08ca345cSEnji Cooper 
42*08ca345cSEnji Cooper enum test_methods {
43*08ca345cSEnji Cooper 	TEST_GETUSERSHELL,
44*08ca345cSEnji Cooper 	TEST_BUILD_SNAPSHOT
45*08ca345cSEnji Cooper };
46*08ca345cSEnji Cooper 
47*08ca345cSEnji Cooper struct usershell {
48*08ca345cSEnji Cooper 	char *path;
49*08ca345cSEnji Cooper };
50*08ca345cSEnji Cooper 
51*08ca345cSEnji Cooper static enum test_methods method = TEST_GETUSERSHELL;
52*08ca345cSEnji Cooper 
53*08ca345cSEnji Cooper DECLARE_TEST_DATA(usershell)
54*08ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(usershell)
55*08ca345cSEnji Cooper DECLARE_2PASS_TEST(usershell)
56*08ca345cSEnji Cooper 
57*08ca345cSEnji Cooper static void clone_usershell(struct usershell *, struct usershell const *);
58*08ca345cSEnji Cooper static int compare_usershell(struct usershell *, struct usershell *, void *);
59*08ca345cSEnji Cooper static void free_usershell(struct usershell *);
60*08ca345cSEnji Cooper 
61*08ca345cSEnji Cooper static void sdump_usershell(struct usershell *, char *, size_t);
62*08ca345cSEnji Cooper static void dump_usershell(struct usershell *);
63*08ca345cSEnji Cooper 
64*08ca345cSEnji Cooper IMPLEMENT_TEST_DATA(usershell)
65*08ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(usershell)
66*08ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(usershell)
67*08ca345cSEnji Cooper 
68*08ca345cSEnji Cooper static void
69*08ca345cSEnji Cooper clone_usershell(struct usershell *dest, struct usershell const *src)
70*08ca345cSEnji Cooper {
71*08ca345cSEnji Cooper 	assert(dest != NULL);
72*08ca345cSEnji Cooper 	assert(src != NULL);
73*08ca345cSEnji Cooper 
74*08ca345cSEnji Cooper 	if (src->path != NULL) {
75*08ca345cSEnji Cooper 		dest->path = strdup(src->path);
76*08ca345cSEnji Cooper 		assert(dest->path != NULL);
77*08ca345cSEnji Cooper 	}
78*08ca345cSEnji Cooper }
79*08ca345cSEnji Cooper 
80*08ca345cSEnji Cooper static int
81*08ca345cSEnji Cooper compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata)
82*08ca345cSEnji Cooper {
83*08ca345cSEnji Cooper 	int rv;
84*08ca345cSEnji Cooper 
85*08ca345cSEnji Cooper 	assert(us1 != NULL);
86*08ca345cSEnji Cooper 	assert(us2 != NULL);
87*08ca345cSEnji Cooper 
88*08ca345cSEnji Cooper 	dump_usershell(us1);
89*08ca345cSEnji Cooper 	dump_usershell(us2);
90*08ca345cSEnji Cooper 
91*08ca345cSEnji Cooper 	if (us1 == us2)
92*08ca345cSEnji Cooper 		return (0);
93*08ca345cSEnji Cooper 
94*08ca345cSEnji Cooper 	rv = strcmp(us1->path, us2->path);
95*08ca345cSEnji Cooper 	if (rv != 0) {
96*08ca345cSEnji Cooper 		printf("following structures are not equal:\n");
97*08ca345cSEnji Cooper 		dump_usershell(us1);
98*08ca345cSEnji Cooper 		dump_usershell(us2);
99*08ca345cSEnji Cooper 	}
100*08ca345cSEnji Cooper 
101*08ca345cSEnji Cooper 	return (rv);
102*08ca345cSEnji Cooper }
103*08ca345cSEnji Cooper 
104*08ca345cSEnji Cooper static void
105*08ca345cSEnji Cooper free_usershell(struct usershell *us)
106*08ca345cSEnji Cooper {
107*08ca345cSEnji Cooper 	free(us->path);
108*08ca345cSEnji Cooper }
109*08ca345cSEnji Cooper 
110*08ca345cSEnji Cooper static void
111*08ca345cSEnji Cooper sdump_usershell(struct usershell *us, char *buffer, size_t buflen)
112*08ca345cSEnji Cooper {
113*08ca345cSEnji Cooper 	snprintf(buffer, buflen, "%s", us->path);
114*08ca345cSEnji Cooper }
115*08ca345cSEnji Cooper 
116*08ca345cSEnji Cooper static void
117*08ca345cSEnji Cooper dump_usershell(struct usershell *us)
118*08ca345cSEnji Cooper {
119*08ca345cSEnji Cooper 	if (us != NULL) {
120*08ca345cSEnji Cooper 		char buffer[2048];
121*08ca345cSEnji Cooper 		sdump_usershell(us, buffer, sizeof(buffer));
122*08ca345cSEnji Cooper 		printf("%s\n", buffer);
123*08ca345cSEnji Cooper 	} else
124*08ca345cSEnji Cooper 		printf("(null)\n");
125*08ca345cSEnji Cooper }
126*08ca345cSEnji Cooper 
127*08ca345cSEnji Cooper static int
128*08ca345cSEnji Cooper usershell_read_snapshot_func(struct usershell *us, char *line)
129*08ca345cSEnji Cooper {
130*08ca345cSEnji Cooper 
131*08ca345cSEnji Cooper 	us->path = strdup(line);
132*08ca345cSEnji Cooper 	ATF_REQUIRE(us->path != NULL);
133*08ca345cSEnji Cooper 
134*08ca345cSEnji Cooper 	return (0);
135*08ca345cSEnji Cooper }
136*08ca345cSEnji Cooper 
137*08ca345cSEnji Cooper int
138*08ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method)
139*08ca345cSEnji Cooper {
140*08ca345cSEnji Cooper 	struct usershell_test_data td, td_snap;
141*08ca345cSEnji Cooper 	struct usershell ushell;
142*08ca345cSEnji Cooper 	int rv;
143*08ca345cSEnji Cooper 
144*08ca345cSEnji Cooper 	rv = 0;
145*08ca345cSEnji Cooper 
146*08ca345cSEnji Cooper 	TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell);
147*08ca345cSEnji Cooper 	TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell);
148*08ca345cSEnji Cooper 
149*08ca345cSEnji Cooper 	setusershell();
150*08ca345cSEnji Cooper 	while ((ushell.path = getusershell()) != NULL) {
151*08ca345cSEnji Cooper 		printf("usershell found:\n");
152*08ca345cSEnji Cooper 		dump_usershell(&ushell);
153*08ca345cSEnji Cooper 		TEST_DATA_APPEND(usershell, &td, &ushell);
154*08ca345cSEnji Cooper 	}
155*08ca345cSEnji Cooper 	endusershell();
156*08ca345cSEnji Cooper 
157*08ca345cSEnji Cooper 	if (snapshot_file != NULL) {
158*08ca345cSEnji Cooper 		if (access(snapshot_file, W_OK | R_OK) != 0) {
159*08ca345cSEnji Cooper 			if (errno == ENOENT)
160*08ca345cSEnji Cooper 				method = TEST_BUILD_SNAPSHOT;
161*08ca345cSEnji Cooper 			else {
162*08ca345cSEnji Cooper 				printf("can't access the snapshot file %s\n",
163*08ca345cSEnji Cooper 				    snapshot_file);
164*08ca345cSEnji Cooper 
165*08ca345cSEnji Cooper 				rv = -1;
166*08ca345cSEnji Cooper 				goto fin;
167*08ca345cSEnji Cooper 			}
168*08ca345cSEnji Cooper 		} else {
169*08ca345cSEnji Cooper 			rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file,
170*08ca345cSEnji Cooper 				&td_snap, usershell_read_snapshot_func);
171*08ca345cSEnji Cooper 			if (rv != 0) {
172*08ca345cSEnji Cooper 				printf("error reading snapshot file\n");
173*08ca345cSEnji Cooper 				goto fin;
174*08ca345cSEnji Cooper 			}
175*08ca345cSEnji Cooper 		}
176*08ca345cSEnji Cooper 	}
177*08ca345cSEnji Cooper 
178*08ca345cSEnji Cooper 	switch (method) {
179*08ca345cSEnji Cooper 	case TEST_GETUSERSHELL:
180*08ca345cSEnji Cooper 		rv = DO_2PASS_TEST(usershell, &td, &td_snap,
181*08ca345cSEnji Cooper 			compare_usershell, NULL);
182*08ca345cSEnji Cooper 		break;
183*08ca345cSEnji Cooper 	case TEST_BUILD_SNAPSHOT:
184*08ca345cSEnji Cooper 		if (snapshot_file != NULL) {
185*08ca345cSEnji Cooper 			rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file,
186*08ca345cSEnji Cooper 			    &td, sdump_usershell);
187*08ca345cSEnji Cooper 		}
188*08ca345cSEnji Cooper 		break;
189*08ca345cSEnji Cooper 	default:
190*08ca345cSEnji Cooper 		rv = 0;
191*08ca345cSEnji Cooper 		break;
192*08ca345cSEnji Cooper 	}
193*08ca345cSEnji Cooper 
194*08ca345cSEnji Cooper fin:
195*08ca345cSEnji Cooper 	TEST_DATA_DESTROY(usershell, &td_snap);
196*08ca345cSEnji Cooper 	TEST_DATA_DESTROY(usershell, &td);
197*08ca345cSEnji Cooper 
198*08ca345cSEnji Cooper 	return (rv);
199*08ca345cSEnji Cooper }
200*08ca345cSEnji Cooper 
201*08ca345cSEnji Cooper #define	SNAPSHOT_FILE	"snapshot_usershell"
202*08ca345cSEnji Cooper 
203*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getusershell_with_snapshot);
204*08ca345cSEnji Cooper ATF_TC_BODY(getusershell_with_snapshot, tc)
205*08ca345cSEnji Cooper {
206*08ca345cSEnji Cooper 
207*08ca345cSEnji Cooper 	ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0);
208*08ca345cSEnji Cooper }
209*08ca345cSEnji Cooper 
210*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getusershell_with_two_pass);
211*08ca345cSEnji Cooper ATF_TC_BODY(getusershell_with_two_pass, tc)
212*08ca345cSEnji Cooper {
213*08ca345cSEnji Cooper 
214*08ca345cSEnji Cooper 	ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0);
215*08ca345cSEnji Cooper 	ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETUSERSHELL) == 0);
216*08ca345cSEnji Cooper }
217*08ca345cSEnji Cooper 
218*08ca345cSEnji Cooper ATF_TP_ADD_TCS(tp)
219*08ca345cSEnji Cooper {
220*08ca345cSEnji Cooper 
221*08ca345cSEnji Cooper 	ATF_TP_ADD_TC(tp, getusershell_with_snapshot);
222*08ca345cSEnji Cooper 	ATF_TP_ADD_TC(tp, getusershell_with_two_pass);
223*08ca345cSEnji Cooper 
224*08ca345cSEnji Cooper 	return (atf_no_error());
225*08ca345cSEnji Cooper }
226