Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2014 Red Hat
6 :
7 : SSSD tests: User utilities
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <sys/types.h>
24 : #include <sys/stat.h>
25 : #include <fcntl.h>
26 : #include <talloc.h>
27 :
28 : #include <popt.h>
29 : #include "util/util.h"
30 : #include "responder/common/responder.h"
31 : #include "tests/cmocka/common_mock.h"
32 :
33 : /* Just to satisfy dependencies */
34 0 : struct cli_protocol_version *register_cli_protocol_version(void)
35 : {
36 : static struct cli_protocol_version responder_test_cli_protocol_version[] = {
37 : {0, NULL, NULL}
38 : };
39 :
40 0 : return responder_test_cli_protocol_version;
41 : }
42 :
43 1 : void test_uid_csv_to_uid_list(void **state)
44 : {
45 : TALLOC_CTX *tmp_ctx;
46 : errno_t ret;
47 : size_t count;
48 : uid_t *list;
49 :
50 1 : tmp_ctx = talloc_new(global_talloc_context);
51 1 : assert_non_null(tmp_ctx);
52 :
53 1 : check_leaks_push(tmp_ctx);
54 :
55 1 : ret = csv_string_to_uid_array(tmp_ctx, "1, 2, 3", false, &count, &list);
56 1 : assert_int_equal(ret, EOK);
57 1 : assert_int_equal(count, 3);
58 1 : assert_int_equal(list[0], 1);
59 1 : assert_int_equal(list[1], 2);
60 1 : assert_int_equal(list[2], 3);
61 :
62 1 : talloc_free(list);
63 1 : check_leaks_pop(tmp_ctx);
64 1 : talloc_free(tmp_ctx);
65 1 : }
66 :
67 1 : void test_name_csv_to_uid_list(void **state)
68 : {
69 : TALLOC_CTX *tmp_ctx;
70 : errno_t ret;
71 : size_t count;
72 : uid_t *list;
73 :
74 1 : tmp_ctx = talloc_new(global_talloc_context);
75 1 : assert_non_null(tmp_ctx);
76 :
77 1 : check_leaks_push(tmp_ctx);
78 :
79 1 : ret = csv_string_to_uid_array(tmp_ctx, "sssd, foobar", true, &count, &list);
80 1 : assert_int_equal(ret, EOK);
81 1 : assert_int_equal(count, 2);
82 1 : assert_int_equal(list[0], 123);
83 1 : assert_int_equal(list[1], 10001);
84 :
85 1 : talloc_free(list);
86 1 : check_leaks_pop(tmp_ctx);
87 1 : talloc_free(tmp_ctx);
88 1 : }
89 :
90 1 : void test_csv_to_uid_list_neg(void **state)
91 : {
92 : TALLOC_CTX *tmp_ctx;
93 : errno_t ret;
94 : size_t count;
95 1 : uid_t *list = NULL;
96 :
97 1 : tmp_ctx = talloc_new(global_talloc_context);
98 1 : assert_non_null(tmp_ctx);
99 :
100 1 : check_leaks_push(tmp_ctx);
101 :
102 1 : ret = csv_string_to_uid_array(tmp_ctx, "nosuchuser", true, &count, &list);
103 1 : assert_int_not_equal(ret, EOK);
104 :
105 1 : check_leaks_pop(tmp_ctx);
106 1 : talloc_free(tmp_ctx);
107 1 : }
108 :
109 : struct create_pipe_ctx {
110 : int fd;
111 : const char *sock_name;
112 : };
113 :
114 1 : static int test_create_pipe_fd_setup(void **state)
115 : {
116 : struct create_pipe_ctx *ctx;
117 :
118 1 : ctx = talloc(global_talloc_context, struct create_pipe_ctx);
119 1 : assert_non_null(ctx);
120 1 : ctx->fd = -1;
121 :
122 1 : *state = ctx;
123 1 : return 0;
124 : }
125 :
126 2 : void check_sock_properties(struct create_pipe_ctx *ctx, mode_t mode)
127 : {
128 : int ret;
129 : int optval;
130 : socklen_t optlen;
131 : struct stat sbuf;
132 :
133 : /* Check existence of the file and the permissions */
134 2 : ret = stat(ctx->sock_name, &sbuf);
135 2 : assert_int_equal(ret, 0);
136 2 : assert_true(S_ISSOCK(sbuf.st_mode));
137 2 : assert_true((sbuf.st_mode & ~S_IFMT) == mode);
138 :
139 : /* Check it's a UNIX socket */
140 2 : optlen = sizeof(optval);
141 2 : ret = getsockopt(ctx->fd, SOL_SOCKET, SO_DOMAIN, &optval, &optlen);
142 2 : assert_int_equal(ret, 0);
143 2 : assert_int_equal(optval, AF_UNIX);
144 :
145 2 : optlen = sizeof(optval);
146 2 : ret = getsockopt(ctx->fd, SOL_SOCKET, SO_TYPE, &optval, &optlen);
147 2 : assert_int_equal(ret, 0);
148 2 : assert_int_equal(optval, SOCK_STREAM);
149 :
150 : /* Make sure this is a listening socket */
151 2 : optlen = sizeof(optval);
152 2 : ret = getsockopt(ctx->fd, SOL_SOCKET, SO_ACCEPTCONN, &optval, &optlen);
153 2 : assert_int_equal(ret, 0);
154 2 : assert_int_equal(optval, 1);
155 :
156 : /* Check the right protocol */
157 2 : optlen = sizeof(optval);
158 2 : ret = getsockopt(ctx->fd, SOL_SOCKET, SO_PROTOCOL, &optval, &optlen);
159 2 : assert_int_equal(ret, 0);
160 2 : assert_int_equal(optval, 0);
161 :
162 2 : }
163 :
164 1 : void test_create_pipe_fd(void **state)
165 : {
166 : int ret;
167 : struct create_pipe_ctx *ctx;
168 :
169 1 : ctx = talloc_get_type(*state, struct create_pipe_ctx);
170 :
171 1 : ctx->sock_name = __FUNCTION__;
172 :
173 1 : ret = create_pipe_fd(ctx->sock_name, &ctx->fd, 0111);
174 1 : assert_int_equal(ret, EOK);
175 1 : assert_int_not_equal(ctx->fd, -1);
176 1 : check_sock_properties(ctx, 0666);
177 :
178 : /* Make sure we can overwrite an existing socket */
179 1 : ret = create_pipe_fd(ctx->sock_name, &ctx->fd, 0000);
180 1 : assert_int_equal(ret, EOK);
181 1 : assert_int_not_equal(ctx->fd, -1);
182 1 : check_sock_properties(ctx, 0777);
183 1 : }
184 :
185 1 : static int test_create_pipe_fd_teardown(void **state)
186 : {
187 : struct create_pipe_ctx *ctx;
188 :
189 1 : ctx = talloc_get_type(*state, struct create_pipe_ctx);
190 :
191 1 : if (ctx->fd != -1) {
192 1 : unlink(ctx->sock_name);
193 1 : close(ctx->fd);
194 : }
195 1 : return 0;
196 : }
197 :
198 1 : int main(int argc, const char *argv[])
199 : {
200 : poptContext pc;
201 : int opt;
202 6 : struct poptOption long_options[] = {
203 : POPT_AUTOHELP
204 5 : SSSD_DEBUG_OPTS
205 : POPT_TABLEEND
206 : };
207 :
208 1 : const struct CMUnitTest tests[] = {
209 : cmocka_unit_test(test_uid_csv_to_uid_list),
210 : cmocka_unit_test(test_name_csv_to_uid_list),
211 : cmocka_unit_test(test_csv_to_uid_list_neg),
212 : cmocka_unit_test_setup_teardown(test_create_pipe_fd,
213 : test_create_pipe_fd_setup,
214 : test_create_pipe_fd_teardown)
215 : };
216 :
217 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
218 1 : debug_level = SSSDBG_INVALID;
219 :
220 1 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
221 1 : while((opt = poptGetNextOpt(pc)) != -1) {
222 : switch(opt) {
223 : default:
224 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
225 : poptBadOption(pc, 0), poptStrerror(opt));
226 0 : poptPrintUsage(pc, stderr, 0);
227 0 : return 1;
228 : }
229 : }
230 1 : poptFreeContext(pc);
231 :
232 1 : DEBUG_CLI_INIT(debug_level);
233 :
234 1 : tests_set_cwd();
235 :
236 1 : return cmocka_run_group_tests(tests, NULL, NULL);
237 : }
|