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

proftpd / proftpd / 21452178162

28 Jan 2026 07:22PM UTC coverage: 93.026% (+0.4%) from 92.638%
21452178162

push

github

51330 of 55178 relevant lines covered (93.03%)

222.09 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 ctrls.c */
102
static int connect_unix(int *fd) {
103
  int fds[2], res;
1✔
104

1✔
105
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
1✔
106
    return -1;
107
  }
108

109
  *fd = fds[1];
110
  return fds[0];
111
}
112

1✔
113
/* Largely copied from mod_ctrls. */
1✔
114
static int listen_unix(const char *path) {
×
115
  int fd = -1, socklen = 0;
×
116
  struct sockaddr_un sock;
117
#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \
118
    !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS)
1✔
119
  int opt = 1;
1✔
120
  socklen_t optlen = sizeof(opt);
1✔
121
#endif /* !LOCAL_CREDS */
1✔
122

123
  fd = socket(AF_UNIX, SOCK_STREAM, 0);
1✔
124
  if (fd < 0) {
1✔
125
    fprintf(stderr, "error creating local socket: %s\n", strerror(errno));
×
126
    return -1;
×
127
  }
×
128

×
129
  (void) unlink(path);
130
  memset(&sock, 0, sizeof(sock));
131
  sock.sun_family = AF_UNIX;
1✔
132
  sstrncpy(sock.sun_path, path, sizeof(sock.sun_path));
×
133

×
134
  socklen = sizeof(sock);
×
135
  if (bind(fd, (struct sockaddr *) &sock, socklen) < 0) {
136
    fprintf(stderr, "error binding local socket to path '%s': %s\n", path,
137
      strerror(errno));
138
    (void) close(fd);
139
    return -1;
140
  }
141

142
  if (listen(fd, 5) < 0) {
143
    fprintf(stderr, "error listening on local socket: %s\n", strerror(errno));
144
    (void) close(fd);
145
    return -1;
146
  }
147

148
#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \
149
    !defined(HAVE_GETPEERUCRED) && defined(LOCAL_CREDS)
150
  /* Set the LOCAL_CREDS socket option. */
1✔
151
  if (setsockopt(fd, 0, LOCAL_CREDS, &opt, optlen) < 0) {
1✔
152
    fprintf(stderr, "error enabling LOCAL_CREDS: %s\n", strerror(errno));
1✔
153
  }
154
#endif /* !LOCAL_CREDS */
1✔
155

1✔
156
  return fd;
1✔
157
}
1✔
158

159
/* Tests */
160

1✔
161
START_TEST (ctrls_alloc_free_test) {
1✔
162
  int res;
1✔
163
  pr_ctrls_t *ctrl, *ctrl2, *ctrl3;
1✔
164

1✔
165
  mark_point();
166
  res = pr_ctrls_free(NULL);
1✔
167
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
168
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
169
    strerror(errno), errno);
1✔
170

1✔
171
  mark_point();
172
  ctrl = pr_ctrls_alloc();
173
  ck_assert_msg(ctrl != NULL, "Failed to allocate ctrl: %s", strerror(errno));
1✔
174
  res = pr_ctrls_free(ctrl);
1✔
175
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
1✔
176

1✔
177
  mark_point();
1✔
178
  ctrl = pr_ctrls_alloc();
1✔
179
  ck_assert_msg(ctrl != NULL, "Failed to allocate ctrl: %s", strerror(errno));
1✔
180
  res = pr_ctrls_free(ctrl);
1✔
181
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
182

1✔
183
  /* LIFO order */
1✔
184
  mark_point();
1✔
185
  ctrl = pr_ctrls_alloc();
1✔
186
  ctrl2 = pr_ctrls_alloc();
1✔
187
  ck_assert_msg(ctrl2 != NULL, "Failed to allocate ctrl2: %s", strerror(errno));
1✔
188
  ctrl2->ctrls_tmp_pool = make_sub_pool(p);
189
  ctrl3 = pr_ctrls_alloc();
190
  ck_assert_msg(ctrl3 != NULL, "Failed to allocate ctrl3: %s", strerror(errno));
1✔
191
  ctrl3->ctrls_tmp_pool = make_sub_pool(p);
1✔
192

1✔
193
  res = pr_ctrls_free(ctrl3);
1✔
194
  ck_assert_msg(res == 0, "Failed to free ctrl3 %s", strerror(errno));
1✔
195
  res = pr_ctrls_free(ctrl2);
1✔
196
  ck_assert_msg(res == 0, "Failed to free ctrl2: %s", strerror(errno));
1✔
197
  res = pr_ctrls_free(ctrl);
1✔
198
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
199

1✔
200
  /* FIFO order */
1✔
201
  mark_point();
1✔
202
  ctrl = pr_ctrls_alloc();
1✔
203
  ctrl2 = pr_ctrls_alloc();
1✔
204
  ck_assert_msg(ctrl2 != NULL, "Failed to allocate ctrl2: %s", strerror(errno));
1✔
205
  ctrl2->ctrls_tmp_pool = make_sub_pool(p);
1✔
206
  ctrl3 = pr_ctrls_alloc();
207
  ck_assert_msg(ctrl3 != NULL, "Failed to allocate ctrl3: %s", strerror(errno));
208
  ctrl3->ctrls_tmp_pool = make_sub_pool(p);
1✔
209

1✔
210
  res = pr_ctrls_free(ctrl);
211
  ck_assert_msg(res == 0, "Failed to free ctrl: %s", strerror(errno));
1✔
212
  res = pr_ctrls_free(ctrl2);
1✔
213
  ck_assert_msg(res == 0, "Failed to free ctrl2: %s", strerror(errno));
1✔
214
  res = pr_ctrls_free(ctrl3);
1✔
215
  ck_assert_msg(res == 0, "Failed to free ctrl3 %s", strerror(errno));
216
}
1✔
217
END_TEST
218

219
START_TEST (ctrls_unregister_test) {
1✔
220
  int res;
1✔
221

222
  mark_point();
223
  res = pr_ctrls_unregister(NULL, NULL);
×
224
  ck_assert_msg(res < 0, "Failed to handle lack of registered actions");
×
225
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
226
    strerror(errno), errno);
227
}
1✔
228
END_TEST
1✔
229

1✔
230
static int ctrls_test_cb(pr_ctrls_t *ctrl, int reqargc, char **reqargv) {
1✔
231
  return 0;
232
}
1✔
233

1✔
234
static int ctrls_test2_cb(pr_ctrls_t *ctrl, int reqargc, char **reqargv) {
1✔
235
  return 0;
1✔
236
}
237

238
START_TEST (ctrls_register_test) {
1✔
239
  int res;
1✔
240
  const char *action = NULL, *desc = NULL;
1✔
241
  module m;
1✔
242

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

1✔
249
  mark_point();
1✔
250
  action = "test";
251
  res = pr_ctrls_register(NULL, action, NULL, NULL);
252
  ck_assert_msg(res < 0, "Failed to handle null desc");
1✔
253
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
254
    strerror(errno), errno);
1✔
255

256
  mark_point();
1✔
257
  desc = "desc";
1✔
258
  res = pr_ctrls_register(NULL, action, desc, NULL);
1✔
259
  ck_assert_msg(res < 0, "Failed to handle null callback");
260
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
261
    strerror(errno), errno);
1✔
262

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

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

1✔
272
  mark_point();
273
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
274
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
275

276
  m.name = "test";
1✔
277
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
278
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
279

1✔
280
  mark_point();
1✔
281
  res = pr_ctrls_unregister(NULL, action);
282
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
283
    strerror(errno));
1✔
284
}
1✔
285
END_TEST
1✔
286

287
START_TEST (ctrls_add_arg_test) {
288
  int res;
1✔
289
  pr_ctrls_t *ctrl;
1✔
290
  char buf[4];
1✔
291
  size_t buflen;
1✔
292

1✔
293
  mark_point();
294
  res = pr_ctrls_add_arg(NULL, NULL, 0);
295
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
296
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
297
    strerror(errno), errno);
298

299
  mark_point();
1✔
300
  ctrl = pr_ctrls_alloc();
1✔
301
  res = pr_ctrls_add_arg(ctrl, NULL, 0);
1✔
302
  ck_assert_msg(res < 0, "Failed to handle null arg");
1✔
303
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
304
    strerror(errno), errno);
1✔
305

1✔
306
  mark_point();
1✔
307
  ctrl = pr_ctrls_alloc();
308

309
  /* Provide an arg that uses unprintable ASCII. */
1✔
310
  buf[0] = 'a';
1✔
311
  buf[1] = 'b';
1✔
312
  buf[2] = -120;
1✔
313
  buflen = 3;
1✔
314

315
  res = pr_ctrls_add_arg(ctrl, buf, buflen);
1✔
316
  ck_assert_msg(res < 0, "Failed to handle bad arg");
1✔
317
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
318
    strerror(errno), errno);
319

320
  mark_point();
1✔
321
  buf[0] = 'a';
1✔
322
  buf[1] = 'B';
1✔
323
  buf[2] = '1';
324
  buflen = 3;
1✔
325

1✔
326
  res = pr_ctrls_add_arg(ctrl, buf, buflen);
1✔
327
  ck_assert_msg(res == 0, "Failed to add ctrl arg: %s", strerror(errno));
1✔
328
}
329
END_TEST
330

1✔
331
START_TEST (ctrls_add_response_test) {
1✔
332
  int res;
1✔
333
  pr_ctrls_t *ctrl;
1✔
334

1✔
335
  mark_point();
336
  res = pr_ctrls_add_response(NULL, NULL);
337
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
338
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
339
    strerror(errno), errno);
1✔
340

1✔
341
  mark_point();
342
  ctrl = pr_ctrls_alloc();
343
  res = pr_ctrls_add_response(ctrl, NULL);
1✔
344
  ck_assert_msg(res < 0, "Failed to handle null fmt");
1✔
345
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
346
    strerror(errno), errno);
347

1✔
348
  mark_point();
1✔
349
  res = pr_ctrls_add_response(ctrl, "%s", "foo");
1✔
350
  ck_assert_msg(res == 0, "Failed to add ctrl response: %s", strerror(errno));
1✔
351
}
352
END_TEST
353

1✔
354
START_TEST (ctrls_copy_args_test) {
1✔
355
  int res;
1✔
356
  pr_ctrls_t *src_ctrl, *dst_ctrl;
1✔
357

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

1✔
364
  mark_point();
365
  src_ctrl = pr_ctrls_alloc();
366
  res = pr_ctrls_copy_args(src_ctrl, NULL);
1✔
367
  ck_assert_msg(res < 0, "Failed to handle null dst ctrl");
1✔
368
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
369
    strerror(errno), errno);
1✔
370

371
  mark_point();
1✔
372
  res = pr_ctrls_copy_args(src_ctrl, src_ctrl);
1✔
373
  ck_assert_msg(res < 0, "Failed to handle same src/dst ctrl");
