• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

proftpd / proftpd / 26182518137

20 May 2026 06:49PM UTC coverage: 93.024% (+0.4%) from 92.635%
26182518137

push

github

51329 of 55178 relevant lines covered (93.02%)

226.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.24
/tests/api/ctrls.c
1
/*
2
 * ProFTPD - FTP server testsuite
3
 * Copyright (c) 2020-2026 The ProFTPD Project team
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
17
 *
18
 * As a special exemption, The ProFTPD Project team and other respective
19
 * copyright holders give permission to link this program with OpenSSL, and
20
 * distribute the resulting executable, without including the source code for
21
 * OpenSSL in the source distribution.
22
 */
23

24
/* Controls API tests */
25

26
#include "tests.h"
27
#include "mod_ctrls.h"
28

29
#if defined(PR_USE_CTRLS)
30
static pool *p = NULL;
31

32
static const char *tmpfile_path = "/tmp/prt-ctrls.dat";
33

34
static void set_up(void) {
35
  (void) unlink(tmpfile_path);
34✔
36

34✔
37
  if (p == NULL) {
38
    p = permanent_pool = make_sub_pool(NULL);
34✔
39
  }
34✔
40

41
  if (getenv("TEST_VERBOSE") != NULL) {
42
    pr_trace_set_levels("ctrls", 1, 20);
34✔
43
    pr_trace_set_levels("json", 1, 20);
34✔
44
  }
34✔
45

46
  init_ctrls2("/tmp/test.sock");
47
}
34✔
48

34✔
49
static void tear_down(void) {
50
  if (getenv("TEST_VERBOSE") != NULL) {
34✔
51
    pr_trace_set_levels("ctrls", 0, 0);
34✔
52
    pr_trace_set_levels("json", 0, 0);
34✔
53
  }
34✔
54

55
  if (p != NULL) {
56
    destroy_pool(p);
34✔
57
    p = permanent_pool = NULL;
34✔
58
  }
34✔
59

60
  (void) unlink(tmpfile_path);
61
}
34✔
62

34✔
63
static int devnull_fd(void) {
64
  int fd;
6✔
65

6✔
66
  fd = open("/dev/null", O_RDWR);
67
  if (fd < 0) {
6✔
68
    fprintf(stderr, "Error opening /dev/null: %s\n", strerror(errno));
6✔
69
    return -1;
×
70
  }
×
71

72
  return fd;
73
}
74

75
static int tmpfile_fd(void) {
76
  int fd;
20✔
77

20✔
78
  fd = open(tmpfile_path, O_CREAT|O_RDWR, 0600);
79
  if (fd < 0) {
20✔
80
    fprintf(stderr, "Error opening %s: %s\n", tmpfile_path, strerror(errno));
20✔
81
    return -1;
×
82
  }
×
83

84
  (void) unlink(tmpfile_path);
85
  return fd;
20✔
86
}
20✔
87

88
static int reset_fd(int fd) {
89
  (void) close(fd);
14✔
90
  return tmpfile_fd();
14✔
91
}
14✔
92

93
static int rewind_fd(int fd) {
94
  if (lseek(fd, 0, SEEK_SET) == (off_t) -1) {
18✔
95
    return -1;
18✔
96
  }
×
97

98
  return 0;
99
}
100

101
/* Largely copied from mod_ctrls. */
102
static int listen_unix(const char *path) {
103
  int fd = -1, socklen = 0;
1✔
104
  struct sockaddr_un sock;
1✔
105
#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \
1✔
106
    !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS)
107
  int opt = 1;
108
  socklen_t optlen = sizeof(opt);
109
#endif /* !LOCAL_CREDS */
110

111
  fd = socket(AF_UNIX, SOCK_STREAM, 0);
112
  if (fd < 0) {
1✔
113
    fprintf(stderr, "error creating local socket: %s\n", strerror(errno));
1✔
114
    return -1;
×
115
  }
×
116

117
  (void) unlink(path);
118
  memset(&sock, 0, sizeof(sock));
1✔
119
  sock.sun_family = AF_UNIX;
1✔
120
  sstrncpy(sock.sun_path, path, sizeof(sock.sun_path));
1✔
121

1✔
122
  socklen = sizeof(sock);
123
  if (bind(fd, (struct sockaddr *) &sock, socklen) < 0) {
1✔
124
    fprintf(stderr, "error binding local socket to path '%s': %s\n", path,
1✔
125
      strerror(errno));
×
126
    (void) close(fd);
×
127
    return -1;
×
128
  }
×
129

130
  if (listen(fd, 5) < 0) {
131
    fprintf(stderr, "error listening on local socket: %s\n", strerror(errno));
1✔
132
    (void) close(fd);
×
133
    return -1;
×
134
  }
×
135

136
#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \
137
    !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS)
138
  /* Set the LOCAL_CREDS socket option. */
139
  if (setsockopt(fd, 0, LOCAL_CREDS, &opt, optlen) < 0) {
140
    fprintf(stderr, "error enabling LOCAL_CREDS: %s\n", strerror(errno));
141
  }
142
#endif /* !LOCAL_CREDS */
143

144
  return fd;
145
}
146

147
/* Tests */
148

149
START_TEST (ctrls_alloc_free_test) {
150
  int res;
1✔
151
  pr_ctrls_t *ctrl, *ctrl2, *ctrl3;
1✔
152

1✔
153
  mark_point();
154
  res = pr_ctrls_free(NULL);
1✔
155
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
156
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
157
    strerror(errno), errno);
1✔
158

159
  mark_point();
160
  ctrl = pr_ctrls_alloc();
1✔
161
  ck_assert_msg(ctrl != NULL, "Failed to allocate ctrl: %s", strerror(errno));
1✔
162
  res = pr_ctrls_free(ctrl);
1✔
163
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
1✔
164

1✔
165
  mark_point();
166
  ctrl = pr_ctrls_alloc();
1✔
167
  ck_assert_msg(ctrl != NULL, "Failed to allocate ctrl: %s", strerror(errno));
1✔
168
  res = pr_ctrls_free(ctrl);
1✔
169
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
1✔
170

1✔
171
  /* LIFO order */
172
  mark_point();
173
  ctrl = pr_ctrls_alloc();
1✔
174
  ctrl2 = pr_ctrls_alloc();
1✔
175
  ck_assert_msg(ctrl2 != NULL, "Failed to allocate ctrl2: %s", strerror(errno));
1✔
176
  ctrl2->ctrls_tmp_pool = make_sub_pool(p);
1✔
177
  ctrl3 = pr_ctrls_alloc();
1✔
178
  ck_assert_msg(ctrl3 != NULL, "Failed to allocate ctrl3: %s", strerror(errno));
1✔
179
  ctrl3->ctrls_tmp_pool = make_sub_pool(p);
1✔
180

1✔
181
  res = pr_ctrls_free(ctrl3);
182
  ck_assert_msg(res == 0, "Failed to free ctrl3 %s", strerror(errno));
1✔
183
  res = pr_ctrls_free(ctrl2);
1✔
184
  ck_assert_msg(res == 0, "Failed to free ctrl2: %s", strerror(errno));
1✔
185
  res = pr_ctrls_free(ctrl);
1✔
186
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
1✔
187

1✔
188
  /* FIFO order */
189
  mark_point();
190
  ctrl = pr_ctrls_alloc();
1✔
191
  ctrl2 = pr_ctrls_alloc();
1✔
192
  ck_assert_msg(ctrl2 != NULL, "Failed to allocate ctrl2: %s", strerror(errno));
1✔
193
  ctrl2->ctrls_tmp_pool = make_sub_pool(p);
1✔
194
  ctrl3 = pr_ctrls_alloc();
1✔
195
  ck_assert_msg(ctrl3 != NULL, "Failed to allocate ctrl3: %s", strerror(errno));
1✔
196
  ctrl3->ctrls_tmp_pool = make_sub_pool(p);
1✔
197

1✔
198
  res = pr_ctrls_free(ctrl);
199
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
1✔
200
  res = pr_ctrls_free(ctrl2);
1✔
201
  ck_assert_msg(res == 0, "Failed to free ctrl2: %s", strerror(errno));
1✔
202
  res = pr_ctrls_free(ctrl3);
1✔
203
  ck_assert_msg(res == 0, "Failed to free ctrl3 %s", strerror(errno));
1✔
204
}
1✔
205
END_TEST
1✔
206

207
START_TEST (ctrls_unregister_test) {
208
  int res;
1✔
209

1✔
210
  mark_point();
211
  res = pr_ctrls_unregister(NULL, NULL);
1✔
212
  ck_assert_msg(res < 0, "Failed to handle lack of registered actions");
1✔
213
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
214
    strerror(errno), errno);
1✔
215
}
216
END_TEST
1✔
217

218
static int ctrls_test_cb(pr_ctrls_t *ctrl, int reqargc, char **reqargv) {
219
  return 0;
1✔
220
}
1✔
221

222
static int ctrls_test2_cb(pr_ctrls_t *ctrl, int reqargc, char **reqargv) {
223
  return 0;
×
224
}
×
225

226
START_TEST (ctrls_register_test) {
227
  int res;
1✔
228
  const char *action = NULL, *desc = NULL;
1✔
229
  module m;
1✔
230

1✔
231
  mark_point();
232
  res = pr_ctrls_register(NULL, NULL, NULL, NULL);
1✔
233
  ck_assert_msg(res < 0, "Failed to handle null action");
1✔
234
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
235
    strerror(errno), errno);
1✔
236

237
  mark_point();
238
  action = "test";
1✔
239
  res = pr_ctrls_register(NULL, action, NULL, NULL);
1✔
240
  ck_assert_msg(res < 0, "Failed to handle null desc");
1✔
241
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
242
    strerror(errno), errno);
1✔
243

244
  mark_point();
245
  desc = "desc";
1✔
246
  res = pr_ctrls_register(NULL, action, desc, NULL);
1✔
247
  ck_assert_msg(res < 0, "Failed to handle null callback");
1✔
248
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
249
    strerror(errno), errno);
1✔
250

251
  mark_point();
252
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
253
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
254

1✔
255
  mark_point();
256
  res = pr_ctrls_unregister(NULL, action);
1✔
257
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
258
    strerror(errno));
1✔
259

260
  mark_point();
261
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
262
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
263

1✔
264
  m.name = "test";
265
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
266
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
267

1✔
268
  mark_point();
269
  res = pr_ctrls_unregister(NULL, action);
1✔
270
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
271
    strerror(errno));
1✔
272
}
273
END_TEST
1✔
274

275
START_TEST (ctrls_add_arg_test) {
276
  int res;
1✔
277
  pr_ctrls_t *ctrl;
1✔
278
  char buf[4];
1✔
279
  size_t buflen;
1✔
280

1✔
281
  mark_point();
282
  res = pr_ctrls_add_arg(NULL, NULL, 0);
1✔
283
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
284
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
285
    strerror(errno), errno);
1✔
286

287
  mark_point();
288
  ctrl = pr_ctrls_alloc();
1✔
289
  res = pr_ctrls_add_arg(ctrl, NULL, 0);
1✔
290
  ck_assert_msg(res < 0, "Failed to handle null arg");
1✔
291
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
292
    strerror(errno), errno);
1✔
293

294
  mark_point();
295
  ctrl = pr_ctrls_alloc();
1✔
296

1✔
297
  /* Provide an arg that uses unprintable ASCII. */
