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

proftpd / proftpd / 26694586415

30 May 2026 08:48PM UTC coverage: 92.637% (-0.4%) from 93.024%
26694586415

push

github

web-flow
Implement some sanity checks on the length of extended attributes (xattrs) that can be requested via custom SFTP extensions.

Bankde Eakasit posited that this could be another vector to triggering excessive memory allocations.

47319 of 51080 relevant lines covered (92.64%)

235.33 hits per line

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

98.08
/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) {
36✔
35
  (void) unlink(tmpfile_path);
36✔
36

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

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

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

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

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

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

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

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

72
  return fd;
73
}
74

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

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

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

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

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

98
  return 0;
99
}
100

101
/* Largely copied from mod_ctrls. */
102
static int listen_unix(const char *path) {
1✔
103
  int fd = -1, socklen = 0;
1✔
104
  struct sockaddr_un sock;
105
#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) && \
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);
1✔
112
  if (fd < 0) {
1✔
113
    fprintf(stderr, "error creating local socket: %s\n", strerror(errno));
×
114
    return -1;
×
115
  }
116

117
  (void) unlink(path);
1✔
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

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

130
  if (listen(fd, 5) < 0) {
1✔
131
    fprintf(stderr, "error listening on local socket: %s\n", strerror(errno));
×
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) {
1✔
150
  int res;
151
  pr_ctrls_t *ctrl, *ctrl2, *ctrl3;
152

153
  mark_point();
1✔
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,
2✔
157
    strerror(errno), errno);
158

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

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

171
  /* LIFO order */
172
  mark_point();
1✔
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));
2✔
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));
2✔
179
  ctrl3->ctrls_tmp_pool = make_sub_pool(p);
1✔
180

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

188
  /* FIFO order */
189
  mark_point();
1✔
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));
2✔
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));
2✔
196
  ctrl3->ctrls_tmp_pool = make_sub_pool(p);
1✔
197

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

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

210
  mark_point();
1✔
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,
2✔
214
    strerror(errno), errno);
215
}
216
END_TEST
1✔
217

218
static int ctrls_test_cb(pr_ctrls_t *ctrl, int reqargc, char **reqargv) {
1✔
219
  return 0;
1✔
220
}
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) {
1✔
227
  int res;
228
  const char *action = NULL, *desc = NULL;
1✔
229
  module m;
230

231
  mark_point();
1✔
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,
2✔
235
    strerror(errno), errno);
236

237
  mark_point();
1✔
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");
2✔
241
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
242
    strerror(errno), errno);
243

244
  mark_point();
1✔
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");
2✔
248
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
249
    strerror(errno), errno);
250

251
  mark_point();
1✔
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));
2✔
254

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

260
  mark_point();
1✔
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));
2✔
263

264
  m.name = "test";
1✔
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));
2✔
267

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

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

281
  mark_point();
1✔
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,
2✔
285
    strerror(errno), errno);
286

287
  mark_point();
1✔
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");
2✔
291
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
292
    strerror(errno), errno);
293

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

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

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

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

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

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

323
  mark_point();
1✔
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,
2✔
327
    strerror(errno), errno);
328

329
  mark_point();
1✔
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");
2✔
333
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
334
    strerror(errno), errno);
335

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

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

346
  mark_point();
1✔
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,
2✔
350
    strerror(errno), errno);
351

352
  mark_point();
1✔
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");
2✔
356
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
357
    strerror(errno), errno);
358

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

365
  mark_point();
1✔
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));
2✔
369

370
  mark_point();
1✔
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));
2✔
373

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

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

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

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

389
  mark_point();
1✔
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,
2✔
393
    strerror(errno), errno);
394

395
  mark_point();
1✔
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");
2✔
399
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
400
    strerror(errno), errno);
401

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

408
  mark_point();
1✔
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");
2✔
412
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
413
    strerror(errno), errno);
414

415
  mark_point();
1✔
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));
2✔
418

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

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

427
  mark_point();
1✔
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));
2✔
431

432
  dst_ctrl = pr_ctrls_alloc();
1✔
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));
2✔
435
}
436
END_TEST
1✔
437

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

444
  mark_point();
1✔
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,
2✔
448
    strerror(errno), errno);
449

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

456
  mark_point();
1✔
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");
2✔
460
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
461
    strerror(errno), errno);
462

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

469
  mark_point();
1✔
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");
2✔
473
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
2✔
474
    strerror(errno), errno);
475

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

481
  mark_point();
1✔
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

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

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

494
  mark_point();
1✔
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,
2✔
498
    strerror(errno), errno);
499

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

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

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

522
  mark_point();
