1/***
2  This file is part of PulseAudio.
3
4  Copyright 2009 Ted Percival
5
6  PulseAudio is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as
8  published by the Free Software Foundation; either version 2.1 of the
9  License, or (at your option) any later version.
10
11  PulseAudio is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15
16  You should have received a copy of the GNU Lesser General Public
17  License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include <config.h>
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/types.h>
26#include <pwd.h>
27#include <grp.h>
28#include <errno.h>
29
30#include <check.h>
31
32#include <pulsecore/usergroup.h>
33#include <pulsecore/core-util.h>
34
35static int load_reference_structs(struct group **gr, struct passwd **pw) {
36    setpwent();
37    *pw = getpwent();
38    endpwent();
39
40    setgrent();
41    *gr = getgrent();
42    endgrent();
43
44    return (*gr && *pw) ? 0 : 1;
45}
46
47static int compare_group(const struct group *a, const struct group *b) {
48    char **amem, **bmem;
49
50    if (!pa_streq(a->gr_name, b->gr_name)) {
51        fprintf(stderr, "Group name mismatch: [%s] [%s]\n", a->gr_name, b->gr_name);
52        return 1;
53    }
54
55    if (!pa_streq(a->gr_passwd, b->gr_passwd)) {
56        fprintf(stderr, "Group password mismatch: [%s] [%s]\n", a->gr_passwd, b->gr_passwd);
57        return 1;
58    }
59
60    if (a->gr_gid != b->gr_gid) {
61        fprintf(stderr, "Gid mismatch: [%lu] [%lu]\n", (unsigned long) a->gr_gid, (unsigned long) b->gr_gid);
62        return 1;
63    }
64
65    /* XXX: Assuming the group ordering is identical. */
66    for (amem = a->gr_mem, bmem = b->gr_mem; *amem && *bmem; ++amem, ++bmem) {
67        if (!pa_streq(*amem, *bmem)) {
68            fprintf(stderr, "Group member mismatch: [%s] [%s]\n", *amem, *bmem);
69            return 1;
70        }
71    }
72
73    if (*amem || *bmem) {
74        fprintf(stderr, "Mismatched group count\n");
75        return 1;
76    }
77
78    return 0;
79}
80
81static int compare_passwd(const struct passwd *a, const struct passwd *b) {
82    if (!pa_streq(a->pw_name, b->pw_name)) {
83        fprintf(stderr, "pw_name mismatch: [%s] [%s]\n", a->pw_name, b->pw_name);
84        return 1;
85    }
86
87    if (!pa_streq(a->pw_passwd, b->pw_passwd)) {
88        fprintf(stderr, "pw_passwd mismatch: [%s] [%s]\n", a->pw_passwd, b->pw_passwd);
89        return 1;
90    }
91
92    if (a->pw_uid != b->pw_uid) {
93        fprintf(stderr, "pw_uid mismatch: [%lu] [%lu]\n", (unsigned long) a->pw_uid, (unsigned long) b->pw_uid);
94        return 1;
95    }
96
97    if (a->pw_gid != b->pw_gid) {
98        fprintf(stderr, "pw_gid mismatch: [%lu] [%lu]\n", (unsigned long) a->pw_gid, (unsigned long) b->pw_gid);
99        return 1;
100    }
101
102    if (!pa_streq(a->pw_gecos, b->pw_gecos)) {
103        fprintf(stderr, "pw_gecos mismatch: [%s] [%s]\n", a->pw_gecos, b->pw_gecos);
104        return 1;
105    }
106
107    if (!pa_streq(a->pw_dir, b->pw_dir)) {
108        fprintf(stderr, "pw_dir mismatch: [%s] [%s]\n", a->pw_dir, b->pw_dir);
109        return 1;
110    }
111
112    if (!pa_streq(a->pw_shell, b->pw_shell)) {
113        fprintf(stderr, "pw_shell mismatch: [%s] [%s]\n", a->pw_shell, b->pw_shell);
114        return 1;
115    }
116
117    return 0;
118}
119
120START_TEST (usergroup_test) {
121    struct group *gr;
122    struct passwd *pw;
123    struct group *reference_group = NULL;
124    struct passwd *reference_passwd = NULL;
125
126    fail_if(load_reference_structs(&reference_group, &reference_passwd));
127
128    errno = 0;
129    gr = pa_getgrgid_malloc(reference_group->gr_gid);
130    fail_if(compare_group(reference_group, gr));
131    pa_getgrgid_free(gr);
132
133    errno = 0;
134    gr = pa_getgrnam_malloc(reference_group->gr_name);
135    fail_if(compare_group(reference_group, gr));
136    pa_getgrnam_free(gr);
137
138    errno = 0;
139    pw = pa_getpwuid_malloc(reference_passwd->pw_uid);
140    fail_if(compare_passwd(reference_passwd, pw));
141    pa_getpwuid_free(pw);
142
143    errno = 0;
144    pw = pa_getpwnam_malloc(reference_passwd->pw_name);
145    fail_if(compare_passwd(reference_passwd, pw));
146    pa_getpwnam_free(pw);
147}
148END_TEST
149
150int main(int argc, char *argv[]) {
151    int failed = 0;
152    Suite *s;
153    TCase *tc;
154    SRunner *sr;
155
156    s = suite_create("Usergroup");
157    tc = tcase_create("usergroup");
158    tcase_add_test(tc, usergroup_test);
159    suite_add_tcase(s, tc);
160
161    sr = srunner_create(s);
162    srunner_run_all(sr, CK_NORMAL);
163    failed = srunner_ntests_failed(sr);
164    srunner_free(sr);
165
166    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
167}
168