298
  buf[0] = 'a';
299
  buf[1] = 'b';
1✔
300
  buf[2] = -120;
1✔
301
  buflen = 3;
1✔
302

1✔
303
  res = pr_ctrls_add_arg(ctrl, buf, buflen);
304
  ck_assert_msg(res < 0, "Failed to handle bad arg");
1✔
305
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
306
    strerror(errno), errno);
1✔
307

308
  mark_point();
309
  buf[0] = 'a';
1✔
310
  buf[1] = 'B';
1✔
311
  buf[2] = '1';
1✔
312
  buflen = 3;
1✔
313

1✔
314
  res = pr_ctrls_add_arg(ctrl, buf, buflen);
315
  ck_assert_msg(res == 0, "Failed to add ctrl arg: %s", strerror(errno));
1✔
316
}
1✔
317
END_TEST
1✔
318

319
START_TEST (ctrls_add_response_test) {
320
  int res;
1✔
321
  pr_ctrls_t *ctrl;
1✔
322

1✔
323
  mark_point();
324
  res = pr_ctrls_add_response(NULL, NULL);
1✔
325
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
326
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
327
    strerror(errno), errno);
1✔
328

329
  mark_point();
330
  ctrl = pr_ctrls_alloc();
1✔
331
  res = pr_ctrls_add_response(ctrl, NULL);
1✔
332
  ck_assert_msg(res < 0, "Failed to handle null fmt");
1✔
333
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
334
    strerror(errno), errno);
1✔
335

336
  mark_point();
337
  res = pr_ctrls_add_response(ctrl, "%s", "foo");
1✔
338
  ck_assert_msg(res == 0, "Failed to add ctrl response: %s", strerror(errno));
1✔
339
}
1✔
340
END_TEST
1✔
341

342
START_TEST (ctrls_copy_args_test) {
343
  int res;
1✔
344
  pr_ctrls_t *src_ctrl, *dst_ctrl;
1✔
345

1✔
346
  mark_point();
347
  res = pr_ctrls_copy_args(NULL, NULL);
1✔
348
  ck_assert_msg(res < 0, "Failed to handle null src ctrl");
1✔
349
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
350
    strerror(errno), errno);
1✔
351

352
  mark_point();
353
  src_ctrl = pr_ctrls_alloc();
1✔
354
  res = pr_ctrls_copy_args(src_ctrl, NULL);
1✔
355
  ck_assert_msg(res < 0, "Failed to handle null dst ctrl");
1✔
356
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
357
    strerror(errno), errno);
1✔
358

359
  mark_point();
360
  res = pr_ctrls_copy_args(src_ctrl, src_ctrl);
1✔
361
  ck_assert_msg(res < 0, "Failed to handle same src/dst ctrl");
1✔
362
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
363
    strerror(errno), errno);
1✔
364

365
  mark_point();
366
  dst_ctrl = pr_ctrls_alloc();
1✔
367
  res = pr_ctrls_copy_args(src_ctrl, dst_ctrl);
1✔
368
  ck_assert_msg(res == 0, "Failed to copy ctrl args: %s", strerror(errno));
1✔
369

1✔
370
  mark_point();
371
  res = pr_ctrls_add_arg(src_ctrl, "foo", 3);
1✔
372
  ck_assert_msg(res == 0, "Failed to add src ctrl arg: %s", strerror(errno));
1✔
373

1✔
374
  res = pr_ctrls_add_arg(src_ctrl, "bar", 3);
375
  ck_assert_msg(res == 0, "Failed to add src ctrl arg: %s", strerror(errno));
1✔
376

1✔
377
  res = pr_ctrls_add_arg(src_ctrl, "baz", 3);
378
  ck_assert_msg(res == 0, "Failed to add src ctrl arg: %s", strerror(errno));
1✔
379

1✔
380
  res = pr_ctrls_copy_args(src_ctrl, dst_ctrl);
381
  ck_assert_msg(res == 0, "Failed to copy ctrl args: %s", strerror(errno));
1✔
382
}
1✔
383
END_TEST
1✔
384

385
START_TEST (ctrls_copy_resps_test) {
386
  int res;
1✔
387
  pr_ctrls_t *src_ctrl, *dst_ctrl;
1✔
388

1✔
389
  mark_point();
390
  res = pr_ctrls_copy_resps(NULL, NULL);
1✔
391
  ck_assert_msg(res < 0, "Failed to handle null src ctrl");
1✔
392
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
393
    strerror(errno), errno);
1✔
394

395
  mark_point();
396
  src_ctrl = pr_ctrls_alloc();
1✔
397
  res = pr_ctrls_copy_resps(src_ctrl, NULL);
1✔
398
  ck_assert_msg(res < 0, "Failed to handle null dst ctrl");
1✔
399
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
400
    strerror(errno), errno);
1✔
401

402
  mark_point();
403
  res = pr_ctrls_copy_resps(src_ctrl, src_ctrl);
1✔
404
  ck_assert_msg(res < 0, "Failed to handle same src/dst ctrl");
1✔
405
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
406
    strerror(errno), errno);
1✔
407

408
  mark_point();
409
  dst_ctrl = pr_ctrls_alloc();
1✔
410
  res = pr_ctrls_copy_resps(src_ctrl, dst_ctrl);
1✔
411
  ck_assert_msg(res < 0, "Failed to handle src ctrl with no responses");
1✔
412
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
413
    strerror(errno), errno);
1✔
414

415
  mark_point();
416
  res = pr_ctrls_add_response(src_ctrl, "%s", "foo");
1✔
417
  ck_assert_msg(res == 0, "Failed to add src ctrl response: %s", strerror(errno));
1✔
418

1✔
419
  res = pr_ctrls_add_response(dst_ctrl, "%s", "bar");
420
  ck_assert_msg(res == 0, "Failed to add dst ctrl response: %s", strerror(errno));
1✔
421

1✔
422
  res = pr_ctrls_copy_resps(src_ctrl, dst_ctrl);
423
  ck_assert_msg(res < 0, "Failed to handle dst ctrl with responses");
1✔
424
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
425
    strerror(errno), errno);
1✔
426

427
  mark_point();
428
  src_ctrl = pr_ctrls_alloc();
1✔
429
  res = pr_ctrls_add_response(src_ctrl, "%s", "foo");
1✔
430
  ck_assert_msg(res == 0, "Failed to add src ctrl response: %s", strerror(errno));
1✔
431

1✔
432
  dst_ctrl = pr_ctrls_alloc();
433
  res = pr_ctrls_copy_resps(src_ctrl, dst_ctrl);
1✔
434
  ck_assert_msg(res == 0, "Failed to copy ctrl responses: %s", strerror(errno));
1✔
435
}
1✔
436
END_TEST
1✔
437

438
START_TEST (ctrls_send_request_test) {
439
  int fd, res;
1✔
440
  char *action = "foo";
1✔
441
  unsigned int msgargc = 1;
1✔
442
  char *msgargv[] = { "bar", NULL };
1✔
443

1✔
444
  mark_point();
445
  res = pr_ctrls_send_request(NULL, -1, NULL, 0, NULL);
1✔
446
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
447
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
448
    strerror(errno), errno);
1✔
449

450
  mark_point();
451
  res = pr_ctrls_send_request(p, -1, NULL, 0, NULL);
1✔
452
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
453
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
454
    strerror(errno), errno);
1✔
455

456
  mark_point();
457
  fd = 7;
1✔
458
  res = pr_ctrls_send_request(p, fd, NULL, 0, NULL);
1✔
459
  ck_assert_msg(res < 0, "Failed to handle null action");
1✔
460
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
461
    strerror(errno), errno);
1✔
462

463
  mark_point();
464
  res = pr_ctrls_send_request(p, fd, action, msgargc, NULL);
1✔
465
  ck_assert_msg(res < 0, "Failed to handle mismatched argc/argv");
1✔
466
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
467
    strerror(errno), errno);
1✔
468

469
  mark_point();
470
  fd = 7777;
1✔
471
  res = pr_ctrls_send_request(p, fd, action, msgargc, msgargv);
1✔
472
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
473
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
474
    strerror(errno), errno);
1✔
475

476
  fd = devnull_fd();
477
  if (fd < 0) {
1✔
478
    return;
1✔
479
  }
×
480

481
  mark_point();
482
  res = pr_ctrls_send_request(p, fd, action, msgargc, msgargv);
1✔
483
  ck_assert_msg(res == 0, "Failed to send ctrl message: %s", strerror(errno));
1✔
484

1✔
485
  (void) close(fd);
486
}
1✔
487
END_TEST
488

489
START_TEST (ctrls_send_response_test) {
490
  int fd, res, status;
1✔
491
  unsigned int msgargc = 1;
1✔
492
  char *msgargv[] = { "foo", NULL };
1✔
493

1✔
494
  mark_point();
495
  res = pr_ctrls_send_response(NULL, -1, 0, 0, NULL);
1✔
496
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
497
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
498
    strerror(errno), errno);
1✔
499

500
  mark_point();
501
  res = pr_ctrls_send_response(p, -1, 0, 0, NULL);
1✔
502
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
503
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
504
    strerror(errno), errno);
1✔
505

506
  mark_point();
507
  fd = devnull_fd();
1✔
508
  if (fd < 0) {
1✔
509
    return;
1✔
510
  }
×
511
  res = pr_ctrls_send_response(p, fd, 0, 0, NULL);
512
  ck_assert_msg(res == 0, "Failed to send zero ctrl messages: %s",
1✔
513
    strerror(errno));
1✔
514

515
  mark_point();
516
  res = pr_ctrls_send_response(p, fd, 0, msgargc, NULL);
1✔
517
  ck_assert_msg(res < 0, "Failed to handle missing argv");
1✔
518
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
519
    strerror(errno), errno);
1✔
520
  (void) close(fd);
521

1✔
522
  mark_point();
523
  fd = 7777;
1✔
524
  status = -24;
1✔
525
  res = pr_ctrls_send_response(p, fd, status, msgargc, msgargv);
1✔
526
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
527
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
528
    strerror(errno), errno);
1✔
529

530
  fd = devnull_fd();
531
  if (fd < 0) {
1✔
532
    return;
1✔
533
  }
534

535
  mark_point();
536
  status = -24;
1✔
537
  res = pr_ctrls_send_response(p, fd, status, msgargc, msgargv);
1✔
538
  ck_assert_msg(res == 0, "Failed to send ctrl message: %s", strerror(errno));
1✔
539

1✔
540
  (void) close(fd);
541
}
1✔
542
END_TEST
543

544
START_TEST (ctrls_flush_response_test) {
545
  int res;
1✔
546
  pr_ctrls_t *ctrl;
1✔
547
  pr_ctrls_cl_t *cl;
1✔
548

1✔
549
  mark_point();
550
  res = pr_ctrls_flush_response(NULL);
1✔
551
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
552
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
553
    strerror(errno), errno);
1✔
554

555
  mark_point();
556
  ctrl = pr_ctrls_alloc();
1✔
557
  res = pr_ctrls_flush_response(ctrl);
1✔
558
  ck_assert_msg(res == 0, "Failed to flush ctrl with no responses: %s",
1✔
559
    strerror(errno));
1✔
560

561
  mark_point();
562
  res = pr_ctrls_add_response(ctrl, "%s", "foo");
1✔
563
  ck_assert_msg(res == 0, "Failed to add ctrl response: %s", strerror(errno));