1✔
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");
2✔
527
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
2✔
528
    strerror(errno), errno);
529

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

535
  mark_point();
1✔
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

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

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

549
  mark_point();
1✔
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,
2✔
553
    strerror(errno), errno);
554

555
  mark_point();
1✔
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",
2✔
559
    strerror(errno));
560

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

569
  mark_point();
1✔
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;
574
  }
575

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

580
  mark_point();
1✔
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");
2✔
584
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
2✔
585
    strerror(errno), errno);
586
}
587
END_TEST
588

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

595
  mark_point();
1✔
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,
2✔
599
    strerror(errno), errno);
600

601
  mark_point();
1✔
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");
2✔
605
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
606
    strerror(errno), errno);
607

608
  mark_point();
1✔
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");
2✔
613
  ck_assert_msg(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
2✔
614
    strerror(errno), errno);
615

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

622
  cl->cl_fd = fd;
1✔
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,
2✔
627
    strerror(errno), errno);
628

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

635
  cl->cl_fd = fd;
1✔
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,
2✔
641
    strerror(errno), errno);
642

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

649
  mark_point();
1✔
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,
2✔
657
    strerror(errno), errno);
658

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

665
  mark_point();
1✔
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,
2✔
673
    strerror(errno), errno);
674

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

681
  mark_point();
1✔
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,
2✔
690
    strerror(errno), errno);
691

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

698
  mark_point();
1✔
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,
2✔
707
    strerror(errno), errno);
708

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

715
  mark_point();
1✔
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,
2✔
724
    strerror(errno), errno);
725

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

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

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

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

744
  cl->cl_fd = fd;
1✔
745

746
  mark_point();
1✔
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);
1✔
751
  ck_assert_msg(res < 0, "Failed to handle invalid msglen (too long)");
1✔
752
  ck_assert_msg(errno == E2BIG, "Expected E2BIG (%d), got %s (%d)", E2BIG,
2✔
753
    strerror(errno), errno);
754

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

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

768
  mark_point();
1✔
769
  m.name = "test";
1✔
770
  action = "test";
1✔
771
  desc = "desc";
1✔
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

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

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

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);
1✔
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));
1✔
792
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
2✔
793
    cl->cl_ctrls->nelts);
794
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
795
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
2✔
796
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
797
  ck_assert_msg(ctrl->ctrls_cb_args == NULL,
2✔
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) {
1✔
803
    return;
804
  }
805
  clear_array(cl->cl_ctrls);
1✔
806
  cl->cl_fd = fd;
1✔
807

808
  msg = "{\"action\":\"test\",\"args\":[\"a\"]}";
1✔
809
  msglen = strlen(msg);
1✔
810
  (void) write(fd, &msglen, sizeof(msglen));
1✔
811
  (void) write(fd, msg, msglen);
1✔
812
  rewind_fd(fd);
1✔
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",
2✔
816
    cl->cl_ctrls->nelts);
817
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
818
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
2✔
819
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
820
  ck_assert_msg(ctrl->ctrls_cb_args != NULL,
2✔
821
    "Expected callback args, got %p", ctrl->ctrls_cb_args);
822

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

831
  msg = "{\"action\":\"test\",\"args\":[\"next\"]}";
1✔
832
  msglen = strlen(msg);
1✔
833
  (void) write(fd, &msglen, sizeof(msglen));
1✔
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));
839
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
2✔
840
    cl->cl_ctrls->nelts);
841
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
842
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
2✔
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");
2✔
845
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
2✔
846
    "Expected 1 callback arg, got %d", ctrl->ctrls_cb_args->nelts);
847

848
  /* next_action present */
849

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

854
  mark_point();
1✔
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\"]}";
1✔
863
  msglen = strlen(msg);
1✔
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",
1✔
869
    strerror(errno));
870
  ck_assert_msg(cl->cl_ctrls->nelts == 2, "Expected 2 ctrl, got %d",
2✔
871
    cl->cl_ctrls->nelts);
872

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

880
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[1];
1✔
881
  ck_assert_msg(ctrl->ctrls_flags & PR_CTRLS_FL_REQUESTED,
2✔
882
    "Expected PR_CTRLS_FL_REQUESTED flag, got %lu", ctrl->ctrls_flags);
883
  ck_assert_msg(ctrl->ctrls_cb_args != NULL, "Expected callback args, got NULL");
2✔
884
  ck_assert_msg(ctrl->ctrls_cb_args->nelts == 1,
2✔
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
}
890
END_TEST
891

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

897
  mark_point();
1✔
898
  res = pr_ctrls_recv_response(NULL, -1, NULL, NULL);