1✔
374
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
375
    strerror(errno), errno);
1✔
376

1✔
377
  mark_point();
378
  dst_ctrl = pr_ctrls_alloc();
1✔
379
  res = pr_ctrls_copy_args(src_ctrl, dst_ctrl);
1✔
380
  ck_assert_msg(res == 0, "Failed to copy ctrl args: %s", strerror(errno));
381

1✔
382
  mark_point();
1✔
383
  res = pr_ctrls_add_arg(src_ctrl, "foo", 3);
1✔
384
  ck_assert_msg(res == 0, "Failed to add src ctrl arg: %s", strerror(errno));
385

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

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

1✔
392
  res = pr_ctrls_copy_args(src_ctrl, dst_ctrl);
1✔
393
  ck_assert_msg(res == 0, "Failed to copy ctrl args: %s", strerror(errno));
1✔
394
}
395
END_TEST
396

1✔
397
START_TEST (ctrls_copy_resps_test) {
1✔
398
  int res;
1✔
399
  pr_ctrls_t *src_ctrl, *dst_ctrl;
1✔
400

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

1✔
407
  mark_point();
408
  src_ctrl = pr_ctrls_alloc();
409
  res = pr_ctrls_copy_resps(src_ctrl, NULL);
1✔
410
  ck_assert_msg(res < 0, "Failed to handle null dst ctrl");
1✔
411
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
412
    strerror(errno), errno);
1✔
413

1✔
414
  mark_point();
415
  res = pr_ctrls_copy_resps(src_ctrl, src_ctrl);
416
  ck_assert_msg(res < 0, "Failed to handle same src/dst ctrl");
1✔
417
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
418
    strerror(errno), errno);
1✔
419

420
  mark_point();
1✔
421
  dst_ctrl = pr_ctrls_alloc();
1✔
422
  res = pr_ctrls_copy_resps(src_ctrl, dst_ctrl);
423
  ck_assert_msg(res < 0, "Failed to handle src ctrl with no 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
  res = pr_ctrls_add_response(src_ctrl, "%s", "foo");
1✔
429
  ck_assert_msg(res == 0, "Failed to add src ctrl response: %s", strerror(errno));
1✔
430

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

1✔
434
  res = pr_ctrls_copy_resps(src_ctrl, dst_ctrl);
1✔
435
  ck_assert_msg(res < 0, "Failed to handle dst ctrl with responses");
1✔
436
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
437
    strerror(errno), errno);
438

439
  mark_point();
1✔
440
  src_ctrl = pr_ctrls_alloc();
1✔
441
  res = pr_ctrls_add_response(src_ctrl, "%s", "foo");
1✔
442
  ck_assert_msg(res == 0, "Failed to add src ctrl response: %s", strerror(errno));
1✔
443

1✔
444
  dst_ctrl = pr_ctrls_alloc();
445
  res = pr_ctrls_copy_resps(src_ctrl, dst_ctrl);
1✔
446
  ck_assert_msg(res == 0, "Failed to copy ctrl responses: %s", strerror(errno));
1✔
447
}
1✔
448
END_TEST
1✔
449

450
START_TEST (ctrls_send_request_test) {
451
  int fd, res;
1✔
452
  char *action = "foo";
1✔
453
  unsigned int msgargc = 1;
1✔
454
  char *msgargv[] = { "bar", NULL };
1✔
455

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

1✔
462
  mark_point();
463
  res = pr_ctrls_send_request(p, -1, NULL, 0, NULL);
464
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
465
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
466
    strerror(errno), errno);
1✔
467

1✔
468
  mark_point();
469
  fd = 7;
470
  res = pr_ctrls_send_request(p, fd, NULL, 0, NULL);
1✔
471
  ck_assert_msg(res < 0, "Failed to handle null action");
1✔
472
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
473
    strerror(errno), errno);
1✔
474

1✔
475
  mark_point();
476
  res = pr_ctrls_send_request(p, fd, action, msgargc, NULL);
477
  ck_assert_msg(res < 0, "Failed to handle mismatched argc/argv");
1✔
478
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
479
    strerror(errno), errno);
×
480

481
  mark_point();
482
  fd = 7777;
1✔
483
  res = pr_ctrls_send_request(p, fd, action, msgargc, msgargv);
1✔
484
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
485
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
486
    strerror(errno), errno);
1✔
487

488
  fd = devnull_fd();
489
  if (fd < 0) {
490
    return;
1✔
491
  }
1✔
492

1✔
493
  mark_point();
1✔
494
  res = pr_ctrls_send_request(p, fd, action, msgargc, msgargv);
495
  ck_assert_msg(res == 0, "Failed to send ctrl message: %s", strerror(errno));
1✔
496

1✔
497
  (void) close(fd);
1✔
498
}
1✔
499
END_TEST
500

501
START_TEST (ctrls_send_response_test) {
1✔
502
  int fd, res, status;
1✔
503
  unsigned int msgargc = 1;
1✔
504
  char *msgargv[] = { "foo", NULL };
1✔
505

506
  mark_point();
507
  res = pr_ctrls_send_response(NULL, -1, 0, 0, NULL);
1✔
508
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
509
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
510
    strerror(errno), errno);
×
511

512
  mark_point();
1✔
513
  res = pr_ctrls_send_response(p, -1, 0, 0, NULL);
1✔
514
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
515
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
516
    strerror(errno), errno);
1✔
517

1✔
518
  mark_point();
1✔
519
  fd = devnull_fd();
1✔
520
  if (fd < 0) {
521
    return;
1✔
522
  }
523
  res = pr_ctrls_send_response(p, fd, 0, 0, NULL);
1✔
524
  ck_assert_msg(res == 0, "Failed to send zero ctrl messages: %s",
1✔
525
    strerror(errno));
1✔
526

1✔
527
  mark_point();
1✔
528
  res = pr_ctrls_send_response(p, fd, 0, msgargc, NULL);
1✔
529
  ck_assert_msg(res < 0, "Failed to handle missing argv");
530
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
531
    strerror(errno), errno);
1✔
532
  (void) close(fd);
1✔
533

534
  mark_point();
535
  fd = 7777;
536
  status = -24;
1✔
537
  res = pr_ctrls_send_response(p, fd, status, msgargc, msgargv);
1✔
538
  ck_assert_msg(res < 0, "Failed to handle invalid fd");
1✔
539
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
540
    strerror(errno), errno);
541

1✔
542
  fd = devnull_fd();
543
  if (fd < 0) {
544
    return;
545
  }
1✔
546

1✔
547
  mark_point();
1✔
548
  status = -24;
1✔
549
  res = pr_ctrls_send_response(p, fd, status, msgargc, msgargv);
550
  ck_assert_msg(res == 0, "Failed to send ctrl message: %s", strerror(errno));
1✔
551

1✔
552
  (void) close(fd);
1✔
553
}
1✔
554
END_TEST
555

556
START_TEST (ctrls_flush_response_test) {
1✔
557
  int res;
1✔
558
  pr_ctrls_t *ctrl;
1✔
559
  pr_ctrls_cl_t *cl;
1✔
560

561
  mark_point();
562
  res = pr_ctrls_flush_response(NULL);
1✔
563
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
564
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
565
    strerror(errno), errno);
1✔
566

1✔
567
  mark_point();
1✔
568
  ctrl = pr_ctrls_alloc();
569
  res = pr_ctrls_flush_response(ctrl);
570
  ck_assert_msg(res == 0, "Failed to flush ctrl with no responses: %s",
1✔
571
    strerror(errno));
1✔
572

1✔
573
  mark_point();
1✔
574
  res = pr_ctrls_add_response(ctrl, "%s", "foo");
575
  ck_assert_msg(res == 0, "Failed to add ctrl response: %s", strerror(errno));
576
  res = pr_ctrls_flush_response(ctrl);
577
  ck_assert_msg(res < 0, "Failed to handle ctrl with no client");
1✔
578
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
579
    strerror(errno), errno);
1✔
580

581
  mark_point();
1✔
582
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
583
  cl->cl_fd = devnull_fd();
1✔
584
  if (cl->cl_fd < 0) {
1✔
585
    return;
1✔
586
  }
587

588
  ctrl->ctrls_cl = cl;
589
  res = pr_ctrls_flush_response(ctrl);
590
  ck_assert_msg(res == 0, "Failed to flush ctrl responses: %s", strerror(errno));
1✔
591

1✔
592
  mark_point();
1✔
593
  (void) close(cl->cl_fd);
1✔
594
  res = pr_ctrls_flush_response(ctrl);
1✔
595
  ck_assert_msg(res < 0, "Failed to handle bad fd");
596
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
597
    strerror(errno), errno);
1✔
598
}
1✔
599
END_TEST
1✔
600

601
START_TEST (ctrls_recv_request_invalid_test) {
602
  int fd, res;
1✔
603
  uint32_t msglen;
1✔
604
  char *msg = NULL;
1✔
605
  pr_ctrls_cl_t *cl;
1✔
606

1✔
607
  mark_point();
608
  res = pr_ctrls_recv_request(NULL);
609
  ck_assert_msg(res < 0, "Failed to handle null client");
1✔
610
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
611
    strerror(errno), errno);
1✔
612

1✔
613
  mark_point();
1✔
614
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
615
  res = pr_ctrls_recv_request(cl);
616
  ck_assert_msg(res < 0, "Failed to handle client without ctrls list");
617
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
618
    strerror(errno), errno);
1✔
619

1✔
620
  mark_point();
×
621
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
622
  cl->cl_fd = -1;
623
  res = pr_ctrls_recv_request(cl);
1✔
624
  ck_assert_msg(res < 0, "Failed to handle client without fd");
1✔
625
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
626
    strerror(errno), errno);
1✔
627

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

634
  cl->cl_fd = fd;
635
  (void) close(cl->cl_fd);
636
  res = pr_ctrls_recv_request(cl);
1✔
637
  ck_assert_msg(res < 0, "Failed to handle client with bad fd");
1✔
638
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
639
    strerror(errno), errno);
1✔
640

1✔
641
  mark_point();
1✔
642
  fd = tmpfile_fd();
643
  if (fd < 0) {
644
    return;
1✔
645
  }
1✔
646

647
  cl->cl_fd = fd;
648
  (void) write(fd, "a", 1);
1✔
649
  rewind_fd(fd);
650
  res = pr_ctrls_recv_request(cl);
1✔
651
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too short)");
1✔
652
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
653
    strerror(errno), errno);
1✔
654

1✔
655
  fd = reset_fd(fd);
1✔
656
  if (fd < 0) {
1✔
657
    return;
1✔
658
  }
659
  cl->cl_fd = fd;
660

1✔
661
  mark_point();
1✔
662
  msglen = 2;
663
  (void) write(fd, &msglen, sizeof(msglen));
664
  (void) write(fd, "a", 1);
1✔
665
  rewind_fd(fd);
666
  res = pr_ctrls_recv_request(cl);
1✔
667
  ck_assert_msg(res < 0, "Failed to handle invalid message (too short)");