1✔
564
  res = pr_ctrls_flush_response(ctrl);
1✔
565
  ck_assert_msg(res < 0, "Failed to handle ctrl with no client");
1✔
566
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
567
    strerror(errno), errno);
1✔
568

569
  mark_point();
570
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
571
  cl->cl_fd = devnull_fd();
1✔
572
  if (cl->cl_fd < 0) {
1✔
573
    return;
1✔
574
  }
575

576
  ctrl->ctrls_cl = cl;
577
  res = pr_ctrls_flush_response(ctrl);
1✔
578
  ck_assert_msg(res == 0, "Failed to flush ctrl responses: %s", strerror(errno));
1✔
579

1✔
580
  mark_point();
581
  (void) close(cl->cl_fd);
1✔
582
  res = pr_ctrls_flush_response(ctrl);
1✔
583
  ck_assert_msg(res < 0, "Failed to handle bad fd");
1✔
584
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
585
    strerror(errno), errno);
1✔
586
}
587
END_TEST
588

589
START_TEST (ctrls_recv_request_invalid_test) {
590
  int fd, res;
1✔
591
  uint32_t msglen;
1✔
592
  char *msg = NULL;
1✔
593
  pr_ctrls_cl_t *cl;
1✔
594

1✔
595
  mark_point();
596
  res = pr_ctrls_recv_request(NULL);
1✔
597
  ck_assert_msg(res < 0, "Failed to handle null client");
1✔
598
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
599
    strerror(errno), errno);
1✔
600

601
  mark_point();
602
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
603
  res = pr_ctrls_recv_request(cl);
1✔
604
  ck_assert_msg(res < 0, "Failed to handle client without ctrls list");
1✔
605
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
606
    strerror(errno), errno);
1✔
607

608
  mark_point();
609
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
1✔
610
  cl->cl_fd = -1;
1✔
611
  res = pr_ctrls_recv_request(cl);
1✔
612
  ck_assert_msg(res < 0, "Failed to handle client without fd");
1✔
613
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
614
    strerror(errno), errno);
1✔
615

616
  mark_point();
617
  fd = tmpfile_fd();
1✔
618
  if (fd < 0) {
1✔
619
    return;
1✔
620
  }
×
621

622
  cl->cl_fd = fd;
623
  (void) close(cl->cl_fd);
1✔
624
  res = pr_ctrls_recv_request(cl);
1✔
625
  ck_assert_msg(res < 0, "Failed to handle client with bad fd");
1✔
626
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
627
    strerror(errno), errno);
1✔
628

629
  mark_point();
630
  fd = tmpfile_fd();
1✔
631
  if (fd < 0) {
1✔
632
    return;
1✔
633
  }
634

635
  cl->cl_fd = fd;
636
  (void) write(fd, "a", 1);
1✔
637
  rewind_fd(fd);
1✔
638
  res = pr_ctrls_recv_request(cl);
1✔
639
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too short)");
1✔
640
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
641
    strerror(errno), errno);
1✔
642

643
  fd = reset_fd(fd);
644
  if (fd < 0) {
1✔
645
    return;
1✔
646
  }
647
  cl->cl_fd = fd;
648

1✔
649
  mark_point();
650
  msglen = 2;
1✔
651
  (void) write(fd, &msglen, sizeof(msglen));
1✔
652
  (void) write(fd, "a", 1);
1✔
653
  rewind_fd(fd);
1✔
654
  res = pr_ctrls_recv_request(cl);
1✔
655
  ck_assert_msg(res < 0, "Failed to handle invalid message (too short)");
1✔
656
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
657
    strerror(errno), errno);
1✔
658

659
  fd = reset_fd(fd);
660
  if (fd < 0) {
1✔
661
    return;
1✔
662
  }
663
  cl->cl_fd = fd;
664

1✔
665
  mark_point();
666
  msglen = 2;
1✔
667
  (void) write(fd, &msglen, sizeof(msglen));
1✔
668
  (void) write(fd, "aa", 2);
1✔
669
  rewind_fd(fd);
1✔
670
  res = pr_ctrls_recv_request(cl);
1✔
671
  ck_assert_msg(res < 0, "Failed to handle invalid message (wrong format)");
1✔
672
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
673
    strerror(errno), errno);
1✔
674

675
  fd = reset_fd(fd);
676
  if (fd < 0) {
1✔
677
    return;
1✔
678
  }
679
  cl->cl_fd = fd;
680

1✔
681
  mark_point();
682
  msg = "{}";
1✔
683
  msglen = strlen(msg);
1✔
684
  (void) write(fd, &msglen, sizeof(msglen));
1✔
685
  (void) write(fd, msg, msglen);
1✔
686
  rewind_fd(fd);
1✔
687
  res = pr_ctrls_recv_request(cl);
1✔
688
  ck_assert_msg(res < 0, "Failed to handle invalid message (missing 'action')");
1✔
689
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
690
    strerror(errno), errno);
1✔
691

692
  fd = reset_fd(fd);
693
  if (fd < 0) {
1✔
694
    return;
1✔
695
  }
696
  cl->cl_fd = fd;
697

1✔
698
  mark_point();
699
  msg = "{\"action\":\"foo\"}";
1✔
700
  msglen = strlen(msg);
1✔
701
  (void) write(fd, &msglen, sizeof(msglen));
1✔
702
  (void) write(fd, msg, msglen);
1✔
703
  rewind_fd(fd);
1✔
704
  res = pr_ctrls_recv_request(cl);
1✔
705
  ck_assert_msg(res < 0, "Failed to handle invalid message (missing 'args')");
1✔
706
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
707
    strerror(errno), errno);
1✔
708

709
  fd = reset_fd(fd);
710
  if (fd < 0) {
1✔
711
    return;
1✔
712
  }
713
  cl->cl_fd = fd;
714

1✔
715
  mark_point();
716
  msg = "{\"action\":\"test\",\"args\":[1,2,3,4,5,6,7,8,9,10]}";
1✔
717
  msglen = strlen(msg);
1✔
718
  (void) write(fd, &msglen, sizeof(msglen));
1✔
719
  (void) write(fd, msg, msglen);
1✔
720
  rewind_fd(fd);
1✔
721
  res = pr_ctrls_recv_request(cl);
1✔
722
  ck_assert_msg(res < 0, "Failed to handle unknown action");
1✔
723
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
724
    strerror(errno), errno);
1✔
725

726
  (void) close(fd);
727
}
1✔
728
END_TEST
729

730
START_TEST (ctrls_recv_request_too_large_test) {
731
  int fd, res;
1✔
732
  uint32_t msglen;
1✔
733
  pr_ctrls_cl_t *cl;
1✔
734

1✔
735
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
736
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
1✔
737

1✔
738
  mark_point();
1✔
739
  fd = tmpfile_fd();
740
  if (fd < 0) {
1✔
741
    return;
1✔
742
  }
1✔
743

1✔
744
  cl->cl_fd = fd;
1✔
745

1✔
746
  mark_point();
747
  msglen = (uint32_t) -1;
1✔
748
  (void) write(fd, (const void *) &msglen, sizeof(msglen));
1✔
749
  rewind_fd(fd);
1✔
750
  res = pr_ctrls_recv_request(cl);
×
751
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too long)");
752
  ck_assert_msg(errno == E2BIG, "Expected E2BIG (%d), got %s (%d)", E2BIG,
753
    strerror(errno), errno);
1✔
754

1✔
755
  (void) close(fd);
1✔
756
}
757
END_TEST
1✔
758

1✔
759
START_TEST (ctrls_recv_request_valid_test) {
1✔
760
  int fd, res;
1✔
761
  uint32_t msglen = 0;
1✔
762
  char *msg = NULL;
1✔
763
  const char *action, *desc;
1✔
764
  pr_ctrls_cl_t *cl;
1✔
765
  pr_ctrls_t *ctrl;
766
  module m;
1✔
767

1✔
768
  mark_point();
769
  m.name = "test";
1✔
770
  action = "test";
771
  desc = "desc";
772
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
773
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
774

1✔
775
  mark_point();
776
  fd = tmpfile_fd();
777
  if (fd < 0) {
1✔
778
    return;
1✔
779
  }
780

1✔
781
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
782
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
1✔
783
  cl->cl_fd = fd;
1✔
784

1✔
785
  msg = "{\"action\":\"test\",\"args\":[]}";
1✔
786
  msglen = strlen(msg);
1✔
787
  (void) write(fd, &msglen, sizeof(msglen));
1✔
788
  (void) write(fd, msg, msglen);
789
  rewind_fd(fd);
1✔
790
  res = pr_ctrls_recv_request(cl);
1✔
791
  ck_assert_msg(res == 0, "Failed to handle known action: %s", strerror(errno));
792
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
1✔
793
    cl->cl_ctrls->nelts);
794
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
795
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
1✔
796
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
797
  ck_assert_msg(ctrl->ctrls_cb_args == NULL,
1✔
798
    "Expected no callback args, got %p", ctrl->ctrls_cb_args);
799

800
  mark_point();
1✔
801
  fd = reset_fd(fd);
1✔
802
  if (fd < 0) {
803
    return;
1✔
804
  }
1✔
805
  clear_array(cl->cl_ctrls);
1✔
806
  cl->cl_fd = fd;
1✔
807

1✔
808
  msg = "{\"action\":\"test\",\"args\":[\"a\"]}";
1✔
809
  msglen = strlen(msg);
1✔
810
  (void) write(fd, &msglen, sizeof(msglen));
811
  (void) write(fd, msg, msglen);
1✔
812
  rewind_fd(fd);
813
  res = pr_ctrls_recv_request(cl);
1✔
814
  ck_assert_msg(res == 0, "Failed to handle known action: %s", strerror(errno));
1✔
815
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
816
    cl->cl_ctrls->nelts);
1✔
817
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
818
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
819
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
820
  ck_assert_msg(ctrl->ctrls_cb_args != NULL,
821
    "Expected callback args, got %p", ctrl->ctrls_cb_args);
822

1✔
823
  mark_point();
1✔
824
  fd = reset_fd(fd);
1✔
825
  if (fd < 0) {
826
    return;
1✔
827
  }
1✔
828
  clear_array(cl->cl_ctrls);
1✔
829
  cl->cl_fd = fd;
830

831
  msg = "{\"action\":\"test\",\"args\":[\"next\"]}";
1✔
832
  msglen = strlen(msg);
1✔
833
  (void) write(fd, &msglen, sizeof(msglen));
834
  (void) write(fd, msg, msglen);
1✔
835
  rewind_fd(fd);
1✔
836
  res = pr_ctrls_recv_request(cl);
1✔
837
  ck_assert_msg(res == 0, "Failed to handle valid request: %s",
1✔
838
    strerror(errno));
1✔
839
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
1✔
840
    cl->cl_ctrls->nelts);
1✔
841
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
842
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
1✔
843
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
844
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
845
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
1✔
846
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
1✔
847

848
  /* next_action present */
1✔
849

1✔
850
  mark_point();
851
  res = pr_ctrls_register(&m, action, desc, ctrls_test2_cb);
852
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
853

1✔
854
  mark_point();
855
  fd = reset_fd(fd);
1✔
856
  if (fd < 0) {
1✔
857
    return;
858
  }
859
  clear_array(cl->cl_ctrls);
1✔
860
  cl->cl_fd = fd;
1✔
861

862
  msg = "{\"action\":\"test\",\"args\":[\"next\"]}";