1✔
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,
2✔
901
    strerror(errno), errno);
902

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

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

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,
2✔
918
    strerror(errno), errno);
919
  (void) close(fd);
1✔
920

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

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,
2✔
932
    strerror(errno), errno);
933

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

939
  mark_point();
1✔
940
  msglen = 2;
1✔
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,
2✔
947
    strerror(errno), errno);
948

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

954
  mark_point();
1✔
955
  msglen = 2;
1✔
956
  (void) write(fd, &msglen, sizeof(msglen));
1✔
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,
2✔
962
    strerror(errno), errno);
963

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

969
  mark_point();
1✔
970
  msg = "{}";
1✔
971
  msglen = strlen(msg);
1✔
972
  (void) write(fd, &msglen, sizeof(msglen));
1✔
973
  (void) write(fd, msg, msglen);
1✔
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,
2✔
978
    strerror(errno), errno);
979

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

985
  mark_point();
1✔
986
  msg = "{\"status\":0}";
1✔
987
  msglen = strlen(msg);
1✔
988
  (void) write(fd, &msglen, sizeof(msglen));
1✔
989
  (void) write(fd, msg, msglen);
1✔
990
  rewind_fd(fd);
1✔
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')");
994
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
995
    strerror(errno), errno);
996

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

1002
  mark_point();
1✔
1003
  msg = "{\"status\":0,\"responses\":[1]}";
1✔
1004
  msglen = strlen(msg);
1✔
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);
1✔
1009
  ck_assert_msg(res < 0,
1✔
1010
    "Failed to handle invalid message (non-text response)");
1011
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1012
    strerror(errno), errno);
1013

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

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);
1✔
1024
  rewind_fd(fd);
1✔
1025
  res = pr_ctrls_recv_response(p, fd, &status, NULL);
1✔
1026
  ck_assert_msg(res == 1, "Failed to handle valid response: %s",
1✔
1027
    strerror(errno));
1028

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

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

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

1043
  mark_point();
1✔
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)");
1✔
1049
  ck_assert_msg(errno == E2BIG, "Expected E2BIG (%d), got %s (%d)", E2BIG,
2✔
1050
    strerror(errno), errno);
1051

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

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

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

1067
#if defined(S_ISFIFO)
1068
  mark_point();
1✔
1069
  mode = 0;
1✔
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);
1✔
1074
  }
1075
#endif /* S_ISFIFO */
1076

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);
1✔
1082
  if (res < 0) {
1✔
1083
    ck_assert_msg(errno == ENOSYS, "Did not expect ENOSYS (%d)", ENOSYS);
×
1084
  }
1085
#endif /* S_ISSOCK */
1086
}
1087
END_TEST
1✔
1088

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

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

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

1107
  mark_point();
1✔
1108
  pr_block_ctrls();
1✔
1109
  res = pr_get_registered_actions(ctrl, 0);
1✔
1110
  ck_assert_msg(res < 0, "Failed to handle blocked actions");
2✔
1111
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
1112
    strerror(errno), errno);
1113
  pr_unblock_ctrls();
1✔
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));
2✔
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));
2✔
1124

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

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",
2✔
1132
    strerror(errno));
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",
2✔
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));
2✔
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",
2✔
1146
    strerror(errno));
1147
}
1148
END_TEST
1✔
1149

1150
START_TEST (ctrls_set_registered_actions_test) {
1✔
1151
  int res;
1152
  const char *action, *desc;
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,
2✔
1158
    strerror(errno), errno);
1159

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");
2✔
1163
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1164
    strerror(errno), errno);
1165

1166
  mark_point();
1✔
1167
  action = "test";
1✔
1168
  desc = "desc";
1✔
1169
  res = pr_ctrls_register(NULL, action, desc, ctrls_test_cb);
1✔
1170
  ck_assert_msg(res >= 0, "Failed to register ctrls action: %s", strerror(errno));
2✔
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",
2✔
1175
    strerror(errno));
1176

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

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

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

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

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

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

1210
  mark_point();
1✔
1211
  action = "test";
1✔
1212
  desc = "desc";
1✔
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));
2✔
1215

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

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

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));
2✔
1226

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

1232
  mark_point();
1✔
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",
2✔
1235
    strerror(errno));
1236

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

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

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

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

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

1272
  mark_point();
1✔
1273
  action = "test";
1✔
1274
  desc = "desc";
1✔
1275
  m.name = "test";
1✔
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));
2✔
1279

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

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));
2✔
1287

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

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

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

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

1308
  msg = "{\"action\":\"test\",\"args\":[\"FOO\"]}";
1✔
1309
  msglen = strlen(msg);