1✔
668
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
669
    strerror(errno), errno);
1✔
670

1✔
671
  fd = reset_fd(fd);
1✔
672
  if (fd < 0) {
1✔
673
    return;
1✔
674
  }
675
  cl->cl_fd = fd;
676

1✔
677
  mark_point();
1✔
678
  msglen = 2;
679
  (void) write(fd, &msglen, sizeof(msglen));
680
  (void) write(fd, "aa", 2);
1✔
681
  rewind_fd(fd);
682
  res = pr_ctrls_recv_request(cl);
1✔
683
  ck_assert_msg(res < 0, "Failed to handle invalid message (wrong format)");
1✔
684
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
685
    strerror(errno), errno);
1✔
686

1✔
687
  fd = reset_fd(fd);
1✔
688
  if (fd < 0) {
1✔
689
    return;
1✔
690
  }
1✔
691
  cl->cl_fd = fd;
692

693
  mark_point();
1✔
694
  msg = "{}";
1✔
695
  msglen = strlen(msg);
696
  (void) write(fd, &msglen, sizeof(msglen));
697
  (void) write(fd, msg, msglen);
1✔
698
  rewind_fd(fd);
699
  res = pr_ctrls_recv_request(cl);
1✔
700
  ck_assert_msg(res < 0, "Failed to handle invalid message (missing 'action')");
1✔
701
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
702
    strerror(errno), errno);
1✔
703

1✔
704
  fd = reset_fd(fd);
1✔
705
  if (fd < 0) {
1✔
706
    return;
1✔
707
  }
1✔
708
  cl->cl_fd = fd;
709

710
  mark_point();
1✔
711
  msg = "{\"action\":\"foo\"}";
1✔
712
  msglen = strlen(msg);
713
  (void) write(fd, &msglen, sizeof(msglen));
714
  (void) write(fd, msg, msglen);
1✔
715
  rewind_fd(fd);
716
  res = pr_ctrls_recv_request(cl);
1✔
717
  ck_assert_msg(res < 0, "Failed to handle invalid message (missing 'args')");
1✔
718
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
719
    strerror(errno), errno);
1✔
720

1✔
721
  fd = reset_fd(fd);
1✔
722
  if (fd < 0) {
1✔
723
    return;
1✔
724
  }
1✔
725
  cl->cl_fd = fd;
726

727
  mark_point();
1✔
728
  msg = "{\"action\":\"test\",\"args\":[1,2,3,4,5,6,7,8,9,10]}";
729
  msglen = strlen(msg);
730
  (void) write(fd, &msglen, sizeof(msglen));
731
  (void) write(fd, msg, msglen);
1✔
732
  rewind_fd(fd);
1✔
733
  res = pr_ctrls_recv_request(cl);
1✔
734
  ck_assert_msg(res < 0, "Failed to handle unknown action");
1✔
735
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
736
    strerror(errno), errno);
1✔
737

1✔
738
  (void) close(fd);
1✔
739
}
740
END_TEST
1✔
741

1✔
742
START_TEST (ctrls_recv_request_too_large_test) {
1✔
743
  int fd, res;
1✔
744
  uint32_t msglen;
1✔
745
  pr_ctrls_cl_t *cl;
1✔
746

747
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
748
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
1✔
749

1✔
750
  mark_point();
×
751
  fd = tmpfile_fd();
752
  if (fd < 0) {
753
    return;
1✔
754
  }
1✔
755

1✔
756
  cl->cl_fd = fd;
757

1✔
758
  mark_point();
1✔
759
  msglen = (uint32_t) -1;
1✔
760
  (void) write(fd, (const void *) &msglen, sizeof(msglen));
1✔
761
  rewind_fd(fd);
1✔
762
  res = pr_ctrls_recv_request(cl);
1✔
763
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too long)");
1✔
764
  ck_assert_msg(errno == E2BIG, "Expected E2BIG (%d), got %s (%d)", E2BIG,
1✔
765
    strerror(errno), errno);
766

1✔
767
  (void) close(fd);
1✔
768
}
769
END_TEST
1✔
770

771
START_TEST (ctrls_recv_request_valid_test) {
772
  int fd, res;
1✔
773
  uint32_t msglen = 0;
1✔
774
  char *msg = NULL;
1✔
775
  const char *action, *desc;
776
  pr_ctrls_cl_t *cl;
777
  pr_ctrls_t *ctrl;
1✔
778
  module m;
1✔
779

780
  mark_point();
1✔
781
  m.name = "test";
1✔
782
  action = "test";
1✔
783
  desc = "desc";
1✔
784
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
785
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
786

1✔
787
  mark_point();
1✔
788
  fd = tmpfile_fd();
789
  if (fd < 0) {
1✔
790
    return;
1✔
791
  }
792

1✔
793
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
794
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
795
  cl->cl_fd = fd;
1✔
796

1✔
797
  msg = "{\"action\":\"test\",\"args\":[]}";
1✔
798
  msglen = strlen(msg);
799
  (void) write(fd, &msglen, sizeof(msglen));
800
  (void) write(fd, msg, msglen);
1✔
801
  rewind_fd(fd);
1✔
802
  res = pr_ctrls_recv_request(cl);
803
  ck_assert_msg(res == 0, "Failed to handle known action: %s", strerror(errno));
1✔
804
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
1✔
805
    cl->cl_ctrls->nelts);
1✔
806
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
807
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
1✔
808
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
809
  ck_assert_msg(ctrl->ctrls_cb_args == NULL,
1✔
810
    "Expected no callback args, got %p", ctrl->ctrls_cb_args);
811

1✔
812
  mark_point();
813
  fd = reset_fd(fd);
1✔
814
  if (fd < 0) {
1✔
815
    return;
816
  }
1✔
817
  clear_array(cl->cl_ctrls);
1✔
818
  cl->cl_fd = fd;
819

820
  msg = "{\"action\":\"test\",\"args\":[\"a\"]}";
821
  msglen = strlen(msg);
822
  (void) write(fd, &msglen, sizeof(msglen));
1✔
823
  (void) write(fd, msg, msglen);
1✔
824
  rewind_fd(fd);
1✔
825
  res = pr_ctrls_recv_request(cl);
826
  ck_assert_msg(res == 0, "Failed to handle known action: %s", strerror(errno));
1✔
827
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
1✔
828
    cl->cl_ctrls->nelts);
1✔
829
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
830
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
831
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
832
  ck_assert_msg(ctrl->ctrls_cb_args != NULL,
1✔
833
    "Expected callback args, got %p", ctrl->ctrls_cb_args);
834

1✔
835
  mark_point();
1✔
836
  fd = reset_fd(fd);
1✔
837
  if (fd < 0) {
1✔
838
    return;
1✔
839
  }
1✔
840
  clear_array(cl->cl_ctrls);
1✔
841
  cl->cl_fd = fd;
842

1✔
843
  msg = "{\"action\":\"test\",\"args\":[\"next\"]}";
844
  msglen = strlen(msg);
845
  (void) write(fd, &msglen, sizeof(msglen));
1✔
846
  (void) write(fd, msg, msglen);
1✔
847
  rewind_fd(fd);
848
  res = pr_ctrls_recv_request(cl);
1✔
849
  ck_assert_msg(res == 0, "Failed to handle valid request: %s",
1✔
850
    strerror(errno));
851
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
852
    cl->cl_ctrls->nelts);
1✔
853
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
854
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
855
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
856
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
1✔
857
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
858
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
859

1✔
860
  /* next_action present */
1✔
861

862
  mark_point();
863
  res = pr_ctrls_register(&m, action, desc, ctrls_test2_cb);
864
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
865

1✔
866
  mark_point();
1✔
867
  fd = reset_fd(fd);
1✔
868
  if (fd < 0) {
869
    return;
1✔
870
  }
1✔
871
  clear_array(cl->cl_ctrls);
1✔
872
  cl->cl_fd = fd;
1✔
873

874
  msg = "{\"action\":\"test\",\"args\":[\"next\"]}";
875
  msglen = strlen(msg);
1✔
876
  (void) write(fd, &msglen, sizeof(msglen));
1✔
877
  (void) write(fd, msg, msglen);
1✔
878
  rewind_fd(fd);
1✔
879
  res = pr_ctrls_recv_request(cl);
880
  ck_assert_msg(res == 0, "Failed to handle valid request: %s",
881
    strerror(errno));
1✔
882
  ck_assert_msg(cl->cl_ctrls->nelts == 2, "Expected 2 ctrl, got %d",
1✔
883
    cl->cl_ctrls->nelts);
1✔
884

×
885
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
886
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
887
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
888
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
1✔
889
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
1✔
890
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
891

1✔
892
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[1];
893
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
1✔
894
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
1✔
895
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
1✔
896
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
897
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
898

899
  (void) pr_ctrls_unregister(&m, action);
1✔
900
  (void) close(fd);
1✔
901
}
1✔
902
END_TEST
1✔
903

1✔
904
START_TEST (ctrls_recv_response_test) {
905
  int fd, res, status;
906
  uint32_t msglen;
1✔
907
  char *msg = NULL;
1✔
908

909
  mark_point();
910
  res = pr_ctrls_recv_response(NULL, -1, NULL, NULL);
911
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
912
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
913
    strerror(errno), errno);
1✔
914

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

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

1✔
927
  res = pr_ctrls_recv_response(p, fd, NULL, NULL);
1✔
928
  ck_assert_msg(res < 0, "Failed to handle null status");
1✔
929
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
930
    strerror(errno), errno);
1✔
931
  (void) close(fd);
1✔
932

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

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

1✔
946
  fd = reset_fd(fd);
1✔
947
  if (fd < 0) {
1✔
948
    return;
1✔
949
  }
1✔
950

951
  mark_point();
952
  msglen = 2;
1✔
953
  (void) write(fd, &msglen, sizeof(msglen));
1✔
954
  (void) write(fd, "a", 1);
955
  rewind_fd(fd);
956
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
957
  ck_assert_msg(res < 0, "Failed to handle invalid message (too short)");
1✔
958
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
959
    strerror(errno), errno);
1✔
960

1✔
961
  fd = reset_fd(fd);
1✔
962
  if (fd < 0) {
1✔
963
    return;
1✔
964
  }
1✔
965

966
  mark_point();
1✔
967
  msglen = 2;
968
  (void) write(fd, &msglen, sizeof(msglen));
969
  (void) write(fd, "aa", 2);
1✔
970
  rewind_fd(fd);
1✔
971
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
972
  ck_assert_msg(res < 0, "Failed to handle invalid message (wrong format)");
973
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
974
    strerror(errno), errno);
1✔
975

1✔
976
  fd = reset_fd(fd);
1✔
977
  if (fd < 0) {
1✔
978
    return;
1✔
979
  }
1✔
980

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

1✔
992
  fd = reset_fd(fd);
1✔
993
  if (fd < 0) {
1✔
994
    return;
1✔
995
  }
1✔
996