863
  msglen = strlen(msg);
864
  (void) write(fd, &msglen, sizeof(msglen));
1✔
865
  (void) write(fd, msg, msglen);
1✔
866
  rewind_fd(fd);
1✔
867
  res = pr_ctrls_recv_request(cl);
1✔
868
  ck_assert_msg(res == 0, "Failed to handle valid request: %s",
869
    strerror(errno));
1✔
870
  ck_assert_msg(cl->cl_ctrls->nelts == 2, "Expected 2 ctrl, got %d",
1✔
871
    cl->cl_ctrls->nelts);
1✔
872

1✔
873
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
874
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
875
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
876
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
1✔
877
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
1✔
878
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
1✔
879

880
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[1];
881
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
1✔
882
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
883
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
1✔
884
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
×
885
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
886

887
  (void) pr_ctrls_unregister(&m, action);
1✔
888
  (void) close(fd);
1✔
889
}
1✔
890
END_TEST
891

1✔
892
START_TEST (ctrls_recv_response_test) {
893
  int fd, res, status;
1✔
894
  uint32_t msglen;
1✔
895
  char *msg = NULL;
1✔
896

897
  mark_point();
898
  res = pr_ctrls_recv_response(NULL, -1, NULL, NULL);
899
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
900
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
901
    strerror(errno), errno);
1✔
902

1✔
903
  mark_point();
1✔
904
  res = pr_ctrls_recv_response(p, -1, NULL, NULL);
905
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
906
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
907
    strerror(errno), errno);
1✔
908

909
  mark_point();
910
  fd = tmpfile_fd();
911
  if (fd < 0) {
1✔
912
    return;
1✔
913
  }
1✔
914

1✔
915
  res = pr_ctrls_recv_response(p, fd, NULL, NULL);
1✔
916
  ck_assert_msg(res < 0, "Failed to handle null status");
1✔
917
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
918
    strerror(errno), errno);
1✔
919
  (void) close(fd);
920

921
  mark_point();
1✔
922
  fd = tmpfile_fd();
1✔
923
  if (fd < 0) {
924
    return;
925
  }
926

1✔
927
  (void) write(fd, "a", 1);
1✔
928
  rewind_fd(fd);
1✔
929
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
930
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too short)");
1✔
931
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
932
    strerror(errno), errno);
1✔
933

1✔
934
  fd = reset_fd(fd);
935
  if (fd < 0) {
936
    return;
1✔
937
  }
1✔
938

939
  mark_point();
940
  msglen = 2;
941
  (void) write(fd, &msglen, sizeof(msglen));
1✔
942
  (void) write(fd, "a", 1);
1✔
943
  rewind_fd(fd);
1✔
944
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
945
  ck_assert_msg(res < 0, "Failed to handle invalid message (too short)");
1✔
946
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
947
    strerror(errno), errno);
1✔
948

1✔
949
  fd = reset_fd(fd);
1✔
950
  if (fd < 0) {
951
    return;
952
  }
1✔
953

1✔
954
  mark_point();
955
  msglen = 2;
956
  (void) write(fd, &msglen, sizeof(msglen));
957
  (void) write(fd, "aa", 2);
1✔
958
  rewind_fd(fd);
1✔
959
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
960
  ck_assert_msg(res < 0, "Failed to handle invalid message (wrong format)");
1✔
961
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
962
    strerror(errno), errno);
1✔
963

1✔
964
  fd = reset_fd(fd);
1✔
965
  if (fd < 0) {
966
    return;
1✔
967
  }
968

969
  mark_point();
1✔
970
  msg = "{}";
1✔
971
  msglen = strlen(msg);
972
  (void) write(fd, &msglen, sizeof(msglen));
973
  (void) write(fd, msg, msglen);
974
  rewind_fd(fd);
1✔
975
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
976
  ck_assert_msg(res < 0, "Failed to handle invalid message (missing 'status')");
1✔
977
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
978
    strerror(errno), errno);
1✔
979

1✔
980
  fd = reset_fd(fd);
1✔
981
  if (fd < 0) {
1✔
982
    return;
983
  }
1✔
984

985
  mark_point();
986
  msg = "{\"status\":0}";
1✔
987
  msglen = strlen(msg);
1✔
988
  (void) write(fd, &msglen, sizeof(msglen));
989
  (void) write(fd, msg, msglen);
990
  rewind_fd(fd);
991
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
992
  ck_assert_msg(res < 0,
1✔
993
    "Failed to handle invalid message (missing 'responses')");
1✔
994
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
995
    strerror(errno), errno);
1✔
996

1✔
997
  fd = reset_fd(fd);
1✔
998
  if (fd < 0) {
1✔
999
    return;
1000
  }
1001

1✔
1002
  mark_point();
1003
  msg = "{\"status\":0,\"responses\":[1]}";
1004
  msglen = strlen(msg);
1005
  (void) write(fd, &msglen, sizeof(msglen));
1✔
1006
  (void) write(fd, msg, msglen);
1✔
1007
  rewind_fd(fd);
1✔
1008
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1009
  ck_assert_msg(res < 0,
1✔
1010
    "Failed to handle invalid message (non-text response)");
1✔
1011
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1012
    strerror(errno), errno);
1✔
1013

1✔
1014
  fd = reset_fd(fd);
1015
  if (fd < 0) {
1016
    return;
1017
  }
1✔
1018

1✔
1019
  mark_point();
1✔
1020
  msg = "{\"status\":0,\"responses\":[\"ok\"]}";
1✔
1021
  msglen = strlen(msg);
1✔
1022
  (void) write(fd, &msglen, sizeof(msglen));
1✔
1023
  (void) write(fd, msg, msglen);
1024
  rewind_fd(fd);
1025
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1026
  ck_assert_msg(res == 1, "Failed to handle valid response: %s",
1027
    strerror(errno));
1✔
1028

1✔
1029
  (void) close(fd);
1✔
1030
}
1✔
1031
END_TEST
1✔
1032

×
1033
START_TEST (ctrls_recv_response_too_large_test) {
1034
  int fd, res, status;
1035
  uint32_t msglen;
1✔
1036

1037
  mark_point();
1038
  fd = tmpfile_fd();
1✔
1039
  if (fd < 0) {
1✔
1040
    return;
1✔
1041
  }
1✔
1042

1✔
1043
  mark_point();
1044
  msglen = (uint32_t) -1;
1✔
1045
  (void) write(fd, (const void *) &msglen, sizeof(msglen));
1✔
1046
  rewind_fd(fd);
1✔
1047
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
1048
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too long)");
1049
  ck_assert_msg(errno == E2BIG, "Expected E2BIG (%d), got %s (%d)", E2BIG,
1050
    strerror(errno), errno);
1✔
1051

1✔
1052
  (void) close(fd);
1✔
1053
}
1✔
1054
END_TEST
1055

1056
START_TEST (ctrls_issock_unix_test) {
1✔
1057
  int res;
1✔
1058
  mode_t mode;
1✔
1059

1✔
1060
  mark_point();
1✔
1061
  mode = 0;
1062
  res = pr_ctrls_issock_unix(mode);
1✔
1063
  ck_assert_msg(res < 0, "Failed to handle invalid mode");
1064
  ck_assert_msg(errno == ENOSYS, "Expected ENOSYS (%d), got %s (%d)", ENOSYS,
1✔
1065
    strerror(errno), errno);
1✔
1066

1✔
1067
#if defined(S_ISFIFO)
1✔
1068
  mark_point();
1✔
1069
  mode = 0;
1070
  mode |= S_IFIFO;
1✔
1071
  res = pr_ctrls_issock_unix(mode);
1✔
1072
  if (res < 0) {
1✔
1073
    ck_assert_msg(errno == ENOSYS, "Did not expect ENOSYS (%d)", ENOSYS);
1074
  }
1✔
1075
#endif /* S_ISFIFO */
1✔
1076

1✔
1077
#if defined(S_ISSOCK)
1078
  mark_point();
1✔
1079
  mode = 0;
1✔
1080
  mode |= S_IFSOCK;
1✔
1081
  res = pr_ctrls_issock_unix(mode);
1082
  if (res < 0) {
1083
    ck_assert_msg(errno == ENOSYS, "Did not expect ENOSYS (%d)", ENOSYS);
1✔
1084
  }
1✔
1085
#endif /* S_ISSOCK */
1✔
1086
}
1087
END_TEST
1088

1✔
1089
START_TEST (ctrls_get_registered_actions_test) {
1✔
1090
  int res;
1✔
1091
  pr_ctrls_t *ctrl;
1092
  const char *action, *desc;
1✔
1093
  module m;
1✔
1094

1✔
1095
  mark_point();
1096
  res = pr_get_registered_actions(NULL, 0);
1✔
1097
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1098
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1099
    strerror(errno), errno);
1✔
1100

1✔
1101
  mark_point();
1✔
1102
  ctrl = pr_ctrls_alloc();
1103
  res = pr_get_registered_actions(ctrl, 0);
1✔
1104
  ck_assert_msg(res == 0, "Failed to handle lack of registered actions: %s",
1✔
1105
    strerror(errno));
1✔
1106

1✔
1107
  mark_point();
1108
  pr_block_ctrls();
1109
  res = pr_get_registered_actions(ctrl, 0);
1✔
1110
  ck_assert_msg(res < 0, "Failed to handle blocked actions");
1✔
1111
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1112
    strerror(errno), errno);
1✔
1113
  pr_unblock_ctrls();
1114

1115
  mark_point();
1✔
1116
  action = "test";
1✔
1117
  desc = "desc";
1✔
1118
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1119
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1120

1121
  m.name = "test";
1✔
1122
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
1123
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1124

1125
  mark_point();
1126
  res = pr_get_registered_actions(ctrl, 0);
1✔
1127
  ck_assert_msg(res == 0, "Failed to handle invalid flags: %s", strerror(errno));
1✔
1128

1✔
1129
  mark_point();
1✔
1130
  res = pr_get_registered_actions(ctrl, CTRLS_GET_ACTION_ALL);
1✔
1131
  ck_assert_msg(res == 2, "Failed to handle GET_ACTION_ALL flag: %s",
1132
    strerror(errno));
1✔
1133

1134
  mark_point();
1✔
1135
  res = pr_get_registered_actions(ctrl, CTRLS_GET_ACTION_ENABLED);
1✔
1136
  ck_assert_msg(res == 2, "Failed to handle GET_ACTION_ENABLED flag: %s",
1✔
1137
    strerror(errno));
1138

1139
  mark_point();
1✔
1140
  res = pr_get_registered_actions(ctrl, CTRLS_GET_DESC);
1✔
1141
  ck_assert_msg(res == 2, "Failed to handle GET_DESC flag: %s", strerror(errno));
1✔
1142

1143
  mark_point();
1✔
1144
  res = pr_ctrls_unregister(NULL, action);
1✔
1145
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
1146
    strerror(errno));
1147
}
1✔
1148
END_TEST
1149

1150
START_TEST (ctrls_set_registered_actions_test) {
1✔
1151
  int res;
1✔
1152
  const char *action, *desc;
1✔
1153

1154
  mark_point();
1✔
1155
  res = pr_set_registered_actions(NULL, NULL, FALSE, 0);
1✔
1156
  ck_assert_msg(res < 0, "Failed to handle no registered actions");
1✔
1157
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1158
    strerror(errno), errno);
1159

1✔
1160
  mark_point();