1✔
1310
  (void) write(fd, &msglen, sizeof(msglen));
1✔
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));
1✔
1315
  ck_assert_msg(cl->cl_ctrls->nelts == 1, "Expected 1 ctrl, got %d",
2✔
1316
    cl->cl_ctrls->nelts);
1317
  ctrl = ((pr_ctrls_t **) cl->cl_ctrls->elts)[0];
1✔
1318

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

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

1327
  mark_point();
1✔
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));
2✔
1332

1333
  mark_point();
1✔
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);
1✔
1338
  ck_assert_msg(res == 0, "Failed to run ctrls: %s", strerror(errno));
2✔
1339

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

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

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

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

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

1375
  mark_point();
1✔
1376
  res = pr_ctrls_reset();
1✔
1377
  ck_assert_msg(res == 0, "Failed to reset ctrls: %s", strerror(errno));
1✔
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));
2✔
1384

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

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

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

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

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

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

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

1420
START_TEST (ctrls_connect_test) {
1✔
1421
  int fd, res;
1422
  const char *socket_path;
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,
2✔
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");
2✔
1434
  ck_assert_msg(errno == ECONNREFUSED || errno == ENOENT,
2✔
1435
    "Expected ECONNREFUSED (%d) or ENOENT (%d), got %s (%d)", ECONNREFUSED,
1436
    ENOENT, strerror(errno), errno);
1437

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

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
}
1452
END_TEST
1453

1454
START_TEST (ctrls_check_group_acl_test) {
1✔
1455
  int res;
1456
  gid_t gid;
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,
2✔
1463
    strerror(errno), errno);
1464

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);
2✔
1469

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);
2✔
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",
2✔
1479
    group_acl->allow, res);
1480

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",
2✔
1484
    group_acl->allow, res);
1485

1486
  mark_point();
1✔
1487
  gid = 1;
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);
1✔
1492
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
2✔
1493

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

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

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,
2✔
1508
    strerror(errno), errno);
1509

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

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);
2✔
1519

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

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",
2✔
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);
1✔
1537
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
2✔
1538

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

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

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,
2✔
1552
    strerror(errno), errno);
1553

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));
2✔
1558
}
1559
END_TEST
1✔
1560

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

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

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,
2✔
1580
    strerror(errno), errno);
1581

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

1589
  mark_point();
1✔
1590
  cl = pcalloc(p, sizeof(pr_ctrls_cl_t));
1✔
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");
2✔
1595
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1596
    strerror(errno), errno);
1597

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");
2✔
1601
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1602
    strerror(errno), errno);
1603

1604
  mark_point();
1✔
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);
2✔
1608

1609
  mark_point();
1✔
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);
2✔
1613

1614
  mark_point();
1✔
1615
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
1616
  res = pr_ctrls_init_acl(acl);
1✔
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);
2✔
1620

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

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

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

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,
2✔
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");
2✔
1645
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1646
    strerror(errno), errno);
1647

1648
  mark_point();
1✔
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,
2✔
1652
    strerror(errno));
1653
  ck_assert_msg(strcmp(res[0], "foo") == 0, "Expected 'foo', got '%s'", res[0]);
2✔
1654
  ck_assert_msg(res[1] == NULL, "Expected NULL, got %p", res[1]);
2✔
1655

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

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

1674
  mark_point();
1✔
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,
2✔
1678
    strerror(errno), errno);
1679

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

1686
  mark_point();
1✔
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");
2✔
1690
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
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");
2✔
1697
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
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));
2✔
1704
  ck_assert_msg(group_acl->allow == TRUE, "Expected TRUE, got %d",
2✔
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",
2✔
1708
    group_acl->ngids);
1709
  ck_assert_msg(group_acl->gids != NULL, "Got NULL unexpectedly");
2✔
1710

1711
  mark_point();
1✔
1712
  group_acl = pcalloc(p, sizeof(ctrls_group_acl_t));
1✔
1713
  allow = "deny";
1✔
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));
2✔
1717
  ck_assert_msg(group_acl->allow == FALSE, "Expected FALSE, got %d",
2✔
1718
    group_acl->allow);
1719
  ck_assert_msg(group_acl->ngids == 1, "Expected 1, got %d",
2✔
1720
    group_acl->ngids);
1721
  ck_assert_msg(group_acl->gids == NULL, "Expected NULL, got %p",
2✔
1722
    group_acl->gids);
1723
}
1724
END_TEST
1✔
1725

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

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,
2✔
1736
    strerror(errno), errno);
1737

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

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");
2✔
1748
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1749
    strerror(errno), errno);