1✔
997
  mark_point();
1✔
998
  msg = "{\"status\":0}";
1✔
999
  msglen = strlen(msg);
1000
  (void) write(fd, &msglen, sizeof(msglen));
1001
  (void) write(fd, msg, msglen);
1✔
1002
  rewind_fd(fd);
1003
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1004
  ck_assert_msg(res < 0,
1005
    "Failed to handle invalid message (missing 'responses')");
1✔
1006
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1007
    strerror(errno), errno);
1✔
1008

1009
  fd = reset_fd(fd);
1✔
1010
  if (fd < 0) {
1✔
1011
    return;
1✔
1012
  }
1✔
1013

1✔
1014
  mark_point();
1015
  msg = "{\"status\":0,\"responses\":[1]}";
1016
  msglen = strlen(msg);
1017
  (void) write(fd, &msglen, sizeof(msglen));
1✔
1018
  (void) write(fd, msg, msglen);
1✔
1019
  rewind_fd(fd);
1✔
1020
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
1021
  ck_assert_msg(res < 0,
1✔
1022
    "Failed to handle invalid message (non-text response)");
1✔
1023
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1024
    strerror(errno), errno);
1025

1026
  fd = reset_fd(fd);
1027
  if (fd < 0) {
1✔
1028
    return;
1✔
1029
  }
1✔
1030

1✔
1031
  mark_point();
1✔
1032
  msg = "{\"status\":0,\"responses\":[\"ok\"]}";
×
1033
  msglen = strlen(msg);
1034
  (void) write(fd, &msglen, sizeof(msglen));
1035
  (void) write(fd, msg, msglen);
1✔
1036
  rewind_fd(fd);
1037
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1038
  ck_assert_msg(res == 1, "Failed to handle valid response: %s",
1✔
1039
    strerror(errno));
1✔
1040

1✔
1041
  (void) close(fd);
1✔
1042
}
1✔
1043
END_TEST
1044

1✔
1045
START_TEST (ctrls_recv_response_too_large_test) {
1✔
1046
  int fd, res, status;
1✔
1047
  uint32_t msglen;
1✔
1048

1049
  mark_point();
1050
  fd = tmpfile_fd();
1✔
1051
  if (fd < 0) {
1✔
1052
    return;
1✔
1053
  }
1✔
1054

1055
  mark_point();
1056
  msglen = (uint32_t) -1;
1✔
1057
  (void) write(fd, (const void *) &msglen, sizeof(msglen));
1✔
1058
  rewind_fd(fd);
1✔
1059
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
1060
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too long)");
1✔
1061
  ck_assert_msg(errno == E2BIG, "Expected E2BIG (%d), got %s (%d)", E2BIG,
1062
    strerror(errno), errno);
1✔
1063

1064
  (void) close(fd);
1✔
1065
}
1✔
1066
END_TEST
1✔
1067

1✔
1068
START_TEST (ctrls_issock_unix_test) {
1✔
1069
  int res;
1070
  mode_t mode;
1✔
1071

1✔
1072
  mark_point();
1✔
1073
  mode = 0;
1074
  res = pr_ctrls_issock_unix(mode);
1✔
1075
  ck_assert_msg(res < 0, "Failed to handle invalid mode");
1✔
1076
  ck_assert_msg(errno == ENOSYS, "Expected ENOSYS (%d), got %s (%d)", ENOSYS,
1✔
1077
    strerror(errno), errno);
1078

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

1✔
1089
#if defined(S_ISSOCK)
1✔
1090
  mark_point();
1✔
1091
  mode = 0;
1092
  mode |= S_IFSOCK;
1✔
1093
  res = pr_ctrls_issock_unix(mode);
1✔
1094
  if (res < 0) {
1✔
1095
    ck_assert_msg(errno == ENOSYS, "Did not expect ENOSYS (%d)", ENOSYS);
1096
  }
1✔
1097
#endif /* S_ISSOCK */
1098
}
1099
END_TEST
1✔
1100

1✔
1101
START_TEST (ctrls_get_registered_actions_test) {
1✔
1102
  int res;
1103
  pr_ctrls_t *ctrl;
1✔
1104
  const char *action, *desc;
1✔
1105
  module m;
1✔
1106

1✔
1107
  mark_point();
1108
  res = pr_get_registered_actions(NULL, 0);
1109
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
1110
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1111
    strerror(errno), errno);
1✔
1112

1✔
1113
  mark_point();
1114
  ctrl = pr_ctrls_alloc();
1115
  res = pr_get_registered_actions(ctrl, 0);
1✔
1116
  ck_assert_msg(res == 0, "Failed to handle lack of registered actions: %s",
1✔
1117
    strerror(errno));
1✔
1118

1✔
1119
  mark_point();
1✔
1120
  pr_block_ctrls();
1121
  res = pr_get_registered_actions(ctrl, 0);
1✔
1122
  ck_assert_msg(res < 0, "Failed to handle blocked actions");
1✔
1123
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1124
    strerror(errno), errno);
1125
  pr_unblock_ctrls();
1126

1✔
1127
  mark_point();
1✔
1128
  action = "test";
1✔
1129
  desc = "desc";
1✔
1130
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1131
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1132

1✔
1133
  m.name = "test";
1134
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
1135
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1136

1✔
1137
  mark_point();
1138
  res = pr_get_registered_actions(ctrl, 0);
1139
  ck_assert_msg(res == 0, "Failed to handle invalid flags: %s", strerror(errno));
1✔
1140

1✔
1141
  mark_point();
1✔
1142
  res = pr_get_registered_actions(ctrl, CTRLS_GET_ACTION_ALL);
1143
  ck_assert_msg(res == 2, "Failed to handle GET_ACTION_ALL flag: %s",
1✔
1144
    strerror(errno));
1✔
1145

1✔
1146
  mark_point();
1147
  res = pr_get_registered_actions(ctrl, CTRLS_GET_ACTION_ENABLED);
1✔
1148
  ck_assert_msg(res == 2, "Failed to handle GET_ACTION_ENABLED flag: %s",
1149
    strerror(errno));
1150

1✔
1151
  mark_point();
1✔
1152
  res = pr_get_registered_actions(ctrl, CTRLS_GET_DESC);
1✔
1153
  ck_assert_msg(res == 2, "Failed to handle GET_DESC flag: %s", strerror(errno));
1154

1✔
1155
  mark_point();
1✔
1156
  res = pr_ctrls_unregister(NULL, action);
1✔
1157
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1158
    strerror(errno));
1159
}
1✔
1160
END_TEST
1✔
1161

1✔
1162
START_TEST (ctrls_set_registered_actions_test) {
1✔
1163
  int res;
1✔
1164
  const char *action, *desc;
1165

1✔
1166
  mark_point();
1✔
1167
  res = pr_set_registered_actions(NULL, NULL, FALSE, 0);
1✔
1168
  ck_assert_msg(res < 0, "Failed to handle no registered actions");
1169
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1170
    strerror(errno), errno);
1171

1172
  mark_point();
1✔
1173
  res = pr_set_registered_actions(NULL, NULL, FALSE, 24);
1✔
1174
  ck_assert_msg(res < 0, "Failed to handle invalid flag");
1✔
1175
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1176
    strerror(errno), errno);
1✔
1177

1✔
1178
  mark_point();
1✔
1179
  action = "test";
1180
  desc = "desc";
1181
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1182
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1183

1✔
1184
  mark_point();
1185
  res = pr_set_registered_actions(NULL, NULL, FALSE, 0);
1186
  ck_assert_msg(res == 0, "Failed to handle no registered actions: %s",
1✔
1187
    strerror(errno));
1✔
1188

1✔
1189
  mark_point();
1✔
1190
  pr_block_ctrls();
1191
  res = pr_set_registered_actions(NULL, NULL, FALSE, 0);
1192
  ck_assert_msg(res < 0, "Failed to handle blocked actions");
1✔
1193
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1194
    strerror(errno), errno);
1✔
1195
  pr_unblock_ctrls();
1196

1✔
1197
  mark_point();
1198
  res = pr_set_registered_actions(NULL, action, FALSE, 0);
1199
  ck_assert_msg(res == 0, "Failed to handle action '%s': %s", action,
1✔
1200
    strerror(errno));
1✔
1201

1✔
1202
  mark_point();
1✔
1203
  res = pr_set_registered_actions(NULL, "all", FALSE, 0);
1✔
1204
  ck_assert_msg(res == 0, "Failed to handle action 'all': %s", strerror(errno));
1✔
1205

1✔
1206
  mark_point();
1✔
1207
  res = pr_ctrls_unregister(NULL, action);
1✔
1208
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1209
    strerror(errno));
1✔
1210
}
1✔
1211
END_TEST
1✔
1212

1213
START_TEST (ctrls_check_actions_test) {
1✔
1214
  int res;
1✔
1215
  const char *action, *desc;
1✔
1216

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

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

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

1233
  /* Register a duplicate action name, then check. */
1✔
1234

1✔
1235
  mark_point();
1✔
1236
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1237
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1238

1✔
1239
  mark_point();
1✔
1240
  res = pr_ctrls_check_actions();
1241
  ck_assert_msg(res == 0, "Failed to handle registered actions: %s",
1242
    strerror(errno));
1243

1244
  mark_point();
1245
  res = pr_set_registered_actions(NULL, action, FALSE, PR_CTRLS_ACT_SOLITARY);
1246
  ck_assert_msg(res == 0, "Failed to set SOLITARY action flag: %s",
1247
    strerror(errno));
1✔
1248

1✔
1249
  mark_point();
1✔
1250
  res = pr_ctrls_check_actions();
×
1251
  ck_assert_msg(res < 0, "Failed to handle duplicate SOLITARY actions");
1252
  ck_assert_msg(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1253
    strerror(errno), errno);
1✔
1254

1✔
1255
  mark_point();
1✔
1256
  res = pr_ctrls_unregister(NULL, action);
1257
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
1258
    strerror(errno));
1✔
1259
}
1✔
1260
END_TEST
1✔
1261

1✔
1262
START_TEST (ctrls_run_ctrls_test) {
1✔
1263
  int fd, res;
1✔
1264
  uint32_t msglen = 0;
1✔
1265
  char *msg = NULL;
1266
  const char *action, *desc;
1✔
1267
  pr_ctrls_cl_t *cl;
1268
  pr_ctrls_t *ctrl;
1✔
1269
  module m, m2;
1✔
1270
  time_t now;
1✔
1271

1272
  mark_point();
1✔
1273
  res = pr_run_ctrls(NULL, NULL);
1✔
1274
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1275

1276
  mark_point();
1✔
1277
  pr_block_ctrls();
1✔
1278
  res = pr_run_ctrls(NULL, NULL);
1✔
1279
  ck_assert_msg(res < 0, "Failed to handle blocked ctrls");
1✔
1280
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1281
    strerror(errno), errno);
1282
  pr_unblock_ctrls();
1✔
1283

1✔
1284
  mark_point();