1✔
1161
  res = pr_set_registered_actions(NULL, NULL, FALSE, 24);
1✔
1162
  ck_assert_msg(res < 0, "Failed to handle invalid flag");
1✔
1163
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1164
    strerror(errno), errno);
1165

1✔
1166
  mark_point();
1✔
1167
  action = "test";
1✔
1168
  desc = "desc";
1169
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1170
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1171

1172
  mark_point();
1✔
1173
  res = pr_set_registered_actions(NULL, NULL, FALSE, 0);
1✔
1174
  ck_assert_msg(res == 0, "Failed to handle no registered actions: %s",
1✔
1175
    strerror(errno));
1176

1✔
1177
  mark_point();
1✔
1178
  pr_block_ctrls();
1✔
1179
  res = pr_set_registered_actions(NULL, NULL, FALSE, 0);
1180
  ck_assert_msg(res < 0, "Failed to handle blocked actions");
1181
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1182
    strerror(errno), errno);
1✔
1183
  pr_unblock_ctrls();
1✔
1184

1185
  mark_point();
1186
  res = pr_set_registered_actions(NULL, action, FALSE, 0);
1✔
1187
  ck_assert_msg(res == 0, "Failed to handle action '%s': %s", action,
1✔
1188
    strerror(errno));
1✔
1189

1✔
1190
  mark_point();
1191
  res = pr_set_registered_actions(NULL, "all", FALSE, 0);
1192
  ck_assert_msg(res == 0, "Failed to handle action 'all': %s", strerror(errno));
1✔
1193

1✔
1194
  mark_point();
1✔
1195
  res = pr_ctrls_unregister(NULL, action);
1196
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
1197
    strerror(errno));
1198
}
1199
END_TEST
1✔
1200

1✔
1201
START_TEST (ctrls_check_actions_test) {
1✔
1202
  int res;
1✔
1203
  const char *action, *desc;
1✔
1204

1✔
1205
  mark_point();
1✔
1206
  res = pr_ctrls_check_actions();
1✔
1207
  ck_assert_msg(res == 0, "Failed to handle no registered actions: %s",
1✔
1208
    strerror(errno));
1209

1✔
1210
  mark_point();
1✔
1211
  action = "test";
1✔
1212
  desc = "desc";
1213
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1214
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1215

1✔
1216
  mark_point();
1✔
1217
  res = pr_ctrls_check_actions();
1✔
1218
  ck_assert_msg(res == 0, "Failed to handle no registered actions: %s",
1219
    strerror(errno));
1✔
1220

1221
  /* Register a duplicate action name, then check. */
1✔
1222

1✔
1223
  mark_point();
1✔
1224
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1225
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1226

1✔
1227
  mark_point();
1✔
1228
  res = pr_ctrls_check_actions();
1229
  ck_assert_msg(res == 0, "Failed to handle registered actions: %s",
1✔
1230
    strerror(errno));
1✔
1231

1✔
1232
  mark_point();
1233
  res = pr_set_registered_actions(NULL, action, FALSE, PR_CTRLS_ACT_SOLITARY);
1✔
1234
  ck_assert_msg(res == 0, "Failed to set SOLITARY action flag: %s",
1✔
1235
    strerror(errno));
1✔
1236

1237
  mark_point();
1✔
1238
  res = pr_ctrls_check_actions();
1✔
1239
  ck_assert_msg(res < 0, "Failed to handle duplicate SOLITARY actions");
1✔
1240
  ck_assert_msg(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1241
    strerror(errno), errno);
1242

1243
  mark_point();
1244
  res = pr_ctrls_unregister(NULL, action);
1245
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1246
    strerror(errno));
1247
}
1✔
1248
END_TEST
1✔
1249

1✔
1250
START_TEST (ctrls_run_ctrls_test) {
×
1251
  int fd, res;
1252
  uint32_t msglen = 0;
1253
  char *msg = NULL;
1✔
1254
  const char *action, *desc;
1✔
1255
  pr_ctrls_cl_t *cl;
1✔
1256
  pr_ctrls_t *ctrl;
1257
  module m, m2;
1✔
1258
  time_t now;
1✔
1259

1✔
1260
  mark_point();
1✔
1261
  res = pr_run_ctrls(NULL, NULL);
1✔
1262
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1263

1✔
1264
  mark_point();
1✔
1265
  pr_block_ctrls();
1266
  res = pr_run_ctrls(NULL, NULL);
1✔
1267
  ck_assert_msg(res < 0, "Failed to handle blocked ctrls");
1268
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1269
    strerror(errno), errno);
1✔
1270
  pr_unblock_ctrls();
1✔
1271

1272
  mark_point();
1✔
1273
  action = "test";
1✔
1274
  desc = "desc";
1✔
1275
  m.name = "test";
1276
  m2.name = "test2";
1✔
1277
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
1278
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1279

1✔
1280
  mark_point();
1✔
1281
  res = pr_run_ctrls(NULL, NULL);
1282
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1283

1✔
1284
  mark_point();
1✔
1285
  res = pr_run_ctrls(&m2, NULL);
1✔
1286
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1287

1✔
1288
  mark_point();
1289
  res = pr_run_ctrls(&m, NULL);
1✔
1290
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1291

1✔
1292
  /* XXX TODO More test cases to fill in here. */
1✔
1293
  /* Note that pr_run_ctrls() makes a lot of assumptions about recv_response,
1✔
1294
   * recv_request having been called previously.  Not great.  How to deal
1✔
1295
   * with that?
1✔
1296
   */
1297

1✔
1298
  mark_point();
1✔
1299
  fd = tmpfile_fd();
1✔
1300
  if (fd < 0) {
1✔
1301
    return;
1✔
1302
  }
1✔
1303

1✔
1304
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1305
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
1✔
1306
  cl->cl_fd = fd;
1✔
1307

1✔
1308
  msg = "{\"action\":\"test\",\"args\":[\"FOO\"]}";
1✔
1309
  msglen = strlen(msg);
1✔
1310
  (void) write(fd, &msglen, sizeof(msglen));
1311
  (void) write(fd, msg, msglen);
1✔
1312
  rewind_fd(fd);
1✔
1313
  res = pr_ctrls_recv_request(cl);
1✔
1314
  ck_assert_msg(res == 0, "Failed to handle known action: %s", strerror(errno));
1315
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
1316
    cl->cl_ctrls->nelts);
1✔
1317
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1318

1319
  mark_point();
1320
  res = pr_run_ctrls(&m2, NULL);
1✔
1321
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1322

1✔
1323
  mark_point();
1324
  res = pr_run_ctrls(&m, NULL);
1✔
1325
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1326

1✔
1327
  mark_point();
1328
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1329
  ctrl->ctrls_flags |= PR_CTRLS_ACT_DISABLED;
1✔
1330
  res = pr_run_ctrls(&m, NULL);
1✔
1331
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1332

1✔
1333
  mark_point();
1334
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1335
  ctrl->ctrls_flags &= ~PR_CTRLS_ACT_DISABLED;
1✔
1336
  ctrl->ctrls_flags &= ~PR_CTRLS_FL_REQUESTED;
1✔
1337
  res = pr_run_ctrls(&m, NULL);
1338
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1339

1✔
1340
  mark_point();
1✔
1341
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1342
  ctrl->ctrls_flags |= PR_CTRLS_FL_REQUESTED;
1✔
1343
  now = time(NULL);
1344
  ctrl->ctrls_when = now + 10;
1345
  res = pr_run_ctrls(&m, NULL);
1✔
1346
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1347

1348
  mark_point();
1✔
1349
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1350
  ctrl->ctrls_flags &= PR_CTRLS_FL_PENDING;
1✔
1351
  ctrl->ctrls_flags |= PR_CTRLS_FL_REQUESTED;
1✔
1352
  ctrl->ctrls_when = now - 10;
1353
  res = pr_run_ctrls(&m, "test2");
1354
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1355

1✔
1356
  mark_point();
1✔
1357
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1358
  ctrl->ctrls_flags |= PR_CTRLS_FL_REQUESTED;
1359
  res = pr_run_ctrls(&m, "test");
1360
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1361

1✔
1362
  mark_point();
1✔
1363
  res = pr_ctrls_unregister(NULL, action);
1364
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1365
    strerror(errno));
1✔
1366

1367
  (void) close(fd);
1368
}
1369
END_TEST
1✔
1370

1✔
1371
START_TEST (ctrls_reset_ctrls_test) {
1✔
1372
  int res;
1373
  const char *action, *desc;
1✔
1374

1✔
1375
  mark_point();
1✔
1376
  res = pr_ctrls_reset();
1✔
1377
  ck_assert_msg(res == 0, "Failed to reset ctrls: %s", strerror(errno));
1378

1379
  mark_point();
1✔
1380
  action = "test";
1✔
1381
  desc = "desc";
1✔
1382
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1383
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1384

1385
  mark_point();
1386
  res = pr_ctrls_reset();
1387
  ck_assert_msg(res == 0, "Failed to reset ctrls: %s", strerror(errno));
1✔
1388

1✔
1389
  mark_point();
1✔
1390
  res = pr_ctrls_unregister(NULL, action);
1391
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1392
    strerror(errno));
1393
}
1✔
1394
END_TEST
1✔
1395

1396
START_TEST (ctrls_accept_test) {
1397
  int fd, res;
1✔
1398

1✔
1399
  mark_point();
1✔
1400
  res = pr_ctrls_accept(-1, NULL, NULL, NULL, 0);
1401
  ck_assert_msg(res < 0, "Failed to handle bad fd");
1402
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1403
    strerror(errno), errno);
1✔
1404

1✔
1405
  mark_point();
1✔
1406
  fd = devnull_fd();
1✔
1407
  if (fd < 0) {
1408
    return;
1✔
1409
  }
1✔
1410

1✔
1411
  res = pr_ctrls_accept(fd, NULL, NULL, NULL, 5);
1✔
1412
  ck_assert_msg(res < 0, "Failed to handle no clients");
1413
  ck_assert_msg(errno = ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1414
    strerror(errno), errno);
1✔
1415

1✔
1416
  (void) close(fd);
1✔
1417
}
1✔
1418
END_TEST
1419

1✔
1420
START_TEST (ctrls_connect_test) {
1✔
1421
  int fd, res;
1✔
1422
  const char *socket_path;
1✔
1423

1424
  mark_point();
1✔
1425
  res = pr_ctrls_connect(NULL);
1✔
1426
  ck_assert_msg(res < 0, "Failed to handle null path");
1✔
1427
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1428
    strerror(errno), errno);
1429

1430
  mark_point();
1✔
1431
  socket_path = "/tmp/foo.sock";
1✔
1432
  res = pr_ctrls_connect(socket_path);
1✔
1433
  ck_assert_msg(res < 0, "Failed to handle nonexistent socket path");
1434
  ck_assert_msg(errno == ECONNREFUSED || errno == ENOENT,
1435
    "Expected ECONNREFUSED (%d) or ENOENT (%d), got %s (%d)", ECONNREFUSED,
1✔
1436
    ENOENT, strerror(errno), errno);
1✔
1437

1✔
1438
  mark_point();
1✔
1439
  fd = listen_unix(socket_path);
1✔
1440
  if (fd < 0) {
1✔
1441
    return;
1✔
1442
  }
1443

1✔
1444
  res = pr_ctrls_connect(socket_path);
1✔
1445
  ck_assert_msg(res >= 0, "Failed to connect to local socket: %s",
1✔
1446
    strerror(errno));