1750

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

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

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);
1✔
1773
  ck_assert_msg(res == 0, "Failed to set user acl: %s", strerror(errno));
2✔
1774
  ck_assert_msg(user_acl->allow == FALSE, "Expected FALSE, got %d",
2✔
1775
    user_acl->allow);
1776
  ck_assert_msg(user_acl->nuids == 1, "Expected 1, got %d", user_acl->nuids);
2✔
1777
  ck_assert_msg(user_acl->uids == NULL, "Expected NULL, got %p",
2✔
1778
    user_acl->uids);
1779
}
1780
END_TEST
1✔
1781

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

1794
  mark_point();
1✔
1795
  res = pr_ctrls_set_module_acls(NULL, NULL, NULL, NULL, NULL, NULL);
1✔
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,
2✔
1798
    strerror(errno), errno);
1799

1800
  mark_point();
1✔
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");
2✔
1803
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1804
    strerror(errno), errno);
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");
2✔
1809
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1810
    strerror(errno), errno);
1811

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");
2✔
1815
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1816
    strerror(errno), errno);
1817

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");
2✔
1822
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1823
    strerror(errno), errno);
1824

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

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

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

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

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

1857
  mark_point();
1✔
1858
  type = "user";
1✔
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));
2✔
1861

1862
  mark_point();
1✔
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));
2✔
1865
}
1866
END_TEST
1✔
1867

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;
1873
  char *good_actions[] = { "test", NULL };
1✔
1874
  char *bad_actions[] = { "bar", "baz", NULL };
1✔
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
  };
1880

1881
  mark_point();
1✔
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,
2✔
1885
    strerror(errno), errno);
1886

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");
2✔
1890
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1891
    strerror(errno), errno);
1892

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

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

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

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

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);
1926
  ck_assert_msg(res < 0, "Failed to handle null bad_action");
2✔
1927
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1928
    strerror(errno), errno);
1929

1930
  mark_point();
1✔
1931
  res = pr_ctrls_set_module_acls2(acttab, p, bad_actions, allow, type, list,
1✔
1932
    &bad_action);
1933
  ck_assert_msg(res < 0, "Failed to handle invalid type '%s'", type);
2✔
1934
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
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);
1941
  ck_assert_msg(res < 0, "Failed to handle invalid action");
2✔
1942
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
1943
    strerror(errno), errno);
1944
  ck_assert_msg(strcmp(bad_action, "bar") == 0,
2✔
1945
    "Expected 'bar', got '%s'", bad_action);
1946

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

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,
1✔
1955
    &bad_action);
1956
  ck_assert_msg(res == 0, "Failed to handle good action: %s", strerror(errno));
2✔
1957

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

1964
  mark_point();
1✔
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));
2✔
1968
}
1969
END_TEST
1✔
1970

1971
START_TEST (ctrls_unregister_module_actions_test) {
1✔
1972
  char *res;
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[] = {
1✔
1977
    { "test", "desc", NULL, test_action_cb },
1978
    { NULL, NULL, NULL, NULL }
1979
  };
1980
  module m;
1981

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");
1✔
1985
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1986
    strerror(errno), errno);
1987

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");
2✔
1991
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1992
    strerror(errno), errno);
1993

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");
2✔
1997
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
1998
    strerror(errno), errno);
1999

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");
2✔
2004
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
2✔
2005
    strerror(errno), errno);
2006
  ck_assert_msg(strcmp(res, "bar") == 0, "Expected 'bar', got '%s'", res);
2✔
2007

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

2019
START_TEST (ctrls_unregister_module_actions2_test) {
1✔
2020
  int res;
2021
  const char *bad_action = NULL;
1✔
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[] = {
1✔
2026
    { "test", "desc", NULL, test_action_cb },
2027
    { NULL, NULL, NULL, NULL }
2028
  };
2029
  module m;
2030

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");
1✔
2034
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
2035
    strerror(errno), errno);
2036

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");
2✔
2040
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
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");
2✔
2046
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
2✔
2047
    strerror(errno), errno);
2048

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

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

2066
  mark_point();
1✔
2067
  acl = pcalloc(p, sizeof(ctrls_acl_t));
1✔
2068
  ck_assert_msg(pr_ctrls_init_acl(acl) == 0,
2✔
2069
    "Failed to initialize acl: %s", strerror(errno));
2070
  acttab[0].act_acl = acl;
1✔
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));
2✔
2074
}
2075
END_TEST
1✔
2076

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

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

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

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

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

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

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

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

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

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

2126
#endif /* PR_USE_CTRLS */
2127

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

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

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

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

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

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

2179
  suite_add_tcase(suite, testcase);
894✔
2180
  return suite;
894✔
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