1✔
1285
  action = "test";
1✔
1286
  desc = "desc";
1✔
1287
  m.name = "test";
1✔
1288
  m2.name = "test2";
1289
  res = pr_ctrls_register(&m, action, desc, ctrls_test_cb);
1✔
1290
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1✔
1291

1✔
1292
  mark_point();
1✔
1293
  res = pr_run_ctrls(NULL, NULL);
1✔
1294
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1295

1✔
1296
  mark_point();
1297
  res = pr_run_ctrls(&m2, NULL);
1✔
1298
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1299

1✔
1300
  mark_point();
1✔
1301
  res = pr_run_ctrls(&m, NULL);
1✔
1302
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1303

1✔
1304
  /* XXX TODO More test cases to fill in here. */
1305
  /* Note that pr_run_ctrls() makes a lot of assumptions about recv_response,
1✔
1306
   * recv_request having been called previously.  Not great.  How to deal
1✔
1307
   * with that?
1✔
1308
   */
1✔
1309

1✔
1310
  mark_point();
1311
  fd = tmpfile_fd();
1✔
1312
  if (fd < 0) {
1✔
1313
    return;
1✔
1314
  }
1315

1316
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
1317
  cl->cl_ctrls = make_array(p, 0, sizeof(pr_ctrls_t *));
1318
  cl->cl_fd = fd;
1319

1320
  msg = "{\"action\":\"test\",\"args\":[\"FOO\"]}";
1✔
1321
  msglen = strlen(msg);
1✔
1322
  (void) write(fd, &msglen, sizeof(msglen));
1✔
1323
  (void) write(fd, msg, msglen);
1324
  rewind_fd(fd);
1✔
1325
  res = pr_ctrls_recv_request(cl);
1✔
1326
  ck_assert_msg(res == 0, "Failed to handle known action: %s", strerror(errno));
1✔
1327
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
1328
    cl->cl_ctrls->nelts);
1✔
1329
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
1330

1✔
1331
  mark_point();
1✔
1332
  res = pr_run_ctrls(&m2, NULL);
1✔
1333
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1334

1✔
1335
  mark_point();
1✔
1336
  res = pr_run_ctrls(&m, NULL);
1✔
1337
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1338

1✔
1339
  mark_point();
1✔
1340
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1341
  ctrl->ctrls_flags |= PR_CTRLS_ACT_DISABLED;
1342
  res = pr_run_ctrls(&m, NULL);
1✔
1343
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1344

1345
  mark_point();
1✔
1346
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1347
  ctrl->ctrls_flags &= ~PR_CTRLS_ACT_DISABLED;
1348
  ctrl->ctrls_flags &= ~PR_CTRLS_FL_REQUESTED;
1✔
1349
  res = pr_run_ctrls(&m, NULL);
1✔
1350
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1✔
1351

1✔
1352
  mark_point();
1353
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1354
  ctrl->ctrls_flags |= PR_CTRLS_FL_REQUESTED;
1✔
1355
  now = time(NULL);
1✔
1356
  ctrl->ctrls_when = now + 10;
1✔
1357
  res = pr_run_ctrls(&m, NULL);
1358
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1359

1360
  mark_point();
1✔
1361
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1362
  ctrl->ctrls_flags &= PR_CTRLS_FL_PENDING;
1✔
1363
  ctrl->ctrls_flags |= PR_CTRLS_FL_REQUESTED;
1364
  ctrl->ctrls_when = now - 10;
1365
  res = pr_run_ctrls(&m, "test2");
1✔
1366
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1367

1368
  mark_point();
1369
  cl->cl_flags = PR_CTRLS_CL_HAVEREQ;
1✔
1370
  ctrl->ctrls_flags |= PR_CTRLS_FL_REQUESTED;
1✔
1371
  res = pr_run_ctrls(&m, "test");
1✔
1372
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
1373

1✔
1374
  mark_point();
1✔
1375
  res = pr_ctrls_unregister(NULL, action);
1✔
1376
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
1377
    strerror(errno));
1378

1379
  (void) close(fd);
1✔
1380
}
1✔
1381
END_TEST
1✔
1382

1✔
1383
START_TEST (ctrls_reset_ctrls_test) {
1✔
1384
  int res;
1385
  const char *action, *desc;
1386

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

1391
  mark_point();
1392
  action = "test";
1393
  desc = "desc";
1✔
1394
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1395
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
1396

1397
  mark_point();
1✔
1398
  res = pr_ctrls_reset();
1✔
1399
  ck_assert_msg(res == 0, "Failed to reset ctrls: %s", strerror(errno));
1✔
1400

1401
  mark_point();
1402
  res = pr_ctrls_unregister(NULL, action);
1403
  ck_assert_msg(res == 0, "Failed to unregister ctrls action: %s",
1✔
1404
    strerror(errno));
1✔
1405
}
1✔
1406
END_TEST
1✔
1407

1408
START_TEST (ctrls_accept_test) {
1✔
1409
  int fd, res;
1✔
1410

1✔
1411
  mark_point();
1✔
1412
  res = pr_ctrls_accept(-1, NULL, NULL, NULL, 0);
1413
  ck_assert_msg(res < 0, "Failed to handle bad fd");
1414
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
1✔
1415
    strerror(errno), errno);
1✔
1416

1✔
1417
  mark_point();
1✔
1418
  fd = devnull_fd();
1419
  if (fd < 0) {
1✔
1420
    return;
1✔
1421
  }
1✔
1422

1✔
1423
  res = pr_ctrls_accept(fd, NULL, NULL, NULL, 5);
1424
  ck_assert_msg(res < 0, "Failed to handle no clients");
1✔
1425
  ck_assert_msg(errno = ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
1426
    strerror(errno), errno);
1✔
1427

1✔
1428
  (void) close(fd);
1429
}
1430
END_TEST
1✔
1431

1✔
1432
START_TEST (ctrls_accept_einval_path_test) {
1✔
1433
  int fd = -1, other_fd = -1, res;
1434

1435
  mark_point();
1✔
1436
  fd = connect_unix(&other_fd);
1✔
1437
  if (fd < 0) {
1✔
1438
    return;
1✔
1439
  }
1✔
1440

1✔
1441
  mark_point();
1✔
1442
  res = pr_ctrls_accept(fd, NULL, NULL, NULL, 5);
1443
  ck_assert_msg(res < 0, "Failed to handle invalid path");
1✔
1444
  ck_assert_msg(errno = EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1445
    strerror(errno), errno);
1✔
1446

1447
  (void) close(fd);
1448
  (void) close(other_fd);
1✔
1449
}
1✔
1450
END_TEST
1✔
1451

1✔
1452
START_TEST (ctrls_connect_test) {
1453
  int fd, res;
1✔
1454
  const char *socket_path;
1✔
1455

1✔
1456
  mark_point();
1✔
1457
  res = pr_ctrls_connect(NULL);
1458
  ck_assert_msg(res < 0, "Failed to handle null path");
1459
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1460
    strerror(errno), errno);
1✔
1461

1✔
1462
  mark_point();
1✔
1463
  socket_path = "/tmp/foo.sock";
1464
  res = pr_ctrls_connect(socket_path);
1✔
1465
  ck_assert_msg(res < 0, "Failed to handle nonexistent socket path");
1✔
1466
  ck_assert_msg(errno == ECONNREFUSED || errno == ENOENT,
1✔
1467
    "Expected ECONNREFUSED (%d) or ENOENT (%d), got %s (%d)", ECONNREFUSED,
1✔
1468
    ENOENT, strerror(errno), errno);
1469

1✔
1470
  mark_point();
1✔
1471
  fd = listen_unix(socket_path);
1✔
1472
  if (fd < 0) {
1✔
1473
    return;
1474
  }
1475

1✔
1476
  res = pr_ctrls_connect(socket_path);
1✔
1477
  ck_assert_msg(res >= 0, "Failed to connect to local socket: %s",
1✔
1478
    strerror(errno));
1479

1480
  (void) close(res);
1✔
1481
  (void) close(fd);
1✔
1482
  (void) unlink(socket_path);
1✔
1483
}
1✔
1484
END_TEST
1✔
1485

1✔
1486
START_TEST (ctrls_connect_eexist_directory_test) {
1✔
1487
  int res;
1488
  const char socket_path[1024];
1✔
1489

1✔
1490
  mark_point();
1✔
1491
  memset(socket_path, '\0', sizeof(socket_path));
1492
  snprintf(socket_path, sizeof(socket_path)-1, "/tmp/ftp.cl%05u",
1493
    (unsigned int) getpid());
1✔
1494
  res = pr_ctrls_connect(socket_path);
1✔
1495
  ck_assert_msg(res < 0, "Failed to handle nonexistent socket path");
1✔
1496
  ck_assert_msg(errno == ECONNREFUSED || errno == ENOENT,
1497
    "Expected ECONNREFUSED (%d) or ENOENT (%d), got %s (%d)", ECONNREFUSED,
1✔
1498
    ENOENT, strerror(errno), errno);
1✔
1499

1✔
1500
  mark_point();
1✔
1501
  if (mkdir(socket_path, 0777) < 0) {
1502
    return;
1503
  }
1✔
1504

1✔
1505
  res = pr_ctrls_connect(socket_path);
1✔
1506
  ck_assert_msg(res < 0, "Failed to handle directory socket path");
1✔
1507
  ck_assert_msg(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)",
1✔
1508
    EEXIST, strerror(errno), errno);
1509

1510
  (void) rmdir(socket_path);
×
1511
}
×
1512
END_TEST
1513

1514
START_TEST (ctrls_connect_eexist_symlink_test) {
1✔
1515
  int res;
1✔
1516
  const char socket_path[1024];
1✔
1517

1✔
1518
  mark_point();
1✔
1519
  memset(socket_path, '\0', sizeof(socket_path));
1✔
1520
  snprintf(socket_path, sizeof(socket_path)-1, "/tmp/ftp.cl%05u",
1✔
1521
    (unsigned int) getpid());
1522
  res = pr_ctrls_connect(socket_path);
1523
  ck_assert_msg(res < 0, "Failed to handle nonexistent socket path");
1524
  ck_assert_msg(errno == ECONNREFUSED || errno == ENOENT,
1525
    "Expected ECONNREFUSED (%d) or ENOENT (%d), got %s (%d)", ECONNREFUSED,
1✔
1526
    ENOENT, strerror(errno), errno);
1✔
1527

1✔
1528
  mark_point();
1✔
1529
  if (symlink(socket_path, "/foo/bar/baz") < 0) {
1530
    return;
1531
  }
1✔
1532

1✔
1533
  res = pr_ctrls_connect(socket_path);
1✔
1534
  ck_assert_msg(res < 0, "Failed to handle symlink socket path");
1✔
1535
  ck_assert_msg(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)",
1✔
1536
    EEXIST, strerror(errno), errno);
1537

1538
  (void) unlink(socket_path);
1✔
1539
}
1✔
1540
END_TEST
1✔
1541