1447

1448
  (void) close(res);
1✔
1449
  (void) close(fd);
1✔
1450
  (void) unlink(socket_path);
1✔
1451
}
1✔
1452
END_TEST
1453

1✔
1454
START_TEST (ctrls_check_group_acl_test) {
1✔
1455
  int res;
1✔
1456
  gid_t gid;
1✔
1457
  ctrls_group_acl_t *group_acl;
1458

1459
  mark_point();
1✔
1460
  res = pr_ctrls_check_group_acl(0, NULL);
1✔
1461
  ck_assert_msg(res < 0, "Failed to handle null acl");
1✔
1462
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1463
    strerror(errno), errno);
1464

1✔
1465
  mark_point();
1✔
1466
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1✔
1467
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1468
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1469

1✔
1470
  mark_point();
1✔
1471
  group_acl->allow = TRUE;
1✔
1472
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1473
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1474

1475
  mark_point();
1✔
1476
  group_acl->ngids = 1;
1✔
1477
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1478
  ck_assert_msg(res == group_acl->allow, "Expected %d, got %d",
1479
    group_acl->allow, res);
1480

1✔
1481
  group_acl->allow = FALSE;
1✔
1482
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1483
  ck_assert_msg(res == group_acl->allow, "Expected %d, got %d",
1✔
1484
    group_acl->allow, res);
1✔
1485

1✔
1486
  mark_point();
1✔
1487
  gid = 1;
1488
  group_acl->allow = TRUE;
1✔
1489
  group_acl->gids = palloc(p, sizeof(gid_t) * 2);
1✔
1490
  ((gid_t *) group_acl->gids)[0] = gid;
1✔
1491
  res = pr_ctrls_check_group_acl(0, group_acl);
1492
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1493

1✔
1494
  res = pr_ctrls_check_group_acl(gid, group_acl);
1✔
1495
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1496
}
1497
END_TEST
1✔
1498

1✔
1499
START_TEST (ctrls_check_user_acl_test) {
1✔
1500
  int res;
1✔
1501
  uid_t uid;
1502
  ctrls_user_acl_t *user_acl;
1503

1✔
1504
  mark_point();
1✔
1505
  res = pr_ctrls_check_user_acl(0, NULL);
1✔
1506
  ck_assert_msg(res < 0, "Failed to handle null acl");
1✔
1507
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1508
    strerror(errno), errno);
1509

1510
  mark_point();
×
1511
  user_acl = pcalloc(p, sizeof(ctrls_user_acl_t));
×
1512
  res = pr_ctrls_check_user_acl(0, user_acl);
1513
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1514

1✔
1515
  mark_point();
1✔
1516
  user_acl->allow = TRUE;
1✔
1517
  res = pr_ctrls_check_user_acl(0, user_acl);
1✔
1518
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1519

1✔
1520
  mark_point();
1✔
1521
  user_acl->nuids = 1;
1522
  res = pr_ctrls_check_user_acl(0, user_acl);
1523
  ck_assert_msg(res == user_acl->allow, "Expected %d, got %d",
1524
    user_acl->allow, res);
1525

1✔
1526
  user_acl->allow = FALSE;
1✔
1527
  res = pr_ctrls_check_user_acl(0, user_acl);
1✔
1528
  ck_assert_msg(res == user_acl->allow, "Expected %d, got %d",
1✔
1529
    user_acl->allow, res);
1530

1531
  mark_point();
1✔
1532
  uid = 1;
1✔
1533
  user_acl->allow = TRUE;
1✔
1534
  user_acl->uids = palloc(p, sizeof(uid_t) * 2);
1✔
1535
  ((uid_t *) user_acl->uids)[0] = uid;
1✔
1536
  res = pr_ctrls_check_user_acl(0, user_acl);
1537
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1538

1✔
1539
  res = pr_ctrls_check_user_acl(uid, user_acl);
1✔
1540
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1541
}
1✔
1542
END_TEST
1✔
1543

1✔
1544
START_TEST (ctrls_init_acl_test) {
1✔
1545
  int res;
1546
  ctrls_acl_t *acl;
1547

1✔
1548
  mark_point();
1✔
1549
  res = pr_ctrls_init_acl(NULL);
1✔
1550
  ck_assert_msg(res < 0, "Failed to handle null acl");
1✔
1551
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1552
    strerror(errno), errno);
1553

1✔
1554
  mark_point();
1✔
1555
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
1556
  res = pr_ctrls_init_acl(acl);
1✔
1557
  ck_assert_msg(res == 0, "Failed to init acl: %s", strerror(errno));
1558
}
1✔
1559
END_TEST
1✔
1560

1✔
1561
static int test_action_cb(pr_ctrls_t *ctl, int reqargc, char **reqargv) {
1✔
1562
  return 0;
1563
}
1✔
1564

1✔
1565
START_TEST (ctrls_check_acl_test) {
1✔
1566
  int res;
1✔
1567
  pr_ctrls_t *ctrl;
1✔
1568
  pr_ctrls_cl_t *cl;
1✔
1569
  ctrls_acl_t *acl;
1570
  const char *action;
1✔
1571
  ctrls_acttab_t acttab[] = {
1✔
1572
    { "test", "desc", NULL, test_action_cb },
1✔
1573
    { NULL, NULL, NULL, NULL }
1✔
1574
  };
1575

1✔
1576
  mark_point();
1✔
1577
  res = pr_ctrls_check_acl(NULL, NULL, NULL);
1✔
1578
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
1579
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1580
    strerror(errno), errno);
1581

1✔
1582
  mark_point();
1✔
1583
  ctrl = pr_ctrls_alloc();
1✔
1584
  res = pr_ctrls_check_acl(ctrl, NULL, NULL);
1585
  ck_assert_msg(res < 0, "Failed to handle ctrl without client");
1✔
1586
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1587
    strerror(errno), errno);
1✔
1588

1✔
1589
  mark_point();
1590
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1591
  cl->cl_uid = cl->cl_gid = 1;
1✔
1592
  ctrl->ctrls_cl = cl;
1✔
1593
  res = pr_ctrls_check_acl(ctrl, NULL, NULL);
1✔
1594
  ck_assert_msg(res < 0, "Failed to handle null acttab");
1✔
1595
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1596
    strerror(errno), errno);
1597

1✔
1598
  mark_point();
1✔
1599
  res = pr_ctrls_check_acl(ctrl, acttab, NULL);
1✔
1600
  ck_assert_msg(res < 0, "Failed to handle null action");
1✔
1601
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1602
    strerror(errno), errno);
1✔
1603

1✔
1604
  mark_point();
1605
  action = "foobar";
1✔
1606
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1✔
1607
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1608

1✔
1609
  mark_point();
1610
  action = "test";
1✔
1611
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1✔
1612
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1613

1✔
1614
  mark_point();
1✔
1615
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1616
  res = pr_ctrls_init_acl(acl);
1617
  acttab[0].act_acl = acl;
1✔
1618
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1✔
1619
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1620

1✔
1621
  mark_point();
1✔
1622
  acl->acl_groups.ngids = 1;
1623
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1✔
1624
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1625

1✔
1626
  acl->acl_users.nuids = 1;
1✔
1627
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1628
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1629
}
1✔
1630
END_TEST
1✔
1631

1✔
1632
START_TEST (ctrls_parse_acl_test) {
1✔
1633
  char **res;
1634
  const char *names;
1635

1✔
1636
  mark_point();
1✔
1637
  res = pr_ctrls_parse_acl(NULL, NULL);
1✔
1638
  ck_assert_msg(res == NULL, "Failed to handle null pool");
1✔
1639
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1640
    strerror(errno), errno);
1641

1642
  mark_point();
1✔
1643
  res = pr_ctrls_parse_acl(p, NULL);
1✔
1644
  ck_assert_msg(res == NULL, "Failed to handle null ACL text");
1✔
1645
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1646
    strerror(errno), errno);
1✔
1647

1648
  mark_point();
1649
  names = "foo";
1✔
1650
  res = pr_ctrls_parse_acl(p, names);
1✔
1651
  ck_assert_msg(res != NULL, "Failed to parse ACL '%s': %s", names,
1✔
1652
    strerror(errno));
1✔
1653
  ck_assert_msg(strcmp(res[0], "foo") == 0, "Expected 'foo', got '%s'", res[0]);
1✔
1654
  ck_assert_msg(res[1] == NULL, "Expected NULL, got %p", res[1]);
1655

1656
  mark_point();
1✔
1657
  names = "foo,'Bar',BAZ";
1658
  res = pr_ctrls_parse_acl(p, names);
1✔
1659
  ck_assert_msg(res != NULL, "Failed to parse ACL '%s': %s", names,
1660
    strerror(errno));
1✔
1661
  ck_assert_msg(strcmp(res[0], "foo") == 0, "Expected 'foo', got '%s'", res[0]);
1✔
1662
  ck_assert_msg(strcmp(res[1], "'Bar'") == 0, "Expected 'Bar', got '%s'", res[1]);
1✔
1663
  ck_assert_msg(strcmp(res[2], "BAZ") == 0, "Expected 'BAZ', got '%s'", res[2]);
1✔
1664
  ck_assert_msg(res[3] == NULL, "Expected NULL, got %p", res[3]);
1✔
1665
}
1✔
1666
END_TEST
1✔
1667

1668
START_TEST (ctrls_set_group_acl_test) {
1✔
1669
  int res;
1670
  ctrls_group_acl_t *group_acl;
1✔
1671
  const char *allow;
1672
  char *grouplist;
1✔
1673

1674
  mark_point();
1675
  res = pr_ctrls_set_group_acl(NULL, NULL, NULL, NULL);
1✔
1676
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
1677
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1678
    strerror(errno), errno);
1✔
1679

1✔
1680
  mark_point();
1681
  res = pr_ctrls_set_group_acl(p, NULL, NULL, NULL);
1✔
1682
  ck_assert_msg(res < 0, "Failed to handle null group_acl");
1✔
1683
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1684
    strerror(errno), errno);
1✔
1685

1686
  mark_point();
1687
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1✔
1688
  res = pr_ctrls_set_group_acl(p, group_acl, NULL, NULL);
1✔
1689
  ck_assert_msg(res < 0, "Failed to handle null allow");
1✔
1690
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1691
    strerror(errno), errno);
1692

1693
  mark_point();
1✔
1694
  allow = "allow";
1✔
1695
  res = pr_ctrls_set_group_acl(p, group_acl, allow, NULL);
1✔
1696
  ck_assert_msg(res < 0, "Failed to handle null grouplist");
1✔
1697
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1698
    strerror(errno), errno);
1699

1700
  mark_point();
1✔
1701
  grouplist = "foo,bar,baz,wheel";
1✔
1702
  res = pr_ctrls_set_group_acl(p, group_acl, allow, grouplist);
1✔
1703
  ck_assert_msg(res == 0, "Failed to set group acl: %s", strerror(errno));
1✔
1704
  ck_assert_msg(group_acl->allow == TRUE, "Expected TRUE, got %d",
1✔
1705
    group_acl->allow);
1706
  /* Note that we expect zero here, because of name/GID lookup failures. */
1707
  ck_assert_msg(group_acl->ngids == 0, "Expected 0, got %d",
1✔
1708
    group_acl->ngids);
1✔
1709
  ck_assert_msg(group_acl->gids != NULL, "Got NULL unexpectedly");