1✔
1542
START_TEST (ctrls_check_group_acl_test) {
1✔
1543
  int res;
1✔
1544
  gid_t gid;
1✔
1545
  ctrls_group_acl_t *group_acl;
1546

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

1553
  mark_point();
1✔
1554
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1✔
1555
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1556
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1557

1558
  mark_point();
1✔
1559
  group_acl->allow = TRUE;
1✔
1560
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1561
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1562

1563
  mark_point();
1✔
1564
  group_acl->ngids = 1;
1✔
1565
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1566
  ck_assert_msg(res == group_acl->allow, "Expected %d, got %d",
1✔
1567
    group_acl->allow, res);
1✔
1568

1✔
1569
  group_acl->allow = FALSE;
1570
  res = pr_ctrls_check_group_acl(0, group_acl);
1✔
1571
  ck_assert_msg(res == group_acl->allow, "Expected %d, got %d",
1✔
1572
    group_acl->allow, res);
1✔
1573

1✔
1574
  mark_point();
1575
  gid = 1;
1✔
1576
  group_acl->allow = TRUE;
1✔
1577
  group_acl->gids = palloc(p, sizeof(gid_t) * 2);
1✔
1578
  ((gid_t *) group_acl->gids)[0] = gid;
1✔
1579
  res = pr_ctrls_check_group_acl(0, group_acl);
1580
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1581

1✔
1582
  res = pr_ctrls_check_group_acl(gid, group_acl);
1✔
1583
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1584
}
1585
END_TEST
1✔
1586

1✔
1587
START_TEST (ctrls_check_user_acl_test) {
1✔
1588
  int res;
1✔
1589
  uid_t uid;
1590
  ctrls_user_acl_t *user_acl;
1591

1✔
1592
  mark_point();
1✔
1593
  res = pr_ctrls_check_user_acl(0, NULL);
1✔
1594
  ck_assert_msg(res < 0, "Failed to handle null acl");
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
  user_acl = pcalloc(p, sizeof(ctrls_user_acl_t));
1✔
1600
  res = pr_ctrls_check_user_acl(0, user_acl);
1✔
1601
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1602

1✔
1603
  mark_point();
1✔
1604
  user_acl->allow = TRUE;
1605
  res = pr_ctrls_check_user_acl(0, user_acl);
1✔
1606
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1607

1✔
1608
  mark_point();
1✔
1609
  user_acl->nuids = 1;
1610
  res = pr_ctrls_check_user_acl(0, user_acl);
1✔
1611
  ck_assert_msg(res == user_acl->allow, "Expected %d, got %d",
1✔
1612
    user_acl->allow, res);
1✔
1613

1✔
1614
  user_acl->allow = FALSE;
1✔
1615
  res = pr_ctrls_check_user_acl(0, user_acl);
1616
  ck_assert_msg(res == user_acl->allow, "Expected %d, got %d",
1617
    user_acl->allow, res);
1✔
1618

1✔
1619
  mark_point();
1✔
1620
  uid = 1;
1✔
1621
  user_acl->allow = TRUE;
1✔
1622
  user_acl->uids = palloc(p, sizeof(uid_t) * 2);
1623
  ((uid_t *) user_acl->uids)[0] = uid;
1✔
1624
  res = pr_ctrls_check_user_acl(0, user_acl);
1✔
1625
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1626

1✔
1627
  res = pr_ctrls_check_user_acl(uid, user_acl);
1628
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1629
}
1✔
1630
END_TEST
1✔
1631

1✔
1632
START_TEST (ctrls_init_acl_test) {
1✔
1633
  int res;
1634
  ctrls_acl_t *acl;
1635

1✔
1636
  mark_point();
1✔
1637
  res = pr_ctrls_init_acl(NULL);
1✔
1638
  ck_assert_msg(res < 0, "Failed to handle null acl");
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
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
1644
  res = pr_ctrls_init_acl(acl);
1✔
1645
  ck_assert_msg(res == 0, "Failed to init acl: %s", strerror(errno));
1✔
1646
}
1✔
1647
END_TEST
1648

1649
static int test_action_cb(pr_ctrls_t *ctl, int reqargc, char **reqargv) {
1✔
1650
  return 0;
1✔
1651
}
1✔
1652

1✔
1653
START_TEST (ctrls_check_acl_test) {
1✔
1654
  int res;
1655
  pr_ctrls_t *ctrl;
1656
  pr_ctrls_cl_t *cl;
1✔
1657
  ctrls_acl_t *acl;
1658
  const char *action;
1✔
1659
  ctrls_acttab_t acttab[] = {
1660
    { "test", "desc", NULL, test_action_cb },
1✔
1661
    { NULL, NULL, NULL, NULL }
1✔
1662
  };
1✔
1663

1✔
1664
  mark_point();
1✔
1665
  res = pr_ctrls_check_acl(NULL, NULL, NULL);
1✔
1666
  ck_assert_msg(res < 0, "Failed to handle null ctrl");
1✔
1667
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1668
    strerror(errno), errno);
1✔
1669

1670
  mark_point();
1✔
1671
  ctrl = pr_ctrls_alloc();
1672
  res = pr_ctrls_check_acl(ctrl, NULL, NULL);
1✔
1673
  ck_assert_msg(res < 0, "Failed to handle ctrl without client");
1674
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1675
    strerror(errno), errno);
1✔
1676

1✔
1677
  mark_point();
1✔
1678
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
1679
  cl->cl_uid = cl->cl_gid = 1;
1✔
1680
  ctrl->ctrls_cl = cl;
1681
  res = pr_ctrls_check_acl(ctrl, NULL, NULL);
1✔
1682
  ck_assert_msg(res < 0, "Failed to handle null acttab");
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
  res = pr_ctrls_check_acl(ctrl, acttab, NULL);
1✔
1688
  ck_assert_msg(res < 0, "Failed to handle null action");
1✔
1689
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1690
    strerror(errno), errno);
1✔
1691

1692
  mark_point();
1693
  action = "foobar";
1✔
1694
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1✔
1695
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1696

1✔
1697
  mark_point();
1✔
1698
  action = "test";
1699
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1700
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1701

1✔
1702
  mark_point();
1✔
1703
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
1704
  res = pr_ctrls_init_acl(acl);
1✔
1705
  acttab[0].act_acl = acl;
1706
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1707
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1708

1✔
1709
  mark_point();
1✔
1710
  acl->acl_groups.ngids = 1;
1✔
1711
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1✔
1712
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1713

1714
  mark_point();
1✔
1715
  acl->acl_users.nuids = 1;
1✔
1716
  res = pr_ctrls_check_acl(ctrl, acttab, action);
1717
  ck_assert_msg(res == TRUE, "Expected TRUE, got %d", res);
1✔
1718
}
1✔
1719
END_TEST
1✔
1720

1✔
1721
START_TEST (ctrls_parse_acl_test) {
1✔
1722
  char **res;
1✔
1723
  const char *names;
1✔
1724

1725
  mark_point();
1✔
1726
  res = pr_ctrls_parse_acl(NULL, NULL);
1✔
1727
  ck_assert_msg(res == NULL, "Failed to handle null pool");
1728
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1729
    strerror(errno), errno);
1730

1731
  mark_point();
1✔
1732
  res = pr_ctrls_parse_acl(p, NULL);
1✔
1733
  ck_assert_msg(res == NULL, "Failed to handle null ACL text");
1✔
1734
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1735
    strerror(errno), errno);
1✔
1736

1✔
1737
  mark_point();
1✔
1738
  names = "foo";
1✔
1739
  res = pr_ctrls_parse_acl(p, names);
1740
  ck_assert_msg(res != NULL, "Failed to parse ACL '%s': %s", names,
1741
    strerror(errno));
1742
  ck_assert_msg(strcmp(res[0], "foo") == 0, "Expected 'foo', got '%s'", res[0]);
1743
  ck_assert_msg(res[1] == NULL, "Expected NULL, got %p", res[1]);
1✔
1744

1✔
1745
  mark_point();
1✔
1746
  names = "foo,'Bar',BAZ";
1✔
1747
  res = pr_ctrls_parse_acl(p, names);
1748
  ck_assert_msg(res != NULL, "Failed to parse ACL '%s': %s", names,
1749
    strerror(errno));
1✔
1750
  ck_assert_msg(strcmp(res[0], "foo") == 0, "Expected 'foo', got '%s'", res[0]);
1✔
1751
  ck_assert_msg(strcmp(res[1], "'Bar'") == 0, "Expected 'Bar', got '%s'", res[1]);
1✔
1752
  ck_assert_msg(strcmp(res[2], "BAZ") == 0, "Expected 'BAZ', got '%s'", res[2]);
1✔
1753
  ck_assert_msg(res[3] == NULL, "Expected NULL, got %p", res[3]);
1754
}
1755
END_TEST
1✔
1756

1✔
1757
START_TEST (ctrls_set_group_acl_test) {
1✔
1758
  int res;
1✔
1759
  ctrls_group_acl_t *group_acl;
1760
  const char *allow;
1761
  char *grouplist;
1✔
1762

1✔
1763
  mark_point();
1✔
1764
  res = pr_ctrls_set_group_acl(NULL, NULL, NULL, NULL);
1✔
1765
  ck_assert_msg(res < 0, "Failed to handle null pool");
1766
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1767
    strerror(errno), errno);
1✔
1768

1✔
1769
  mark_point();
1✔
1770
  res = pr_ctrls_set_group_acl(p, NULL, NULL, NULL);
1✔
1771
  ck_assert_msg(res < 0, "Failed to handle null group_acl");
1✔
1772
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1773
    strerror(errno), errno);
1774

1✔
1775
  mark_point();
1✔
1776
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1✔
1777
  res = pr_ctrls_set_group_acl(p, group_acl, NULL, NULL);
1✔
1778
  ck_assert_msg(res < 0, "Failed to handle null allow");
1✔
1779
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1780
    strerror(errno), errno);
1781

1✔
1782
  mark_point();
1✔
1783
  allow = "allow";
1✔
1784
  res = pr_ctrls_set_group_acl(p, group_acl, allow, NULL);
1✔
1785
  ck_assert_msg(res < 0, "Failed to handle null grouplist");
1✔
1786
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1787
    strerror(errno), errno);
1788

1✔
1789
  mark_point();
1✔
1790
  grouplist = "foo,bar,baz,wheel";
1✔
1791
  res = pr_ctrls_set_group_acl(p, group_acl, allow, grouplist);
1✔
1792
  ck_assert_msg(res == 0, "Failed to set group acl: %s", strerror(errno));
1✔
1793
  ck_assert_msg(group_acl->allow == TRUE, "Expected TRUE, got %d",
1794
    group_acl->allow);
1✔
1795
  /* Note that we expect zero here, because of name/GID lookup failures. */
1796
  ck_assert_msg(group_acl->ngids == 0, "Expected 0, got %d",
1✔
1797
    group_acl->ngids);
1✔
1798
  ck_assert_msg(group_acl->gids != NULL, "Got NULL unexpectedly");
1✔
1799

1800
  mark_point();
1801
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1✔
1802
  allow = "deny";
1✔
1803
  grouplist = "foo,*";
1✔
1804
  res = pr_ctrls_set_group_acl(p, group_acl, allow, grouplist);
1✔
1805
  ck_assert_msg(res == 0, "Failed to set group acl: %s", strerror(errno));
1806
  ck_assert_msg(group_acl->allow == FALSE, "Expected FALSE, got %d",
1✔
1807
    group_acl->allow);
1✔
1808
  ck_assert_msg(group_acl->ngids == 1, "Expected 1, got %d",
1✔
1809
    group_acl->ngids);
1✔
1810
  ck_assert_msg(group_acl->gids == NULL, "Expected NULL, got %p",
1811
    group_acl->gids);
1✔
1812
}
1✔
1813
END_TEST
1✔
1814

1✔
1815
START_TEST (ctrls_set_user_acl_test) {
1816
  int res;
1817
  ctrls_user_acl_t *user_acl;
1✔
1818
  const char *allow;
1✔
1819
  char *userlist;
1✔
1820

1✔
1821
  mark_point();
1✔
1822
  res = pr_ctrls_set_user_acl(NULL, NULL, NULL, NULL);
1✔
1823
  ck_assert_msg(res < 0, "Failed to handle null pool");
1✔
1824
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1825
    strerror(errno), errno);
1✔
1826

1827
  mark_point();
1828
  res = pr_ctrls_set_user_acl(p, NULL, NULL, NULL);
1829
  ck_assert_msg(res < 0, "Failed to handle null user_acl");
1830
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1831
    strerror(errno), errno);
1✔
1832

1✔
1833
  mark_point();
1✔
1834
  user_acl = pcalloc(p, sizeof(ctrls_user_acl_t));
1835
  res = pr_ctrls_set_user_acl(p, user_acl, NULL, NULL);
1836
  ck_assert_msg(res < 0, "Failed to handle null allow");
1✔
1837
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1838
    strerror(errno), errno);
1✔
1839

1✔
1840
  mark_point();
1841
  allow = "allow";
1842
  res = pr_ctrls_set_user_acl(p, user_acl, allow, NULL);
1✔
1843
  ck_assert_msg(res < 0, "Failed to handle null userlist");
1✔
1844
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1845
    strerror(errno), errno);
1✔
1846

1847
  mark_point();
1848
  userlist = "foo,bar,baz,root";
1✔
1849
  res = pr_ctrls_set_user_acl(p, user_acl, allow, userlist);
1✔
1850
  ck_assert_msg(res == 0, "Failed to set user acl: %s", strerror(errno));
1851
  ck_assert_msg(user_acl->allow == TRUE, "Expected TRUE, got %d",
1✔
1852
    user_acl->allow);
1✔
1853
  /* Note that we expect zero here, because of name/UID lookup failures. */
1854
  ck_assert_msg(user_acl->nuids == 0, "Expected 0, got %d", user_acl->nuids);
1855
  ck_assert_msg(user_acl->uids != NULL, "Got NULL unexpectedly");
1✔
1856

1✔
1857
  mark_point();
1✔
1858
  user_acl = pcalloc(p, sizeof(ctrls_user_acl_t));
1859
  allow = "deny";
1✔
1860
  userlist = "foo,*";
1✔
1861
  res = pr_ctrls_set_user_acl(p, user_acl, allow, userlist);
1862
  ck_assert_msg(res == 0, "Failed to set user acl: %s", strerror(errno));
1863
  ck_assert_msg(user_acl->allow == FALSE, "Expected FALSE, got %d",
1✔
1864
    user_acl->allow);
1✔
1865
  ck_assert_msg(user_acl->nuids == 1, "Expected 1, got %d", user_acl->nuids);
1✔
1866
  ck_assert_msg(user_acl->uids == NULL, "Expected NULL, got %p",
1867
    user_acl->uids);
1✔
1868
}
1✔
1869
END_TEST
1870

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

1✔
1883
  mark_point();
1✔
1884
  res = pr_ctrls_set_module_acls(NULL, NULL, NULL, NULL, NULL, NULL);
1885
  ck_assert_msg(res == NULL, "Failed to handle null acttab");
1886
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1887
    strerror(errno), errno);
1✔
1888

1✔
1889
  mark_point();
1890
  res = pr_ctrls_set_module_acls(acttab, NULL, NULL, NULL, NULL, NULL);
1✔
1891
  ck_assert_msg(res == NULL, "Failed to handle null acl_pool");
1✔
1892
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1893
    strerror(errno), errno);
1✔
1894

1895
  mark_point();
1896
  res = pr_ctrls_set_module_acls(acttab, p, NULL, NULL, NULL, NULL);
1✔
1897
  ck_assert_msg(res == NULL, "Failed to handle null actions");
1✔
1898
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1899
    strerror(errno), errno);
1900

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

1907
  mark_point();
1✔
1908
  allow = "allow";
1✔
1909
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, NULL, NULL);
1✔
1910
  ck_assert_msg(res == NULL, "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_acls(acttab, p, good_actions, allow, type, NULL);
1✔
1917
  ck_assert_msg(res == NULL, "Failed to handle null list");
1✔
1918
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1919
    strerror(errno), errno);
1920

1✔
1921
  mark_point();
1✔
1922
  list = "foo,bar,baz";
1✔
1923
  res = pr_ctrls_set_module_acls(acttab, p, bad_actions, allow, type, list);
1✔
1924
  ck_assert_msg(res == NULL, "Failed to handle invalid type '%s'", type);
1✔
1925
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1926
    strerror(errno), errno);
1927

1928
  mark_point();
1929
  type = "user";
1✔
1930
  res = pr_ctrls_set_module_acls(acttab, p, bad_actions, allow, type, list);
1931
  ck_assert_msg(res != NULL, "Failed to handle invalid action");
1✔
1932
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1933
    strerror(errno), errno);
1✔
1934
  ck_assert_msg(strcmp(res, "bar") == 0, "Expected 'bar', got '%s'", res);
1✔
1935

1936
  mark_point();
1937
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
1938
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
1✔
1939
    "Failed to initialize acl: %s", strerror(errno));
1✔
1940

1✔
1941
  acttab[0].act_acl = acl;
1942
  type = "group";
1943
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, type, list);
1✔
1944
  ck_assert_msg(res == NULL, "Failed to handle good action: %s", strerror(errno));
1✔
1945

1✔
1946
  mark_point();
1✔
1947
  type = "user";
1948
  res = pr_ctrls_set_module_acls(acttab, p, good_actions, allow, type, list);
1949
  ck_assert_msg(res == NULL, "Failed to handle good action: %s", strerror(errno));
1✔
1950

1✔
1951
  mark_point();
1✔
1952
  res = pr_ctrls_set_module_acls(acttab, p, all_actions, allow, type, list);
1✔
1953
  ck_assert_msg(res == NULL, "Failed to handle all actions: %s", strerror(errno));
1✔
1954
}
1955
END_TEST
1✔
1956

1957
START_TEST (ctrls_set_module_acls2_test) {
1✔
1958
  int res;
1✔
1959
  char *list;
1✔
1960
  const char *allow, *type, *bad_action = NULL;
1961
  ctrls_acl_t *acl;
1✔
1962
  char *good_actions[] = { "test", NULL };
1✔
1963
  char *bad_actions[] = { "bar", "baz", NULL };
1✔
1964
  char *all_actions[] = { "all", NULL };
1965
  ctrls_acttab_t acttab[] = {
1✔
1966
    { "test", "desc", NULL, test_action_cb },
1967
    { NULL, NULL, NULL, NULL }
1968
  };
1✔
1969

1✔
1970
  mark_point();
1✔
1971
  res = pr_ctrls_set_module_acls2(NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1✔
1972
  ck_assert_msg(res < 0, "Failed to handle null acttab");
1✔
1973
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1974
    strerror(errno), errno);
1✔
1975

1976
  mark_point();
1977
  res = pr_ctrls_set_module_acls2(acttab, NULL, NULL, NULL, NULL, NULL, NULL);
1978
  ck_assert_msg(res < 0, "Failed to handle null acl_pool");
1✔
1979
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1980
    strerror(errno), errno);
1✔
1981

1✔
1982
  mark_point();
1✔
1983
  res = pr_ctrls_set_module_acls2(acttab, p, NULL, NULL, NULL, NULL, NULL);
1✔
1984
  ck_assert_msg(res < 0, "Failed to handle null actions");
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_set_module_acls2(acttab, p, good_actions, NULL, NULL, NULL,
1✔
1990
    NULL);
1991
  ck_assert_msg(res < 0, "Failed to handle null allow");
1992
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1993
    strerror(errno), errno);
1✔
1994

1✔
1995
  mark_point();
1✔
1996
  allow = "allow";
1997
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, NULL, NULL,
1998
    NULL);
1✔
1999
  ck_assert_msg(res < 0, "Failed to handle null type");
1✔
2000
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2001
    strerror(errno), errno);
1✔
2002

1✔
2003
  mark_point();
2004
  type = "test";
2005
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, type, NULL,
1✔
2006
    NULL);
1✔
2007
  ck_assert_msg(res < 0, "Failed to handle null list");
2008
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2009
    strerror(errno), errno);
1✔
2010

2011
  mark_point();
1✔
2012
  list = "foo,bar,baz";
1✔
2013
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
2014
    NULL);
2015
  ck_assert_msg(res < 0, "Failed to handle null bad_action");
1✔
2016
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2017
    strerror(errno), errno);
1✔
2018

2019
  mark_point();
1✔
2020
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
1✔
2021
    &bad_action);
2022
  ck_assert_msg(res < 0, "Failed to handle invalid type '%s'", type);
1✔
2023
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2024
    strerror(errno), errno);
2025

2026
  mark_point();
1✔
2027
  type = "user";
1✔
2028
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
2029
    &bad_action);
1✔
2030
  ck_assert_msg(res < 0, "Failed to handle invalid action");
1✔
2031
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
2032
    strerror(errno), errno);
1✔
2033
  ck_assert_msg(strcmp(bad_action, "bar") == 0,
2034
    "Expected 'bar', got '%s'", bad_action);
2035

1✔
2036
  mark_point();
1✔
2037
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
2038
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
1✔
2039
    "Failed to initialize acl: %s", strerror(errno));
2040

1✔
2041
  acttab[0].act_acl = acl;
2042
  type = "group";
2043
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, type, list,
1✔
2044
    &bad_action);
1✔
2045
  ck_assert_msg(res == 0, "Failed to handle good action: %s", strerror(errno));
2046

1✔
2047
  mark_point();
1✔
2048
  type = "user";
1✔
2049
  res = pr_ctrls_set_module_acls2(acttab, p, good_actions, allow, type, list,
1✔
2050
    &bad_action);
1✔
2051
  ck_assert_msg(res == 0, "Failed to handle good action: %s", strerror(errno));
2052

1✔
2053
  mark_point();
1✔
2054
  res = pr_ctrls_set_module_acls2(acttab, p, all_actions, allow, type, list,
1✔
2055
    &bad_action);
2056
  ck_assert_msg(res == 0, "Failed to handle all actions: %s", strerror(errno));
2057
}
2058
END_TEST
1✔
2059

1✔
2060
START_TEST (ctrls_unregister_module_actions_test) {
1✔
2061
  char *res;
2062
  char *good_actions[] = { "test", NULL };
2063
  char *bad_actions[] = { "bar", "baz", NULL };
1✔
2064
  ctrls_acl_t *acl;
1✔
2065
  ctrls_acttab_t acttab[] = {
1✔
2066
    { "test", "desc", NULL, test_action_cb },
2067
    { NULL, NULL, NULL, NULL }
1✔
2068
  };
1✔
2069
  module m;
1✔
2070

2071
  mark_point();
1✔
2072
  res = pr_ctrls_unregister_module_actions(NULL, NULL, NULL);
2073
  ck_assert_msg(res == NULL, "Failed to handle null acttab");
2074
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2075
    strerror(errno), errno);
2076

2077
  mark_point();
889✔
2078
  res = pr_ctrls_unregister_module_actions(acttab, NULL, NULL);
889✔
2079
  ck_assert_msg(res == NULL, "Failed to handle null actions");
889✔
2080
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2081
    strerror(errno), errno);
889✔
2082

889✔
2083
  mark_point();
2084
  res = pr_ctrls_unregister_module_actions(acttab, good_actions, NULL);
2085
  ck_assert_msg(res == NULL, "Failed to handle null module");
889✔
2086
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2087
    strerror(errno), errno);
889✔
2088

889✔
2089
  mark_point();
889✔
2090
  m.name = "test";
889✔
2091
  res = pr_ctrls_unregister_module_actions(acttab, bad_actions, &m);
889✔
2092
  ck_assert_msg(res != NULL, "Failed to handle invalid action");
889✔
2093
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
889✔
2094
    strerror(errno), errno);
889✔
2095
  ck_assert_msg(strcmp(res, "bar") == 0, "Expected 'bar', got '%s'", res);
889✔
2096

889✔
2097
  mark_point();
889✔
2098
  acl = pcalloc(p, sizeof(ctrls_acl_t));
889✔
2099
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
889✔
2100
    "Failed to initialize acl: %s", strerror(errno));
2101
  acttab[0].act_acl = acl;
889✔
2102
  res = pr_ctrls_unregister_module_actions(acttab, good_actions, &m);
889✔
2103
  ck_assert_msg(res == NULL, "Failed to handle valid action: %s",
889✔
2104
    strerror(errno));
889✔
2105
}
889✔
2106
END_TEST
889✔
2107

889✔
2108
START_TEST (ctrls_unregister_module_actions2_test) {
889✔
2109
  int res;
2110
  const char *bad_action = NULL;
2111
  char *good_actions[] = { "test", NULL };
889✔
2112
  char *bad_actions[] = { "bar", "baz", NULL };
889✔
2113
  ctrls_acl_t *acl;
889✔
2114
  ctrls_acttab_t acttab[] = {
889✔
2115
    { "test", "desc", NULL, test_action_cb },
889✔
2116
    { NULL, NULL, NULL, NULL }
889✔
2117
  };
889✔
2118
  module m;
889✔
2119

889✔
2120
  mark_point();
889✔
2121
  res = pr_ctrls_unregister_module_actions2(NULL, NULL, NULL, NULL);
889✔
2122
  ck_assert_msg(res < 0, "Failed to handle null acttab");
889✔
2123
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
889✔
2124
    strerror(errno), errno);
2125

2126
  mark_point();
889✔
2127
  res = pr_ctrls_unregister_module_actions2(acttab, NULL, NULL, NULL);
889✔
2128
  ck_assert_msg(res < 0, "Failed to handle null actions");
2129
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2130
    strerror(errno), errno);
2131

2132
  mark_point();
2133
  res = pr_ctrls_unregister_module_actions2(acttab, good_actions, NULL, NULL);
2134
  ck_assert_msg(res < 0, "Failed to handle null module");
2135
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2136
    strerror(errno), errno);
2137

2138
  mark_point();
2139
  m.name = "test";
2140
  res = pr_ctrls_unregister_module_actions2(acttab, bad_actions, &m, NULL);
2141
  ck_assert_msg(res < 0, "Failed to handle null bad_action");
2142
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2143
    strerror(errno), errno);
2144

2145
  mark_point();
2146
  res = pr_ctrls_unregister_module_actions2(acttab, bad_actions, &m,
2147
    &bad_action);
2148
  ck_assert_msg(res < 0, "Failed to handle invalid action");
2149
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2150
    strerror(errno), errno);
2151
  ck_assert_msg(bad_action != NULL, "Expected bad_action, got NULL");
2152
  ck_assert_msg(strcmp(bad_action, "bar") == 0,
2153
    "Expected 'bar', got '%s'", bad_action);
2154

2155
  mark_point();
2156
  acl = pcalloc(p, sizeof(ctrls_acl_t));
2157
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
2158
    "Failed to initialize acl: %s", strerror(errno));
2159
  acttab[0].act_acl = acl;
2160
  res = pr_ctrls_unregister_module_actions2(acttab, good_actions, &m,
2161
    &bad_action);
2162
  ck_assert_msg(res == 0, "Failed to handle valid action: %s", strerror(errno));
2163
}
2164
END_TEST
2165

2166
START_TEST (ctrls_set_logfd_test) {
2167
  int fd, res;
2168

2169
  mark_point();
2170
  fd = 0;
2171
  res = pr_ctrls_set_logfd(fd);
2172
  ck_assert_msg(res == 0, "Failed to set ctrls log fd %d: %s", fd,
2173
     strerror(errno));
2174

2175
  mark_point();
2176
  fd = -1;
2177
  res = pr_ctrls_set_logfd(fd);
2178
  ck_assert_msg(res == 0, "Failed to set ctrls log fd %d: %s", fd,
2179
     strerror(errno));
2180
}
2181
END_TEST
2182

2183
START_TEST (ctrls_log_test) {
2184
  int fd, res;
2185

2186
  mark_point();
2187
  fd = -1;
2188
  pr_ctrls_set_logfd(fd);
2189
  res = pr_ctrls_log(NULL, NULL);
2190
  ck_assert_msg(res == 0, "Failed to handle bad logfd: %s", strerror(errno));
2191

2192
  mark_point();
2193
  fd = devnull_fd();
2194
  if (fd < 0) {
2195
    return;
2196
  }
2197

2198
  pr_ctrls_set_logfd(fd);
2199
  res = pr_ctrls_log(NULL, NULL);
2200
  ck_assert_msg(res == 0, "Failed to handle bad module_version: %s",
2201
    strerror(errno));
2202

2203
  mark_point();
2204
  res = pr_ctrls_log("test", NULL);
2205
  ck_assert_msg(res == 0, "Failed to handle null fmt: %s", strerror(errno));
2206

2207
  mark_point();
2208
  res = pr_ctrls_log("test", "%s", "foo bar baz");
2209
  ck_assert_msg(res == 0, "Failed to handle valid fmt: %s", strerror(errno));
2210

2211
  (void) close(fd);
2212
}
2213
END_TEST
2214

2215
#endif /* PR_USE_CTRLS */
2216

2217
Suite *tests_get_ctrls_suite(void) {
2218
  Suite *suite;
2219
  TCase *testcase;
2220

2221
  suite = suite_create("ctrls");
2222
  testcase = tcase_create("base");
2223

2224
#if defined(PR_USE_CTRLS)
2225
  tcase_add_checked_fixture(testcase, set_up, tear_down);
2226

2227
  tcase_add_test(testcase, ctrls_alloc_free_test);
2228
  tcase_add_test(testcase, ctrls_unregister_test);
2229
  tcase_add_test(testcase, ctrls_register_test);
2230
  tcase_add_test(testcase, ctrls_add_arg_test);
2231
  tcase_add_test(testcase, ctrls_add_response_test);
2232
  tcase_add_test(testcase, ctrls_copy_args_test);
2233
  tcase_add_test(testcase, ctrls_copy_resps_test);
2234
  tcase_add_test(testcase, ctrls_send_request_test);
2235
  tcase_add_test(testcase, ctrls_send_response_test);
2236
  tcase_add_test(testcase, ctrls_flush_response_test);
2237
  tcase_add_test(testcase, ctrls_recv_request_invalid_test);
2238
  tcase_add_test(testcase, ctrls_recv_request_too_large_test);
2239
  tcase_add_test(testcase, ctrls_recv_request_valid_test);
2240
  tcase_add_test(testcase, ctrls_recv_response_test);
2241
  tcase_add_test(testcase, ctrls_recv_response_too_large_test);
2242

2243
  tcase_add_test(testcase, ctrls_issock_unix_test);
2244
  tcase_add_test(testcase, ctrls_get_registered_actions_test);
2245
  tcase_add_test(testcase, ctrls_set_registered_actions_test);
2246
  tcase_add_test(testcase, ctrls_check_actions_test);
2247
  tcase_add_test(testcase, ctrls_run_ctrls_test);
2248
  tcase_add_test(testcase, ctrls_reset_ctrls_test);
2249
  tcase_add_test(testcase, ctrls_accept_test);
2250
  tcase_add_test(testcase, ctrls_accept_einval_path_test);
2251
  tcase_add_test(testcase, ctrls_connect_test);
2252
  tcase_add_test(testcase, ctrls_connect_eexist_directory_test);
2253
  tcase_add_test(testcase, ctrls_connect_eexist_symlink_test);
2254

2255
  /* mod_ctrls */
2256
  tcase_add_test(testcase, ctrls_check_group_acl_test);
2257
  tcase_add_test(testcase, ctrls_check_user_acl_test);
2258
  tcase_add_test(testcase, ctrls_init_acl_test);
2259
  tcase_add_test(testcase, ctrls_check_acl_test);
2260
  tcase_add_test(testcase, ctrls_parse_acl_test);
2261
  tcase_add_test(testcase, ctrls_set_group_acl_test);
2262
  tcase_add_test(testcase, ctrls_set_user_acl_test);
2263
  tcase_add_test(testcase, ctrls_set_module_acls_test);
2264
  tcase_add_test(testcase, ctrls_set_module_acls2_test);
2265
  tcase_add_test(testcase, ctrls_unregister_module_actions_test);
2266
  tcase_add_test(testcase, ctrls_unregister_module_actions2_test);
2267
  tcase_add_test(testcase, ctrls_set_logfd_test);
2268
  tcase_add_test(testcase, ctrls_log_test);
2269
#endif /* PR_USE_CTRLS */
2270

2271
  suite_add_tcase(suite, testcase);
2272
  return suite;
2273
}
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