1✔
1710

1✔
1711
  mark_point();
1✔
1712
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1713
  allow = "deny";
1714
  grouplist = "foo,*";
1✔
1715
  res = pr_ctrls_set_group_acl(p, group_acl, allow, grouplist);
1✔
1716
  ck_assert_msg(res == 0, "Failed to set group acl: %s", strerror(errno));
1717
  ck_assert_msg(group_acl->allow == FALSE, "Expected FALSE, got %d",
1✔
1718
    group_acl->allow);
1✔
1719
  ck_assert_msg(group_acl->ngids == 1, "Expected 1, got %d",
1✔
1720
    group_acl->ngids);
1✔
1721
  ck_assert_msg(group_acl->gids == NULL, "Expected NULL, got %p",
1✔
1722
    group_acl->gids);
1✔
1723
}
1✔
1724
END_TEST
1725

1✔
1726
START_TEST (ctrls_set_user_acl_test) {
1✔
1727
  int res;
1728
  ctrls_user_acl_t *user_acl;
1✔
1729
  const char *allow;
1730
  char *userlist;
1731

1✔
1732
  mark_point();
1✔
1733
  res = pr_ctrls_set_user_acl(NULL, NULL, NULL, NULL);
1✔
1734
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
1735
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1736
    strerror(errno), errno);
1✔
1737

1✔
1738
  mark_point();
1✔
1739
  res = pr_ctrls_set_user_acl(p, NULL, NULL, NULL);
1740
  ck_assert_msg(res < 0, "Failed to handle null user_acl");
1741
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1742
    strerror(errno), errno);
1743

1✔
1744
  mark_point();
1✔
1745
  user_acl = pcalloc(p, sizeof(ctrls_user_acl_t));
1✔
1746
  res = pr_ctrls_set_user_acl(p, user_acl, NULL, NULL);
1✔
1747
  ck_assert_msg(res < 0, "Failed to handle null allow");
1748
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1749
    strerror(errno), errno);
1✔
1750

1✔
1751
  mark_point();
1✔
1752
  allow = "allow";
1✔
1753
  res = pr_ctrls_set_user_acl(p, user_acl, allow, NULL);
1754
  ck_assert_msg(res < 0, "Failed to handle null userlist");
1755
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1756
    strerror(errno), errno);
1✔
1757

1✔
1758
  mark_point();
1✔
1759
  userlist = "foo,bar,baz,root";
1760
  res = pr_ctrls_set_user_acl(p, user_acl, allow, userlist);
1761
  ck_assert_msg(res == 0, "Failed to set user acl: %s", strerror(errno));
1✔
1762
  ck_assert_msg(user_acl->allow == TRUE, "Expected TRUE, got %d",
1✔
1763
    user_acl->allow);
1✔
1764
  /* Note that we expect zero here, because of name/UID lookup failures. */
1✔
1765
  ck_assert_msg(user_acl->nuids == 0, "Expected 0, got %d", user_acl->nuids);
1766
  ck_assert_msg(user_acl->uids != NULL, "Got NULL unexpectedly");
1767

1✔
1768
  mark_point();
1✔
1769
  user_acl = pcalloc(p, sizeof(ctrls_user_acl_t));
1✔
1770
  allow = "deny";
1✔
1771
  userlist = "foo,*";
1✔
1772
  res = pr_ctrls_set_user_acl(p, user_acl, allow, userlist);
1773
  ck_assert_msg(res == 0, "Failed to set user acl: %s", strerror(errno));
1774
  ck_assert_msg(user_acl->allow == FALSE, "Expected FALSE, got %d",
1✔
1775
    user_acl->allow);
1✔
1776
  ck_assert_msg(user_acl->nuids == 1, "Expected 1, got %d", user_acl->nuids);
1✔
1777
  ck_assert_msg(user_acl->uids == NULL, "Expected NULL, got %p",
1✔
1778
    user_acl->uids);
1✔
1779
}
1780
END_TEST
1781

1✔
1782
START_TEST (ctrls_set_module_acls_test) {
1✔
1783
  char *res, *list;
1✔
1784
  const char *allow, *type;
1✔
1785
  ctrls_acl_t *acl;
1✔
1786
  char *good_actions[] = { "test", NULL };
1787
  char *bad_actions[] = { "bar", "baz", NULL };
1788
  char *all_actions[] = { "all", NULL };
1✔
1789
  ctrls_acttab_t acttab[] = {
1✔
1790
    { "test", "desc", NULL, test_action_cb },
1✔
1791
    { NULL, NULL, NULL, NULL }
1✔
1792
  };
1✔
1793

1794
  mark_point();
1✔
1795
  res = pr_ctrls_set_module_acls(NULL, NULL, NULL, NULL, NULL, NULL);
1796
  ck_assert_msg(res == NULL, "Failed to handle null acttab");
1✔
1797
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1798
    strerror(errno), errno);
1✔
1799

1800
  mark_point();
1801
  res = pr_ctrls_set_module_acls(acttab, NULL, NULL, NULL, NULL, NULL);
1✔
1802
  ck_assert_msg(res == NULL, "Failed to handle null acl_pool");
1✔
1803
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1804
    strerror(errno), errno);
1✔
1805

1806
  mark_point();
1✔
1807
  res = pr_ctrls_set_module_acls(acttab, p, NULL, NULL, NULL, NULL);
1✔
1808
  ck_assert_msg(res == NULL, "Failed to handle null actions");
1✔
1809
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1810
    strerror(errno), errno);
1811

1✔
1812
  mark_point();
1✔
1813
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, NULL, NULL, NULL);
1✔
1814
  ck_assert_msg(res == NULL, "Failed to handle null allow");
1✔
1815
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1816
    strerror(errno), errno);
1817

1✔
1818
  mark_point();
1✔
1819
  allow = "allow";
1✔
1820
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, NULL, NULL);
1✔
1821
  ck_assert_msg(res == NULL, "Failed to handle null type");
1✔
1822
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1823
    strerror(errno), errno);
1✔
1824

1✔
1825
  mark_point();
1✔
1826
  type = "test";
1827
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, type, NULL);
1828
  ck_assert_msg(res == NULL, "Failed to handle null list");
1829
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1830
    strerror(errno), errno);
1✔
1831

1✔
1832
  mark_point();
1✔
1833
  list = "foo,bar,baz";
1✔
1834
  res = pr_ctrls_set_module_acls(acttab, p, bad_actions, allow, type, list);
1835
  ck_assert_msg(res == NULL, "Failed to handle invalid type '%s'", type);
1836
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1837
    strerror(errno), errno);
1✔
1838

1✔
1839
  mark_point();
1✔
1840
  type = "user";
1841
  res = pr_ctrls_set_module_acls(acttab, p, bad_actions, allow, type, list);
1842
  ck_assert_msg(res != NULL, "Failed to handle invalid action");
1✔
1843
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1844
    strerror(errno), errno);
1✔
1845
  ck_assert_msg(strcmp(res, "bar") == 0, "Expected 'bar', got '%s'", res);
1✔
1846

1847
  mark_point();
1848
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
1849
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
1✔
1850
    "Failed to initialize acl: %s", strerror(errno));
1851

1✔
1852
  acttab[0].act_acl = acl;
1✔
1853
  type = "group";
1854
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, type, list);
1855
  ck_assert_msg(res == NULL, "Failed to handle good action: %s", strerror(errno));
1✔
1856

1✔
1857
  mark_point();
1✔
1858
  type = "user";
1859
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, type, list);
1✔
1860
  ck_assert_msg(res == NULL, "Failed to handle good action: %s", strerror(errno));
1✔
1861

1862
  mark_point();
1863
  res = pr_ctrls_set_module_acls(acttab, p, all_actions, allow, type, list);
1✔
1864
  ck_assert_msg(res == NULL, "Failed to handle all actions: %s", strerror(errno));
1✔
1865
}
1✔
1866
END_TEST
1867

1✔
1868
START_TEST (ctrls_set_module_acls2_test) {
1✔
1869
  int res;
1870
  char *list;
1871
  const char *allow, *type, *bad_action = NULL;
1✔
1872
  ctrls_acl_t *acl;
1✔
1873
  char *good_actions[] = { "test", NULL };
1✔
1874
  char *bad_actions[] = { "bar", "baz", NULL };
1875
  char *all_actions[] = { "all", NULL };
1✔
1876
  ctrls_acttab_t acttab[] = {
1✔
1877
    { "test", "desc", NULL, test_action_cb },
1878
    { NULL, NULL, NULL, NULL }
1879
  };
1✔
1880

1✔
1881
  mark_point();
1882
  res = pr_ctrls_set_module_acls2(NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1✔
1883
  ck_assert_msg(res < 0, "Failed to handle null acttab");
1✔
1884
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1885
    strerror(errno), errno);
1886

1✔
1887
  mark_point();
1✔
1888
  res = pr_ctrls_set_module_acls2(acttab, NULL, NULL, NULL, NULL, NULL, NULL);
1✔
1889
  ck_assert_msg(res < 0, "Failed to handle null acl_pool");
1890
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1891
    strerror(errno), errno);
1✔
1892

1893
  mark_point();
1✔
1894
  res = pr_ctrls_set_module_acls2(acttab, p, NULL, NULL, NULL, NULL, NULL);
1895
  ck_assert_msg(res < 0, "Failed to handle null actions");
1896
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1897
    strerror(errno), errno);
1✔
1898

1✔
1899
  mark_point();
1900
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, NULL, NULL, NULL,
1901
    NULL);
1✔
1902
  ck_assert_msg(res < 0, "Failed to handle null allow");
1✔
1903
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1904
    strerror(errno), errno);
1905

1✔
1906
  mark_point();
1907
  allow = "allow";
1✔
1908
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, NULL, NULL,
1✔
1909
    NULL);
1✔
1910
  ck_assert_msg(res < 0, "Failed to handle null type");
1911
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1912
    strerror(errno), errno);
1913

1✔
1914
  mark_point();
1✔
1915
  type = "test";
1916
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, type, NULL,
1✔
1917
    NULL);
1✔
1918
  ck_assert_msg(res < 0, "Failed to handle null list");
1919
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1920
    strerror(errno), errno);
1✔
1921

1✔
1922
  mark_point();
1✔
1923
  list = "foo,bar,baz";
1✔
1924
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
1✔
1925
    NULL);
1✔
1926
  ck_assert_msg(res < 0, "Failed to handle null bad_action");
1927
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1928
    strerror(errno), errno);
1929

1✔
1930
  mark_point();
1931
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
1✔
1932
    &bad_action);
1✔
1933
  ck_assert_msg(res < 0, "Failed to handle invalid type '%s'", type);
1✔
1934
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1935
    strerror(errno), errno);
1936

1937
  mark_point();
1✔
1938
  type = "user";
1✔
1939
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
1✔
1940
    &bad_action);
1✔
1941
  ck_assert_msg(res < 0, "Failed to handle invalid action");
1942
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1943
    strerror(errno), errno);
1✔
1944
  ck_assert_msg(strcmp(bad_action, "bar") == 0,
1✔
1945
    "Expected 'bar', got '%s'", bad_action);
1✔
1946

1✔
1947
  mark_point();
1948
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1949
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
1✔
1950
    "Failed to initialize acl: %s", strerror(errno));
1✔
1951

1✔
1952
  acttab[0].act_acl = acl;
1✔
1953
  type = "group";
1✔
1954
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, type, list,
1955
    &bad_action);
1✔
1956
  ck_assert_msg(res == 0, "Failed to handle good action: %s", strerror(errno));
1957

1✔
1958
  mark_point();
1✔
1959
  type = "user";
1✔
1960
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, type, list,
1961
    &bad_action);
1✔
1962
  ck_assert_msg(res == 0, "Failed to handle good action: %s", strerror(errno));
1✔
1963

1✔
1964
  mark_point();
1965
  res = pr_ctrls_set_module_acls2(acttab, p, all_actions, allow, type, list,
1✔
1966
    &bad_action);
1967
  ck_assert_msg(res == 0, "Failed to handle all actions: %s", strerror(errno));
1968
}
1✔
1969
END_TEST
1✔
1970

1✔
1971
START_TEST (ctrls_unregister_module_actions_test) {
1✔
1972
  char *res;
1✔
1973
  char *good_actions[] = { "test", NULL };
1✔
1974
  char *bad_actions[] = { "bar", "baz", NULL };
1✔
1975
  ctrls_acl_t *acl;
1976
  ctrls_acttab_t acttab[] = {
1977
    { "test", "desc", NULL, test_action_cb },
1978
    { NULL, NULL, NULL, NULL }
1✔
1979
  };
1980
  module m;
1✔
1981

1✔
1982
  mark_point();
1✔
1983
  res = pr_ctrls_unregister_module_actions(NULL, NULL, NULL);
1✔
1984
  ck_assert_msg(res == NULL, "Failed to handle null acttab");
1985
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1986
    strerror(errno), errno);
1✔
1987

1✔
1988
  mark_point();
1✔
1989
  res = pr_ctrls_unregister_module_actions(acttab, NULL, NULL);
1✔
1990
  ck_assert_msg(res == NULL, "Failed to handle null actions");
1991
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1992
    strerror(errno), errno);
1✔
1993

1✔
1994
  mark_point();
1✔
1995
  res = pr_ctrls_unregister_module_actions(acttab, good_actions, NULL);
1✔
1996
  ck_assert_msg(res == NULL, "Failed to handle null module");
1997
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1998
    strerror(errno), errno);
1✔
1999

1✔
2000
  mark_point();
1✔
2001
  m.name = "test";
1✔
2002
  res = pr_ctrls_unregister_module_actions(acttab, bad_actions, &m);
1✔
2003
  ck_assert_msg(res != NULL, "Failed to handle invalid action");
2004
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2005
    strerror(errno), errno);
1✔
2006
  ck_assert_msg(strcmp(res, "bar") == 0, "Expected 'bar', got '%s'", res);
1✔
2007

2008
  mark_point();
1✔
2009
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
2010
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
2011
    "Failed to initialize acl: %s", strerror(errno));
1✔
2012
  acttab[0].act_acl = acl;
1✔
2013
  res = pr_ctrls_unregister_module_actions(acttab, good_actions, &m);
2014
  ck_assert_msg(res == NULL, "Failed to handle valid action: %s",
2015
    strerror(errno));
1✔
2016
}
1✔
2017
END_TEST
1✔
2018

2019
START_TEST (ctrls_unregister_module_actions2_test) {
1✔
2020
  int res;
1✔
2021
  const char *bad_action = NULL;
2022
  char *good_actions[] = { "test", NULL };
1✔
2023
  char *bad_actions[] = { "bar", "baz", NULL };
1✔
2024
  ctrls_acl_t *acl;
2025
  ctrls_acttab_t acttab[] = {
2026
    { "test", "desc", NULL, test_action_cb },
1✔
2027
    { NULL, NULL, NULL, NULL }
1✔
2028
  };
2029
  module m;
1✔
2030

1✔
2031
  mark_point();
1✔
2032
  res = pr_ctrls_unregister_module_actions2(NULL, NULL, NULL, NULL);
1✔
2033
  ck_assert_msg(res < 0, "Failed to handle null acttab");
2034
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2035
    strerror(errno), errno);
1✔
2036

1✔
2037
  mark_point();
1✔
2038
  res = pr_ctrls_unregister_module_actions2(acttab, NULL, NULL, NULL);
1✔
2039
  ck_assert_msg(res < 0, "Failed to handle null actions");
2040
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2041
    strerror(errno), errno);
2042

2043
  mark_point();
1✔
2044
  res = pr_ctrls_unregister_module_actions2(acttab, good_actions, NULL, NULL);
1✔
2045
  ck_assert_msg(res < 0, "Failed to handle null module");
2046
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2047
    strerror(errno), errno);
1✔
2048

1✔
2049
  mark_point();
1✔
2050
  m.name = "test";
1✔
2051
  res = pr_ctrls_unregister_module_actions2(acttab, bad_actions, &m, NULL);
2052
  ck_assert_msg(res < 0, "Failed to handle null bad_action");
1✔
2053
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2054
    strerror(errno), errno);
1✔
2055

2056
  mark_point();
2057
  res = pr_ctrls_unregister_module_actions2(acttab, bad_actions, &m,
2058
    &bad_action);
1✔
2059
  ck_assert_msg(res < 0, "Failed to handle invalid action");
1✔
2060
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
2061
    strerror(errno), errno);
2062
  ck_assert_msg(bad_action != NULL, "Expected bad_action, got NULL");
2063
  ck_assert_msg(strcmp(bad_action, "bar") == 0,
1✔
2064
    "Expected 'bar', got '%s'", bad_action);
1✔
2065

1✔
2066
  mark_point();
2067
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
2068
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
1✔
2069
    "Failed to initialize acl: %s", strerror(errno));
1✔
2070
  acttab[0].act_acl = acl;
2071
  res = pr_ctrls_unregister_module_actions2(acttab, good_actions, &m,
1✔
2072
    &bad_action);
2073
  ck_assert_msg(res == 0, "Failed to handle valid action: %s", strerror(errno));
2074
}
2075
END_TEST
2076

2077
START_TEST (ctrls_set_logfd_test) {
889✔
2078
  int fd, res;
889✔
2079

889✔
2080
  mark_point();
2081
  fd = 0;
889✔
2082
  res = pr_ctrls_set_logfd(fd);
889✔
2083
  ck_assert_msg(res == 0, "Failed to set ctrls log fd %d: %s", fd,
2084
     strerror(errno));
2085

889✔
2086
  mark_point();
2087
  fd = -1;
889✔
2088
  res = pr_ctrls_set_logfd(fd);
889✔
2089
  ck_assert_msg(res == 0, "Failed to set ctrls log fd %d: %s", fd,
889✔
2090
     strerror(errno));
889✔
2091
}
889✔
2092
END_TEST
889✔
2093

889✔
2094
START_TEST (ctrls_log_test) {
889✔
2095
  int fd, res;
889✔
2096

889✔
2097
  mark_point();
889✔
2098
  fd = -1;
889✔
2099
  pr_ctrls_set_logfd(fd);
889✔
2100
  res = pr_ctrls_log(NULL, NULL);
2101
  ck_assert_msg(res == 0, "Failed to handle bad logfd: %s", strerror(errno));
889✔
2102

889✔
2103
  mark_point();
889✔
2104
  fd = devnull_fd();
889✔
2105
  if (fd < 0) {
889✔
2106
    return;
889✔
2107
  }
889✔
2108

889✔
2109
  pr_ctrls_set_logfd(fd);
2110
  res = pr_ctrls_log(NULL, NULL);
2111
  ck_assert_msg(res == 0, "Failed to handle bad module_version: %s",
889✔
2112
    strerror(errno));
889✔
2113

889✔
2114
  mark_point();
889✔
2115
  res = pr_ctrls_log("test", NULL);
889✔
2116
  ck_assert_msg(res == 0, "Failed to handle null fmt: %s", strerror(errno));
889✔
2117

889✔
2118
  mark_point();
889✔
2119
  res = pr_ctrls_log("test", "%s", "foo bar baz");
889✔
2120
  ck_assert_msg(res == 0, "Failed to handle valid fmt: %s", strerror(errno));
889✔
2121

889✔
2122
  (void) close(fd);
889✔
2123
}
889✔
2124
END_TEST
2125

2126
#endif /* PR_USE_CTRLS */
889✔
2127

889✔
2128
Suite *tests_get_ctrls_suite(void) {
2129
  Suite *suite;
2130
  TCase *testcase;
2131

2132
  suite = suite_create("ctrls");
2133
  testcase = tcase_create("base");
2134

2135
#if defined(PR_USE_CTRLS)
2136
  tcase_add_checked_fixture(testcase, set_up, tear_down);
2137

2138
  tcase_add_test(testcase, ctrls_alloc_free_test);
2139
  tcase_add_test(testcase, ctrls_unregister_test);
2140
  tcase_add_test(testcase, ctrls_register_test);
2141
  tcase_add_test(testcase, ctrls_add_arg_test);
2142
  tcase_add_test(testcase, ctrls_add_response_test);
2143
  tcase_add_test(testcase, ctrls_copy_args_test);
2144
  tcase_add_test(testcase, ctrls_copy_resps_test);
2145
  tcase_add_test(testcase, ctrls_send_request_test);
2146
  tcase_add_test(testcase, ctrls_send_response_test);
2147
  tcase_add_test(testcase, ctrls_flush_response_test);
2148
  tcase_add_test(testcase, ctrls_recv_request_invalid_test);
2149
  tcase_add_test(testcase, ctrls_recv_request_too_large_test);
2150
  tcase_add_test(testcase, ctrls_recv_request_valid_test);
2151
  tcase_add_test(testcase, ctrls_recv_response_test);
2152
  tcase_add_test(testcase, ctrls_recv_response_too_large_test);
2153

2154
  tcase_add_test(testcase, ctrls_issock_unix_test);
2155
  tcase_add_test(testcase, ctrls_get_registered_actions_test);
2156
  tcase_add_test(testcase, ctrls_set_registered_actions_test);
2157
  tcase_add_test(testcase, ctrls_check_actions_test);
2158
  tcase_add_test(testcase, ctrls_run_ctrls_test);
2159
  tcase_add_test(testcase, ctrls_reset_ctrls_test);
2160
  tcase_add_test(testcase, ctrls_accept_test);
2161
  tcase_add_test(testcase, ctrls_connect_test);
2162

2163
  /* mod_ctrls */
2164
  tcase_add_test(testcase, ctrls_check_group_acl_test);
2165
  tcase_add_test(testcase, ctrls_check_user_acl_test);
2166
  tcase_add_test(testcase, ctrls_init_acl_test);
2167
  tcase_add_test(testcase, ctrls_check_acl_test);
2168
  tcase_add_test(testcase, ctrls_parse_acl_test);
2169
  tcase_add_test(testcase, ctrls_set_group_acl_test);
2170
  tcase_add_test(testcase, ctrls_set_user_acl_test);
2171
  tcase_add_test(testcase, ctrls_set_module_acls_test);
2172
  tcase_add_test(testcase, ctrls_set_module_acls2_test);
2173
  tcase_add_test(testcase, ctrls_unregister_module_actions_test);
2174
  tcase_add_test(testcase, ctrls_unregister_module_actions2_test);
2175
  tcase_add_test(testcase, ctrls_set_logfd_test);
2176
  tcase_add_test(testcase, ctrls_log_test);
2177
#endif /* PR_USE_CTRLS */
2178

2179
  suite_add_tcase(suite, testcase);
2180
  return suite;
2181
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc