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

proftpd / proftpd / 26127302613

19 May 2026 09:51PM UTC coverage: 93.024% (+0.4%) from 92.635%
26127302613

push

github

51329 of 55178 relevant lines covered (93.02%)

215.14 hits per line

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

98.77
/tests/api/auth.c
1
/*
2
 * ProFTPD - FTP server testsuite
3
 * Copyright (c) 2014-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
/* Auth API tests */
25

26
#include "tests.h"
27

28
#define PR_TEST_AUTH_NAME                "testsuite_user"
29
#define PR_TEST_AUTH_NOBODY                "testsuite_nobody"
30
#define PR_TEST_AUTH_NOBODY2                "testsuite_nobody2"
31
#define PR_TEST_AUTH_NOGROUP                "testsuite_nogroup"
32
#define PR_TEST_AUTH_UID                500
33
#define PR_TEST_AUTH_UID_STR                "500"
34
#define PR_TEST_AUTH_NOUID                666
35
#define PR_TEST_AUTH_NOUID2                667
36
#define PR_TEST_AUTH_GID                500
37
#define PR_TEST_AUTH_GID_STR                "500"
38
#define PR_TEST_AUTH_NOGID                666
39
#define PR_TEST_AUTH_HOME                "/tmp"
40
#define PR_TEST_AUTH_SHELL                "/bin/bash"
41
#define PR_TEST_AUTH_PASSWD                "password"
42

43
static pool *p = NULL;
44
static server_rec *test_server = NULL;
45

46
static struct passwd test_pwd;
47
static struct group test_grp;
48

49
static unsigned int setpwent_count = 0;
50
static unsigned int endpwent_count = 0;
51
static unsigned int getpwent_count = 0;
52
static unsigned int getpwnam_count = 0;
53
static unsigned int getpwuid_count = 0;
54
static unsigned int name2uid_count = 0;
55
static unsigned int uid2name_count = 0;
56

57
static unsigned int setgrent_count = 0;
58
static unsigned int endgrent_count = 0;
59
static unsigned int getgrent_count = 0;
60
static unsigned int getgrnam_count = 0;
61
static unsigned int getgrgid_count = 0;
62
static unsigned int name2gid_count = 0;
63
static unsigned int gid2name_count = 0;
64
static unsigned int getgroups_count = 0;
65

66
static module testsuite_module = {
67
  NULL, NULL,
68

69
  /* Module API version */
70
  0x20,
71

72
  /* Module name */
73
  "testsuite",
74

75
  /* Module configuration directive table */
76
  NULL,
77

78
  /* Module command handler table */
79
  NULL,
80

81
  /* Module authentication handler table */
82
  NULL,
83

84
  /* Module initialization function */
85
  NULL,
86

87
  /* Session initialization function */
88
  NULL
89
};
90

91
MODRET handle_setpwent(cmd_rec *cmd) {
92
  setpwent_count++;
1✔
93
  return PR_HANDLED(cmd);
1✔
94
}
1✔
95

96
MODRET handle_endpwent(cmd_rec *cmd) {
97
  endpwent_count++;
1✔
98
  return PR_HANDLED(cmd);
1✔
99
}
1✔
100

101
MODRET handle_getpwent(cmd_rec *cmd) {
102
  getpwent_count++;
3✔
103

3✔
104
  if (getpwent_count == 1) {
105
    test_pwd.pw_uid = PR_TEST_AUTH_UID;
3✔
106
    test_pwd.pw_gid = PR_TEST_AUTH_GID;
1✔
107
    return mod_create_data(cmd, &test_pwd);
1✔
108
  }
1✔
109

110
  if (getpwent_count == 2) {
111
    test_pwd.pw_uid = (uid_t) -1;
2✔
112
    test_pwd.pw_gid = PR_TEST_AUTH_GID;
1✔
113
    return mod_create_data(cmd, &test_pwd);
1✔
114
  }
1✔
115

116
  if (getpwent_count == 3) {
117
    test_pwd.pw_uid = PR_TEST_AUTH_UID;
1✔
118
    test_pwd.pw_gid = (gid_t) -1;
1✔
119
    return mod_create_data(cmd, &test_pwd);
1✔
120
  }
1✔
121

122
  return PR_DECLINED(cmd);
123
}
124

125
MODRET handle_getpwnam(cmd_rec *cmd) {
126
  const char *name;
5✔
127

5✔
128
  name = cmd->argv[0];
129
  getpwnam_count++;
5✔
130

5✔
131
  if (strcmp(name, PR_TEST_AUTH_NAME) == 0) {
132
    test_pwd.pw_uid = PR_TEST_AUTH_UID;
5✔
133
    test_pwd.pw_gid = PR_TEST_AUTH_GID;
2✔
134
    return mod_create_data(cmd, &test_pwd);
2✔
135
  }
2✔
136

137
  if (strcmp(name, PR_TEST_AUTH_NOBODY) == 0) {
138
    test_pwd.pw_uid = (uid_t) -1;
3✔
139
    test_pwd.pw_gid = PR_TEST_AUTH_GID;
1✔
140
    return mod_create_data(cmd, &test_pwd);
1✔
141
  }
1✔
142

143
  if (strcmp(name, PR_TEST_AUTH_NOBODY2) == 0) {
144
    test_pwd.pw_uid = PR_TEST_AUTH_UID;
2✔
145
    test_pwd.pw_gid = (gid_t) -1;
1✔
146
    return mod_create_data(cmd, &test_pwd);
1✔
147
  }
1✔
148

149
  return PR_DECLINED(cmd);
150
}
151

152
MODRET handle_getpwuid(cmd_rec *cmd) {
153
  uid_t uid;
4✔
154

4✔
155
  uid = *((uid_t *) cmd->argv[0]);
156
  getpwuid_count++;
4✔
157

4✔
158
  if (uid == PR_TEST_AUTH_UID) {
159
    test_pwd.pw_uid = PR_TEST_AUTH_UID;
4✔
160
    test_pwd.pw_gid = PR_TEST_AUTH_GID;
1✔
161
    return mod_create_data(cmd, &test_pwd);
1✔
162
  }
1✔
163

164
  if (uid == PR_TEST_AUTH_NOUID) {
165
    test_pwd.pw_uid = (uid_t) -1;
3✔
166
    test_pwd.pw_gid = PR_TEST_AUTH_GID;
1✔
167
    return mod_create_data(cmd, &test_pwd);
1✔
168
  }
1✔
169

170
  if (uid == PR_TEST_AUTH_NOUID2) {
171
    test_pwd.pw_uid = PR_TEST_AUTH_UID;
2✔
172
    test_pwd.pw_gid = (gid_t) -1;
1✔
173
    return mod_create_data(cmd, &test_pwd);
1✔
174
  }
1✔
175

176
  return PR_DECLINED(cmd);
177
}
178

179
MODRET decline_name2uid(cmd_rec *cmd) {
180
  name2uid_count++;
1✔
181
  return PR_DECLINED(cmd);
1✔
182
}
1✔
183

184
MODRET handle_name2uid(cmd_rec *cmd) {
185
  const char *name;
1✔
186

1✔
187
  name = cmd->argv[0];
188
  name2uid_count++;
1✔
189

1✔
190
  if (strcmp(name, PR_TEST_AUTH_NAME) != 0) {
191
    return PR_DECLINED(cmd);
1✔
192
  }
193

194
  return mod_create_data(cmd, (void *) &(test_pwd.pw_uid));
195
}
1✔
196

197
MODRET decline_uid2name(cmd_rec *cmd) {
198
  uid2name_count++;
1✔
199
  return PR_DECLINED(cmd);
1✔
200
}
1✔
201

202
MODRET handle_uid2name(cmd_rec *cmd) {
203
  uid_t uid;
2✔
204

2✔
205
  uid = *((uid_t *) cmd->argv[0]);
206
  uid2name_count++;
2✔
207

2✔
208
  if (uid != PR_TEST_AUTH_UID) {
209
    return PR_DECLINED(cmd);
2✔
210
  }
211

212
  return mod_create_data(cmd, test_pwd.pw_name);
213
}
2✔
214

215
MODRET handle_setgrent(cmd_rec *cmd) {
216
  setgrent_count++;
1✔
217
  return PR_HANDLED(cmd);
1✔
218
}
1✔
219

220
MODRET handle_endgrent(cmd_rec *cmd) {
221
  endgrent_count++;
1✔
222
  return PR_HANDLED(cmd);
1✔
223
}
1✔
224

225
MODRET handle_getgrent(cmd_rec *cmd) {
226
  getgrent_count++;
2✔
227

2✔
228
  if (getgrent_count == 1) {
229
    test_grp.gr_gid = PR_TEST_AUTH_GID;
2✔
230
    return mod_create_data(cmd, &test_grp);
1✔
231
  }
1✔
232

233
  if (getgrent_count == 2) {
234
    test_grp.gr_gid = (gid_t) -1;
1✔
235
    return mod_create_data(cmd, &test_grp);
1✔
236
  }
1✔
237

238
  return PR_DECLINED(cmd);
239
}
240

241
MODRET handle_getgrnam(cmd_rec *cmd) {
242
  const char *name;
3✔
243

3✔
244
  name = cmd->argv[0];
245
  getgrnam_count++;
3✔
246

3✔
247
  if (strcmp(name, PR_TEST_AUTH_NAME) == 0) {
248
    test_grp.gr_gid = PR_TEST_AUTH_GID;
3✔
249
    return mod_create_data(cmd, &test_grp);
1✔
250
  }
1✔
251

252
  if (strcmp(name, PR_TEST_AUTH_NOGROUP) == 0) {
253
    test_grp.gr_gid = (gid_t) -1;
2✔
254
    return mod_create_data(cmd, &test_grp);
1✔
255
  }
1✔
256

257
  return PR_DECLINED(cmd);
258
}
259

260
MODRET handle_getgrgid(cmd_rec *cmd) {
261
  gid_t gid;
3✔
262

3✔
263
  gid = *((gid_t *) cmd->argv[0]);
264
  getgrgid_count++;
3✔
265

3✔
266
  if (gid == PR_TEST_AUTH_GID) {
267
    test_grp.gr_gid = PR_TEST_AUTH_GID;
3✔
268
    return mod_create_data(cmd, &test_grp);
1✔
269
  }
1✔
270

271
  if (gid == PR_TEST_AUTH_NOGID) {
272
    test_grp.gr_gid = (gid_t) -1;
2✔
273
    return mod_create_data(cmd, &test_grp);
1✔
274
  }
1✔
275

276
  return PR_DECLINED(cmd);
277
}
278

279
MODRET decline_name2gid(cmd_rec *cmd) {
280
  name2gid_count++;
2✔
281
  return PR_DECLINED(cmd);
2✔
282
}
2✔
283

284
MODRET handle_name2gid(cmd_rec *cmd) {
285
  const char *name;
1✔
286

1✔
287
  name = cmd->argv[0];
288
  name2gid_count++;
1✔
289

1✔
290
  if (strcmp(name, PR_TEST_AUTH_NAME) != 0) {
291
    return PR_DECLINED(cmd);
1✔
292
  }
293

294
  return mod_create_data(cmd, (void *) &(test_grp.gr_gid));
295
}
1✔
296

297
MODRET decline_gid2name(cmd_rec *cmd) {
298
  gid2name_count++;
1✔
299
  return PR_DECLINED(cmd);
1✔
300
}
1✔
301

302
MODRET handle_gid2name(cmd_rec *cmd) {
303
  gid_t gid;
2✔
304

2✔
305
  gid = *((gid_t *) cmd->argv[0]);
306
  gid2name_count++;
2✔
307

2✔
308
  if (gid != PR_TEST_AUTH_GID) {
309
    return PR_DECLINED(cmd);
2✔
310
  }
311

312
  return mod_create_data(cmd, test_grp.gr_name);
313
}
2✔
314

315
MODRET handle_getgroups(cmd_rec *cmd) {
316
  const char *name;
2✔
317
  array_header *gids = NULL, *names = NULL;
2✔
318

2✔
319
  name = (char *) cmd->argv[0];
320

2✔
321
  if (cmd->argv[1]) {
322
    gids = (array_header *) cmd->argv[1];
2✔
323
  }
2✔
324

325
  if (cmd->argv[2]) {
326
    names = (array_header *) cmd->argv[2];
2✔
327
  }
2✔
328

329
  getgroups_count++;
330

2✔
331
  if (strcmp(name, PR_TEST_AUTH_NAME) != 0) {
332
    return PR_DECLINED(cmd);
2✔
333
  }
334

335
  if (gids != NULL) {
336
    *((gid_t *) push_array(gids)) = PR_TEST_AUTH_GID;
1✔
337
  }
1✔
338

339
  if (names != NULL) {
340
    *((char **) push_array(names)) = pstrdup(p, PR_TEST_AUTH_NAME);
1✔
341
  }
1✔
342

343
  return mod_create_data(cmd, (void *) &gids->nelts);
344
}
1✔
345

346
static int authn_rfc2228 = FALSE;
347

348
MODRET handle_authn(cmd_rec *cmd) {
349
  const char *user, *cleartext_passwd;
10✔
350

10✔
351
  user = cmd->argv[0];
352
  cleartext_passwd = cmd->argv[1];
10✔
353

10✔
354
  if (strcmp(user, PR_TEST_AUTH_NAME) == 0) {
355
    if (strcmp(cleartext_passwd, PR_TEST_AUTH_PASSWD) == 0) {
10✔
356
      if (authn_rfc2228) {
7✔
357
        authn_rfc2228 = FALSE;
5✔
358
        return mod_create_data(cmd, (void *) PR_AUTH_RFC2228_OK);
2✔
359
      }
2✔
360

361
      return PR_HANDLED(cmd);
362
    }
3✔
363

364
    return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);
365
  }
2✔
366

367
  return PR_DECLINED(cmd);
368
}
369

370
MODRET handle_authz(cmd_rec *cmd) {
371
  const char *user;
3✔
372

3✔
373
  user = cmd->argv[0];
374

3✔
375
  if (strcmp(user, PR_TEST_AUTH_NAME) == 0) {
376
    return PR_HANDLED(cmd);
3✔
377
  }
2✔
378

379
  return PR_ERROR_INT(cmd, PR_AUTH_NOPWD);
380
}
1✔
381

382
static int check_rfc2228 = FALSE;
383

384
MODRET handle_check(cmd_rec *cmd) {
385
  const char *user, *cleartext_passwd, *ciphertext_passwd;
5✔
386

5✔
387
  ciphertext_passwd = cmd->argv[0];
388
  user = cmd->argv[1];
5✔
389
  cleartext_passwd = cmd->argv[2];
5✔
390

5✔
391
  if (strcmp(user, PR_TEST_AUTH_NAME) == 0) {
392
    if (ciphertext_passwd != NULL &&
5✔
393
        strcmp(ciphertext_passwd, cleartext_passwd) == 0) {
4✔
394
      if (check_rfc2228) {
3✔
395
        check_rfc2228 = FALSE;
2✔
396
        return mod_create_data(cmd, (void *) PR_AUTH_RFC2228_OK);
1✔
397
      }
1✔
398

399
      return PR_HANDLED(cmd);
400
    }
1✔
401

402
    return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);
403
  }
2✔
404

405
  return PR_DECLINED(cmd);
406
}
407

408
MODRET handle_requires_pass(cmd_rec *cmd) {
409
  const char *name;
2✔
410

2✔
411
  name = cmd->argv[0];
412

2✔
413
  if (strcmp(name, PR_TEST_AUTH_NAME) == 0) {
414
    return mod_create_data(cmd, (void *) PR_AUTH_RFC2228_OK);
2✔
415
  }
1✔
416

417
  return PR_DECLINED(cmd);
418
}
419

420
/* Fixtures */
421

422
static void set_up(void) {
423
  if (p == NULL) {
39✔
424
    p = permanent_pool = make_sub_pool(NULL);
39✔
425
  }
39✔
426

427
  init_stash();
428
  init_auth();
39✔
429
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_DEFAULT);
39✔
430

39✔
431
  if (getenv("TEST_VERBOSE") != NULL) {
432
    pr_trace_set_levels("auth", 1, 20);
39✔
433
  }
39✔
434

435
  test_server = pcalloc(p, sizeof(server_rec));
436
  tests_stubs_set_main_server(test_server);
39✔
437

39✔
438
  test_pwd.pw_name = PR_TEST_AUTH_NAME;
439
  test_pwd.pw_uid = PR_TEST_AUTH_UID;
39✔
440
  test_pwd.pw_gid = PR_TEST_AUTH_GID;
39✔
441
  test_pwd.pw_dir = PR_TEST_AUTH_HOME;
39✔
442
  test_pwd.pw_shell = PR_TEST_AUTH_SHELL;
39✔
443

39✔
444
  test_grp.gr_name = PR_TEST_AUTH_NAME;
445
  test_grp.gr_gid = PR_TEST_AUTH_GID;
39✔
446

39✔
447
  /* Reset counters. */
448
  setpwent_count = 0;
449
  endpwent_count = 0;
39✔
450
  getpwent_count = 0;
39✔
451
  getpwnam_count = 0;
39✔
452
  getpwuid_count = 0;
39✔
453
  name2uid_count = 0;
39✔
454
  uid2name_count = 0;
39✔
455

39✔
456
  setgrent_count = 0;
457
  endgrent_count = 0;
39✔
458
  getgrent_count = 0;
39✔
459
  getgrnam_count = 0;
39✔
460
  getgrgid_count = 0;
39✔
461
  name2gid_count = 0;
39✔
462
  gid2name_count = 0;
39✔
463
  getgroups_count = 0;
39✔
464

39✔
465
  pr_auth_cache_clear();
466
}
39✔
467

39✔
468
static void tear_down(void) {
469
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_DEFAULT);
39✔
470

39✔
471
  if (getenv("TEST_VERBOSE") != NULL) {
472
    pr_trace_set_levels("auth", 0, 0);
39✔
473
  }
39✔
474

475
  if (p != NULL) {
476
    destroy_pool(p);
39✔
477
    p = session.pool = permanent_pool = NULL;
39✔
478
  }
39✔
479

480
  test_server = NULL;
481
  tests_stubs_set_main_server(NULL);
39✔
482
}
39✔
483

39✔
484
/* Tests */
485

486
START_TEST (auth_setpwent_test) {
487
  int res;
1✔
488
  authtable authtab;
1✔
489
  char *sym_name = "setpwent";
1✔
490

1✔
491
  pr_auth_setpwent(p);
492
  ck_assert_msg(setpwent_count == 0, "Expected call count 0, got %u",
1✔
493
    setpwent_count);
1✔
494
  mark_point();
495

1✔
496
  /* Load the appropriate AUTH symbol, and call it. */
497

498
  memset(&authtab, 0, sizeof(authtab));
499
  authtab.name = sym_name;
1✔
500
  authtab.handler = handle_setpwent;
1✔
501
  authtab.m = &testsuite_module;
1✔
502
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
503
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
504
    strerror(errno));
1✔
505

506
  pr_auth_setpwent(p);
507
  ck_assert_msg(setpwent_count == 1, "Expected call count 1, got %u",
1✔
508
    setpwent_count);
1✔
509

510
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
511
}
1✔
512
END_TEST
1✔
513

514
START_TEST (auth_endpwent_test) {
515
  int res;
1✔
516
  authtable authtab;
1✔
517
  char *sym_name = "endpwent";
1✔
518

1✔
519
  pr_auth_endpwent(p);
520
  ck_assert_msg(endpwent_count == 0, "Expected call count 0, got %u",
1✔
521
    endpwent_count);
1✔
522
  mark_point();
523

1✔
524
  /* Load the appropriate AUTH symbol, and call it. */
525

526
  memset(&authtab, 0, sizeof(authtab));
527
  authtab.name = sym_name;
1✔
528
  authtab.handler = handle_endpwent;
1✔
529
  authtab.m = &testsuite_module;
1✔
530
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
531
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
532
    strerror(errno));
1✔
533

534
  pr_auth_endpwent(p);
535
  ck_assert_msg(endpwent_count == 1, "Expected call count 1, got %u",
1✔
536
    endpwent_count);
1✔
537

538
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
539
}
1✔
540
END_TEST
1✔
541

542
START_TEST (auth_getpwent_test) {
543
  int res;
1✔
544
  struct passwd *pw;
1✔
545
  authtable authtab;
1✔
546
  char *sym_name = "getpwent";
1✔
547

1✔
548
  getpwent_count = 0;
549

1✔
550
  pw = pr_auth_getpwent(NULL);
551
  ck_assert_msg(pw == NULL, "Found pwent unexpectedly");
1✔
552
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
553
    errno, strerror(errno));
1✔
554

555
  pw = pr_auth_getpwent(p);
556
  ck_assert_msg(pw == NULL, "Found pwent unexpectedly");
1✔
557
  ck_assert_msg(getpwent_count == 0, "Expected call count 0, got %u",
1✔
558
    getpwent_count);
1✔
559
  mark_point();
560

1✔
561
  /* Load the appropriate AUTH symbol, and call it. */
562

563
  memset(&authtab, 0, sizeof(authtab));
564
  authtab.name = sym_name;
1✔
565
  authtab.handler = handle_getpwent;
1✔
566
  authtab.m = &testsuite_module;
1✔
567
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
568
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
569
    strerror(errno));
1✔
570

571
  pw = pr_auth_getpwent(p);
572
  ck_assert_msg(pw != NULL, "Failed to find pwent: %s", strerror(errno));
1✔
573
  ck_assert_msg(getpwent_count == 1, "Expected call count 1, got %u",
1✔
574
    getpwent_count);
1✔
575

576
  pw = pr_auth_getpwent(p);
577
  ck_assert_msg(pw == NULL, "Failed to avoid pwent with bad UID");
1✔
578
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
579
    strerror(errno), errno);
1✔
580
  ck_assert_msg(getpwent_count == 2, "Expected call count 2, got %u",
581
    getpwent_count);
1✔
582

583
  pw = pr_auth_getpwent(p);
584
  ck_assert_msg(pw == NULL, "Failed to avoid pwent with bad GID");
1✔
585
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
586
    strerror(errno), errno);
1✔
587
  ck_assert_msg(getpwent_count == 3, "Expected call count 3, got %u",
588
    getpwent_count);
1✔
589

590
  pr_auth_endpwent(p);
591
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1✔
592
}
1✔
593
END_TEST
1✔
594

595
START_TEST (auth_getpwnam_test) {
596
  int res;
1✔
597
  struct passwd *pw;
1✔
598
  authtable authtab;
1✔
599
  char *sym_name = "getpwnam";
1✔
600

1✔
601
  pw = pr_auth_getpwnam(NULL, NULL);
602
  ck_assert_msg(pw == NULL, "Found pwnam unexpectedly");
1✔
603
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
604
    errno, strerror(errno));
1✔
605

606
  pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME);
607
  ck_assert_msg(pw == NULL, "Found pwnam unexpectedly");
1✔
608
  ck_assert_msg(getpwnam_count == 0, "Expected call count 0, got %u",
1✔
609
    getpwnam_count);
1✔
610
  mark_point();
611

1✔
612
  /* Load the appropriate AUTH symbol, and call it. */
613

614
  memset(&authtab, 0, sizeof(authtab));
615
  authtab.name = sym_name;
1✔
616
  authtab.handler = handle_getpwnam;
1✔
617
  authtab.m = &testsuite_module;
1✔
618
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
619
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
620
    strerror(errno));
1✔
621

622
  mark_point();
623

1✔
624
  pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NOBODY);
625
  ck_assert_msg(pw == NULL, "Found user '%s' unexpectedly", PR_TEST_AUTH_NOBODY);
1✔
626
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
627
    strerror(errno), errno);
1✔
628

629
  pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NOBODY2);
630
  ck_assert_msg(pw == NULL, "Found user '%s' unexpectedly", PR_TEST_AUTH_NOBODY2);
1✔
631
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
632
    strerror(errno), errno);
1✔
633

634
  pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME);
635
  ck_assert_msg(pw != NULL, "Failed to find user '%s': %s", PR_TEST_AUTH_NAME,
1✔
636
    strerror(errno));
1✔
637
  ck_assert_msg(getpwnam_count == 3, "Expected call count 3, got %u",
638
    getpwnam_count);
1✔
639

640
  pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME);
641
  ck_assert_msg(pw != NULL, "Failed to find user '%s': %s", PR_TEST_AUTH_NAME,
1✔
642
    strerror(errno));
1✔
643
  ck_assert_msg(getpwnam_count == 4, "Expected call count 4, got %u",
644
    getpwnam_count);
1✔
645

646
  mark_point();
647

1✔
648
  pw = pr_auth_getpwnam(p, "other");
649
  ck_assert_msg(pw == NULL, "Found pwnam for user 'other' unexpectedly");
1✔
650
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
1✔
651
    errno, strerror(errno));
1✔
652
  ck_assert_msg(getpwnam_count == 5, "Expected call count 5, got %u",
653
    getpwnam_count);
1✔
654

655
  pr_auth_endpwent(p);
656
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1✔
657
}
1✔
658
END_TEST
1✔
659

660
START_TEST (auth_getpwuid_test) {
661
  int res;
1✔
662
  struct passwd *pw;
1✔
663
  authtable authtab;
1✔
664
  char *sym_name = "getpwuid";
1✔
665

1✔
666
  pw = pr_auth_getpwuid(NULL, -1);
667
  ck_assert_msg(pw == NULL, "Found pwuid unexpectedly");
1✔
668
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
669
    errno, strerror(errno));
1✔
670

671
  pw = pr_auth_getpwuid(p, PR_TEST_AUTH_UID);
672
  ck_assert_msg(pw == NULL, "Found pwuid unexpectedly");
1✔
673
  ck_assert_msg(getpwuid_count == 0, "Expected call count 0, got %u",
1✔
674
    getpwuid_count);
1✔
675
  mark_point();
676

1✔
677
  /* Load the appropriate AUTH symbol, and call it. */
678

679
  memset(&authtab, 0, sizeof(authtab));
680
  authtab.name = sym_name;
1✔
681
  authtab.handler = handle_getpwuid;
1✔
682
  authtab.m = &testsuite_module;
1✔
683
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
684
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
685
    strerror(errno));
1✔
686

687
  mark_point();
688

1✔
689
  pw = pr_auth_getpwuid(p, PR_TEST_AUTH_UID);
690
  ck_assert_msg(pw != NULL, "Failed to find pwuid: %s", strerror(errno));
1✔
691
  ck_assert_msg(getpwuid_count == 1, "Expected call count 1, got %u",
1✔
692
    getpwuid_count);
1✔
693

694
  pw = pr_auth_getpwuid(p, PR_TEST_AUTH_NOUID);
695
  ck_assert_msg(pw == NULL, "Found pwuid for NOUID unexpectedly");
1✔
696
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
697
    strerror(errno), errno);
1✔
698

699
  pw = pr_auth_getpwuid(p, PR_TEST_AUTH_NOUID2);
700
  ck_assert_msg(pw == NULL, "Found pwuid for NOUID2 unexpectedly");
1✔
701
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
702
    strerror(errno), errno);
1✔
703

704
  mark_point();
705

1✔
706
  pw = pr_auth_getpwuid(p, 5);
707
  ck_assert_msg(pw == NULL, "Found pwuid for UID 5 unexpectedly");
1✔
708
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
709
    strerror(errno), errno);
1✔
710

711
  ck_assert_msg(getpwuid_count == 4, "Expected call count 4, got %u",
712
    getpwuid_count);
1✔
713

714
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
715
}
1✔
716
END_TEST
1✔
717

718
START_TEST (auth_name2uid_test) {
719
  int res;
1✔
720
  uid_t uid;
1✔
721
  authtable authtab;
1✔
722
  char *sym_name = "name2uid";
1✔
723

1✔
724
  pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_NAME2UID);
725

1✔
726
  uid = pr_auth_name2uid(NULL, NULL);
727
  ck_assert_msg(uid == (uid_t) -1, "Found UID unexpectedly");
1✔
728
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
729
    errno, strerror(errno));
1✔
730

731
  uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
732
  ck_assert_msg(uid == (uid_t) -1, "Found UID unexpectedly");
1✔
733
  ck_assert_msg(name2uid_count == 0, "Expected call count 0, got %u",
1✔
734
    name2uid_count);
1✔
735
  mark_point();
736

1✔
737
  /* Load the appropriate AUTH symbol, and call it. */
738

739
  memset(&authtab, 0, sizeof(authtab));
740
  authtab.name = sym_name;
1✔
741
  authtab.handler = handle_name2uid;
1✔
742
  authtab.m = &testsuite_module;
1✔
743
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
744
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
745
    strerror(errno));
1✔
746

747
  mark_point();
748

1✔
749
  uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
750
  ck_assert_msg(uid == PR_TEST_AUTH_UID, "Expected UID %lu, got %lu",
1✔
751
    (unsigned long) PR_TEST_AUTH_UID, (unsigned long) uid);
1✔
752
  ck_assert_msg(name2uid_count == 1, "Expected call count 1, got %u",
753
    name2uid_count);
1✔
754

755
  mark_point();
756

1✔
757
  /* Call again; the call counter should NOT increment due to caching. */
758

759
  uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
760
  ck_assert_msg(uid == PR_TEST_AUTH_UID, "Expected UID %lu, got %lu",
1✔
761
    (unsigned long) PR_TEST_AUTH_UID, (unsigned long) uid);
1✔
762
  ck_assert_msg(name2uid_count == 1, "Expected call count 1, got %u",
763
    name2uid_count);
1✔
764

765
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
766
}
1✔
767
END_TEST
1✔
768

769
START_TEST (auth_uid2name_test) {
770
  int res;
1✔
771
  const char *name;
1✔
772
  authtable authtab;
1✔
773
  char *sym_name = "uid2name";
1✔
774

1✔
775
  pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_UID2NAME);
776

1✔
777
  name = pr_auth_uid2name(NULL, -1);
778
  ck_assert_msg(name == NULL, "Found name unexpectedly: %s", name);
1✔
779
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
780
    errno, strerror(errno));
1✔
781
  mark_point();
782

1✔
783
  name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
784
  ck_assert_msg(name != NULL, "Failed to find name for UID %lu: %s",
1✔
785
    (unsigned long) PR_TEST_AUTH_UID, strerror(errno));
1✔
786
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_UID_STR) == 0,
787
     "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name);
1✔
788
  ck_assert_msg(uid2name_count == 0, "Expected call count 0, got %u",
789
    uid2name_count);
1✔
790
  mark_point();
791

1✔
792
  /* Load the appropriate AUTH symbol, and call it. */
793

794
  memset(&authtab, 0, sizeof(authtab));
795
  authtab.name = sym_name;
1✔
796
  authtab.handler = handle_uid2name;
1✔
797
  authtab.m = &testsuite_module;
1✔
798
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
799
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
800
    strerror(errno));
1✔
801

802
  mark_point();
803

1✔
804
  name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
805
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
806
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1✔
807
    "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1✔
808
  ck_assert_msg(uid2name_count == 1, "Expected call count 1, got %u",
809
    uid2name_count);
1✔
810

811
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
812
}
1✔
813
END_TEST
1✔
814

815
START_TEST (auth_setgrent_test) {
816
  int res;
1✔
817
  authtable authtab;
1✔
818
  char *sym_name = "setgrent";
1✔
819

1✔
820
  pr_auth_setgrent(p);
821
  ck_assert_msg(setgrent_count == 0, "Expected call count 0, got %u",
1✔
822
    setgrent_count);
1✔
823
  mark_point();
824

1✔
825
  /* Load the appropriate AUTH symbol, and call it. */
826

827
  memset(&authtab, 0, sizeof(authtab));
828
  authtab.name = sym_name;
1✔
829
  authtab.handler = handle_setgrent;
1✔
830
  authtab.m = &testsuite_module;
1✔
831
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
832
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
833
    strerror(errno));
1✔
834

835
  pr_auth_setgrent(p);
836
  ck_assert_msg(setgrent_count == 1, "Expected call count 1, got %u",
1✔
837
    setgrent_count);
1✔
838

839
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
840
}
1✔
841
END_TEST
1✔
842

843
START_TEST (auth_endgrent_test) {
844
  int res;
1✔
845
  authtable authtab;
1✔
846
  char *sym_name = "endgrent";
1✔
847

1✔
848
  pr_auth_endgrent(p);
849
  ck_assert_msg(endgrent_count == 0, "Expected call count 0, got %u",
1✔
850
    endgrent_count);
1✔
851
  mark_point();
852

1✔
853
  /* Load the appropriate AUTH symbol, and call it. */
854

855
  memset(&authtab, 0, sizeof(authtab));
856
  authtab.name = sym_name;
1✔
857
  authtab.handler = handle_endgrent;
1✔
858
  authtab.m = &testsuite_module;
1✔
859
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
860
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
861
    strerror(errno));
1✔
862

863
  pr_auth_endgrent(p);
864
  ck_assert_msg(endgrent_count == 1, "Expected call count 1, got %u",
1✔
865
    endgrent_count);
1✔
866

867
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
868
}
1✔
869
END_TEST
1✔
870

871
START_TEST (auth_getgrent_test) {
872
  int res;
1✔
873
  struct group *gr;
1✔
874
  authtable authtab;
1✔
875
  char *sym_name = "getgrent";
1✔
876

1✔
877
  gr = pr_auth_getgrent(NULL);
878
  ck_assert_msg(gr == NULL, "Found grent unexpectedly");
1✔
879
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
880
    errno, strerror(errno));
1✔
881

882
  gr = pr_auth_getgrent(p);
883
  ck_assert_msg(gr == NULL, "Found grent unexpectedly");
1✔
884
  ck_assert_msg(getgrent_count == 0, "Expected call count 0, got %u",
1✔
885
    getgrent_count);
1✔
886
  mark_point();
887

1✔
888
  /* Load the appropriate AUTH symbol, and call it. */
889

890
  memset(&authtab, 0, sizeof(authtab));
891
  authtab.name = sym_name;
1✔
892
  authtab.handler = handle_getgrent;
1✔
893
  authtab.m = &testsuite_module;
1✔
894
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
895
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
896
    strerror(errno));
1✔
897

898
  gr = pr_auth_getgrent(p);
899
  ck_assert_msg(gr != NULL, "Failed to find grent: %s", strerror(errno));
1✔
900
  ck_assert_msg(getgrent_count == 1, "Expected call count 1, got %u",
1✔
901
    getgrent_count);
1✔
902

903
  gr = pr_auth_getgrent(p);
904
  ck_assert_msg(gr == NULL, "Failed to avoid grent with bad GID");
1✔
905
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
906
    strerror(errno), errno);
1✔
907
  ck_assert_msg(getgrent_count == 2, "Expected call count 2, got %u",
908
    getgrent_count);
1✔
909

910
  pr_auth_endgrent(p);
911
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1✔
912
}
1✔
913
END_TEST
1✔
914

915
START_TEST (auth_getgrnam_test) {
916
  int res;
1✔
917
  struct group *gr;
1✔
918
  authtable authtab;
1✔
919
  char *sym_name = "getgrnam";
1✔
920

1✔
921
  gr = pr_auth_getgrnam(NULL, NULL);
922
  ck_assert_msg(gr == NULL, "Found grnam unexpectedly");
1✔
923
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
924
    errno, strerror(errno));
1✔
925

926
  gr = pr_auth_getgrnam(p, PR_TEST_AUTH_NAME);
927
  ck_assert_msg(gr == NULL, "Found grnam unexpectedly");
1✔
928
  ck_assert_msg(getgrnam_count == 0, "Expected call count 0, got %u",
1✔
929
    getgrnam_count);
1✔
930
  mark_point();
931

1✔
932
  /* Load the appropriate AUTH symbol, and call it. */
933

934
  memset(&authtab, 0, sizeof(authtab));
935
  authtab.name = sym_name;
1✔
936
  authtab.handler = handle_getgrnam;
1✔
937
  authtab.m = &testsuite_module;
1✔
938
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
939
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
940
    strerror(errno));
1✔
941

942
  mark_point();
943

1✔
944
  gr = pr_auth_getgrnam(p, PR_TEST_AUTH_NOGROUP);
945
  ck_assert_msg(gr == NULL, "Found group '%s' unexpectedly",
1✔
946
    PR_TEST_AUTH_NOGROUP);
1✔
947
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
948
    strerror(errno), errno);
1✔
949

950
  gr = pr_auth_getgrnam(p, PR_TEST_AUTH_NAME);
951
  ck_assert_msg(gr != NULL, "Failed to find grnam: %s", strerror(errno));
1✔
952
  ck_assert_msg(getgrnam_count == 2, "Expected call count 2, got %u",
1✔
953
    getgrnam_count);
1✔
954

955
  mark_point();
956

1✔
957
  gr = pr_auth_getgrnam(p, "other");
958
  ck_assert_msg(gr == NULL, "Found grnam for user 'other' unexpectedly");
1✔
959
  ck_assert_msg(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
1✔
960
    errno, strerror(errno));
1✔
961
  ck_assert_msg(getgrnam_count == 3, "Expected call count 3, got %u",
962
    getgrnam_count);
1✔
963

964
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
965
}
1✔
966
END_TEST
1✔
967

968
START_TEST (auth_getgrgid_test) {
969
  int res;
1✔
970
  struct group *gr;
1✔
971
  authtable authtab;
1✔
972
  char *sym_name = "getgrgid";
1✔
973

1✔
974
  gr = pr_auth_getgrgid(NULL, -1);
975
  ck_assert_msg(gr == NULL, "Found grgid unexpectedly");
1✔
976
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
977
    errno, strerror(errno));
1✔
978

979
  gr = pr_auth_getgrgid(p, PR_TEST_AUTH_GID);
980
  ck_assert_msg(gr == NULL, "Found grgid unexpectedly");
1✔
981
  ck_assert_msg(getgrgid_count == 0, "Expected call count 0, got %u",
1✔
982
    getgrgid_count);
1✔
983
  mark_point();
984

1✔
985
  /* Load the appropriate AUTH symbol, and call it. */
986

987
  memset(&authtab, 0, sizeof(authtab));
988
  authtab.name = sym_name;
1✔
989
  authtab.handler = handle_getgrgid;
1✔
990
  authtab.m = &testsuite_module;
1✔
991
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
992
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
993
    strerror(errno));
1✔
994

995
  mark_point();
996

1✔
997
  gr = pr_auth_getgrgid(p, PR_TEST_AUTH_GID);
998
  ck_assert_msg(gr != NULL, "Failed to find grgid: %s", strerror(errno));
1✔
999
  ck_assert_msg(getgrgid_count == 1, "Expected call count 1, got %u",
1✔
1000
    getgrgid_count);
1✔
1001

1002
  gr = pr_auth_getgrgid(p, PR_TEST_AUTH_NOGID);
1003
  ck_assert_msg(gr == NULL, "Found grgid for NOGID unexpectedly");
1✔
1004
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
1005
    strerror(errno), errno);
1✔
1006

1007
  mark_point();
1008

1✔
1009
  gr = pr_auth_getgrgid(p, 5);
1010
  ck_assert_msg(gr == NULL, "Found grgid for GID 5 unexpectedly");
1✔
1011
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
1012
    strerror(errno), errno);
1✔
1013

1014
  ck_assert_msg(getgrgid_count == 3, "Expected call count 3, got %u",
1015
    getgrgid_count);
1✔
1016

1017
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1018
}
1✔
1019
END_TEST
1✔
1020

1021
START_TEST (auth_name2gid_test) {
1022
  int res;
1✔
1023
  gid_t gid;
1✔
1024
  authtable authtab;
1✔
1025
  char *sym_name = "name2gid";
1✔
1026

1✔
1027
  pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_NAME2GID);
1028

1✔
1029
  gid = pr_auth_name2gid(NULL, NULL);
1030
  ck_assert_msg(gid == (gid_t) -1, "Found GID unexpectedly");
1✔
1031
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
1032
    errno, strerror(errno));
1✔
1033

1034
  gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1035
  ck_assert_msg(gid == (gid_t) -1, "Found GID unexpectedly");
1✔
1036
  ck_assert_msg(name2gid_count == 0, "Expected call count 0, got %u",
1✔
1037
    name2gid_count);
1✔
1038
  mark_point();
1039

1✔
1040
  /* Load the appropriate AUTH symbol, and call it. */
1041

1042
  memset(&authtab, 0, sizeof(authtab));
1043
  authtab.name = sym_name;
1✔
1044
  authtab.handler = handle_name2gid;
1✔
1045
  authtab.m = &testsuite_module;
1✔
1046
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1047
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1048
    strerror(errno));
1✔
1049

1050
  mark_point();
1051

1✔
1052
  gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1053
  ck_assert_msg(gid == PR_TEST_AUTH_GID, "Expected GID %lu, got %lu",
1✔
1054
    (unsigned long) PR_TEST_AUTH_GID, (unsigned long) gid);
1✔
1055
  ck_assert_msg(name2gid_count == 1, "Expected call count 1, got %u",
1056
    name2gid_count);
1✔
1057

1058
  mark_point();
1059

1✔
1060
  /* Call again; the call counter should NOT increment due to caching. */
1061

1062
  gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1063
  ck_assert_msg(gid == PR_TEST_AUTH_GID, "Expected GID %lu, got %lu",
1✔
1064
    (unsigned long) PR_TEST_AUTH_GID, (unsigned long) gid);
1✔
1065
  ck_assert_msg(name2gid_count == 1, "Expected call count 1, got %u",
1066
    name2gid_count);
1✔
1067

1068
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1069
}
1✔
1070
END_TEST
1✔
1071

1072
START_TEST (auth_gid2name_test) {
1073
  int res;
1✔
1074
  const char *name;
1✔
1075
  authtable authtab;
1✔
1076
  char *sym_name = "gid2name";
1✔
1077

1✔
1078
  pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_GID2NAME);
1079

1✔
1080
  name = pr_auth_gid2name(NULL, -1);
1081
  ck_assert_msg(name == NULL, "Found name unexpectedly: %s", name);
1✔
1082
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
1083
    errno, strerror(errno));
1✔
1084
  mark_point();
1085

1✔
1086
  name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1087
  ck_assert_msg(name != NULL, "Failed to find name for GID %lu: %s",
1✔
1088
    (unsigned long) PR_TEST_AUTH_GID, strerror(errno));
1✔
1089
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_GID_STR) == 0,
1090
     "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name);
1✔
1091
  ck_assert_msg(gid2name_count == 0, "Expected call count 0, got %u",
1092
    gid2name_count);
1✔
1093
  mark_point();
1094

1✔
1095
  /* Load the appropriate AUTH symbol, and call it. */
1096

1097
  memset(&authtab, 0, sizeof(authtab));
1098
  authtab.name = sym_name;
1✔
1099
  authtab.handler = handle_gid2name;
1✔
1100
  authtab.m = &testsuite_module;
1✔
1101
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1102
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1103
    strerror(errno));
1✔
1104

1105
  mark_point();
1106

1✔
1107
  name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1108
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1109
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1✔
1110
    "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1✔
1111
  ck_assert_msg(gid2name_count == 1, "Expected call count 1, got %u",
1112
    gid2name_count);
1✔
1113

1114
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1115
}
1✔
1116
END_TEST
1✔
1117

1118
START_TEST (auth_getgroups_test) {
1119
  int res;
1✔
1120
  array_header *gids = NULL, *names = NULL;
1✔
1121
  authtable authtab;
1✔
1122
  char *sym_name = "getgroups";
1✔
1123

1✔
1124
  res = pr_auth_getgroups(NULL, NULL, NULL, NULL);
1125
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
1126
  ck_assert_msg(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1✔
1127
    errno, strerror(errno));
1✔
1128

1129
  res = pr_auth_getgroups(p, PR_TEST_AUTH_NAME, &gids, NULL);
1130
  ck_assert_msg(res < 0, "Found groups for '%s' unexpectedly", PR_TEST_AUTH_NAME);
1✔
1131
  ck_assert_msg(getgroups_count == 0, "Expected call count 0, got %u",
1✔
1132
    getgroups_count);
1✔
1133
  mark_point();
1134

1✔
1135
  /* Load the appropriate AUTH symbol, and call it. */
1136

1137
  memset(&authtab, 0, sizeof(authtab));
1138
  authtab.name = sym_name;
1✔
1139
  authtab.handler = handle_getgroups;
1✔
1140
  authtab.m = &testsuite_module;
1✔
1141
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1142
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1143
    strerror(errno));
1✔
1144

1145
  mark_point();
1146

1✔
1147
  res = pr_auth_getgroups(p, PR_TEST_AUTH_NAME, &gids, &names);
1148
  ck_assert_msg(res > 0, "Expected group count 1 for '%s', got %d: %s",
1✔
1149
    PR_TEST_AUTH_NAME, res, strerror(errno));
1✔
1150
  ck_assert_msg(getgroups_count == 1, "Expected call count 1, got %u",
1151
    getgroups_count);
1✔
1152

1153
  res = pr_auth_getgroups(p, "other", &gids, &names);
1154
  ck_assert_msg(res < 0, "Found groups for 'other' unexpectedly");
1✔
1155
  ck_assert_msg(getgroups_count == 2, "Expected call count 2, got %u",
1✔
1156
    getgroups_count);
1✔
1157

1158
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1159
}
1✔
1160
END_TEST
1✔
1161

1162
START_TEST (auth_cache_uid2name_test) {
1163
  int res;
1✔
1164
  const char *name;
1✔
1165
  authtable authtab;
1✔
1166
  char *sym_name = "uid2name";
1✔
1167

1✔
1168
  /* Load the appropriate AUTH symbol, and call it. */
1169

1170
  memset(&authtab, 0, sizeof(authtab));
1171
  authtab.name = sym_name;
1✔
1172
  authtab.handler = handle_uid2name;
1✔
1173
  authtab.m = &testsuite_module;
1✔
1174
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1175
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1176
    strerror(errno));
1✔
1177

1178
  mark_point();
1179

1✔
1180
  name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1181
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1182
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1✔
1183
    "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1✔
1184
  ck_assert_msg(uid2name_count == 1, "Expected call count 1, got %u",
1185
    uid2name_count);
1✔
1186

1187
  /* Call again; the call counter should NOT increment due to caching. */
1188

1189
  name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1190
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1191
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1✔
1192
    "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1✔
1193
  ck_assert_msg(uid2name_count == 1, "Expected call count 1, got %u",
1194
    uid2name_count);
1✔
1195

1196
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1197
}
1✔
1198
END_TEST
1✔
1199

1200
START_TEST (auth_cache_gid2name_test) {
1201
  int res;
1✔
1202
  const char *name;
1✔
1203
  authtable authtab;
1✔
1204
  char *sym_name = "gid2name";
1✔
1205

1✔
1206
  /* Load the appropriate AUTH symbol, and call it. */
1207

1208
  memset(&authtab, 0, sizeof(authtab));
1209
  authtab.name = sym_name;
1✔
1210
  authtab.handler = handle_gid2name;
1✔
1211
  authtab.m = &testsuite_module;
1✔
1212
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1213
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1214
    strerror(errno));
1✔
1215

1216
  mark_point();
1217

1✔
1218
  name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1219
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1220
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1✔
1221
    "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1✔
1222
  ck_assert_msg(gid2name_count == 1, "Expected call count 1, got %u",
1223
    gid2name_count);
1✔
1224

1225
  /* Call again; the call counter should NOT increment due to caching. */
1226

1227
  name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1228
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1229
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1✔
1230
    "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1✔
1231
  ck_assert_msg(gid2name_count == 1, "Expected call count 1, got %u",
1232
    gid2name_count);
1✔
1233

1234
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1235
}
1✔
1236
END_TEST
1✔
1237

1238
START_TEST (auth_cache_uid2name_failed_test) {
1239
  int res;
1✔
1240
  const char *name;
1✔
1241
  authtable authtab;
1✔
1242
  char *sym_name = "uid2name";
1✔
1243

1✔
1244
  /* Load the appropriate AUTH symbol, and call it. */
1245

1246
  memset(&authtab, 0, sizeof(authtab));
1247
  authtab.name = sym_name;
1✔
1248
  authtab.handler = decline_uid2name;
1✔
1249
  authtab.m = &testsuite_module;
1✔
1250
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1251
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1252
    strerror(errno));
1✔
1253

1254
  mark_point();
1255

1✔
1256
  name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1257
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1258
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_UID_STR) == 0,
1✔
1259
    "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name);
1✔
1260
  ck_assert_msg(uid2name_count == 1, "Expected call count 1, got %u",
1261
    uid2name_count);
1✔
1262

1263
  /* Call again; the call counter should NOT increment due to caching. */
1264

1265
  name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1266
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1267
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_UID_STR) == 0,
1✔
1268
    "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name);
1✔
1269
  ck_assert_msg(uid2name_count == 1, "Expected call count 1, got %u",
1270
    uid2name_count);
1✔
1271

1272
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1273
}
1✔
1274
END_TEST
1✔
1275

1276
START_TEST (auth_cache_gid2name_failed_test) {
1277
  int res;
1✔
1278
  const char *name;
1✔
1279
  authtable authtab;
1✔
1280
  char *sym_name = "gid2name";
1✔
1281

1✔
1282
  /* Load the appropriate AUTH symbol, and call it. */
1283

1284
  memset(&authtab, 0, sizeof(authtab));
1285
  authtab.name = sym_name;
1✔
1286
  authtab.handler = decline_gid2name;
1✔
1287
  authtab.m = &testsuite_module;
1✔
1288
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1289
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1290
    strerror(errno));
1✔
1291

1292
  mark_point();
1293

1✔
1294
  name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1295
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1296
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_GID_STR) == 0,
1✔
1297
    "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name);
1✔
1298
  ck_assert_msg(gid2name_count == 1, "Expected call count 1, got %u",
1299
    gid2name_count);
1✔
1300

1301
  /* Call again; the call counter should NOT increment due to caching. */
1302

1303
  name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1304
  ck_assert_msg(name != NULL, "Expected name, got null");
1✔
1305
  ck_assert_msg(strcmp(name, PR_TEST_AUTH_GID_STR) == 0,
1✔
1306
    "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name);
1✔
1307
  ck_assert_msg(gid2name_count == 1, "Expected call count 1, got %u",
1308
    gid2name_count);
1✔
1309

1310
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1311
}
1✔
1312
END_TEST
1✔
1313

1314
START_TEST (auth_cache_name2uid_failed_test) {
1315
  int res;
1✔
1316
  uid_t uid;
1✔
1317
  authtable authtab;
1✔
1318
  char *sym_name = "name2uid";
1✔
1319

1✔
1320
  /* Load the appropriate AUTH symbol, and call it. */
1321

1322
  memset(&authtab, 0, sizeof(authtab));
1323
  authtab.name = sym_name;
1✔
1324
  authtab.handler = decline_name2uid;
1✔
1325
  authtab.m = &testsuite_module;
1✔
1326
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1327
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1328
    strerror(errno));
1✔
1329

1330
  mark_point();
1331

1✔
1332
  uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
1333
  ck_assert_msg(uid == (uid_t) -1, "Expected -1, got %lu", (unsigned long) uid);
1✔
1334
  ck_assert_msg(name2uid_count == 1, "Expected call count 1, got %u",
1✔
1335
    name2uid_count);
1✔
1336

1337
  /* Call again; the call counter should NOT increment due to caching. */
1338

1339
  uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
1340
  ck_assert_msg(uid == (uid_t) -1, "Expected -1, got %lu", (unsigned long) uid);
1✔
1341
  ck_assert_msg(name2uid_count == 1, "Expected call count 1, got %u",
1✔
1342
    name2uid_count);
1✔
1343

1344
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1345
}
1✔
1346
END_TEST
1✔
1347

1348
START_TEST (auth_cache_name2gid_failed_test) {
1349
  int res;
1✔
1350
  gid_t gid;
1✔
1351
  authtable authtab;
1✔
1352
  char *sym_name = "name2gid";
1✔
1353

1✔
1354
  /* Load the appropriate AUTH symbol, and call it. */
1355

1356
  memset(&authtab, 0, sizeof(authtab));
1357
  authtab.name = sym_name;
1✔
1358
  authtab.handler = decline_name2gid;
1✔
1359
  authtab.m = &testsuite_module;
1✔
1360
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1361
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1362
    strerror(errno));
1✔
1363

1364
  mark_point();
1365

1✔
1366
  gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1367
  ck_assert_msg(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid);
1✔
1368
  ck_assert_msg(name2gid_count == 1, "Expected call count 1, got %u",
1✔
1369
    name2gid_count);
1✔
1370

1371
  /* Call again; the call counter should NOT increment due to caching. */
1372

1373
  gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1374
  ck_assert_msg(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid);
1✔
1375
  ck_assert_msg(name2gid_count == 1, "Expected call count 1, got %u",
1✔
1376
    name2gid_count);
1✔
1377

1378
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1379
}
1✔
1380
END_TEST
1✔
1381

1382
START_TEST (auth_cache_clear_test) {
1383
  int res;
1✔
1384
  gid_t gid;
1✔
1385
  authtable authtab;
1✔
1386
  char *sym_name = "name2gid";
1✔
1387

1✔
1388
  mark_point();
1389
  pr_auth_cache_clear();
1✔
1390

1✔
1391
  /* Load the appropriate AUTH symbol, and call it. */
1392

1393
  memset(&authtab, 0, sizeof(authtab));
1394
  authtab.name = sym_name;
1✔
1395
  authtab.handler = decline_name2gid;
1✔
1396
  authtab.m = &testsuite_module;
1✔
1397
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1398
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1399
    strerror(errno));
1✔
1400

1401
  mark_point();
1402
  gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1✔
1403
  ck_assert_msg(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid);
1✔
1404
  ck_assert_msg(name2gid_count == 1, "Expected call count 1, got %u",
1✔
1405
    name2gid_count);
1✔
1406

1407
  mark_point();
1408
  pr_auth_cache_clear();
1✔
1409
}
1✔
1410
END_TEST
1✔
1411

1412
START_TEST (auth_cache_set_test) {
1413
  int res;
1✔
1414
  unsigned int flags = PR_AUTH_CACHE_FL_UID2NAME|PR_AUTH_CACHE_FL_GID2NAME|PR_AUTH_CACHE_FL_AUTH_MODULE|PR_AUTH_CACHE_FL_NAME2UID|PR_AUTH_CACHE_FL_NAME2GID|PR_AUTH_CACHE_FL_BAD_UID2NAME|PR_AUTH_CACHE_FL_BAD_GID2NAME|PR_AUTH_CACHE_FL_BAD_NAME2UID|PR_AUTH_CACHE_FL_BAD_NAME2GID;
1✔
1415

1✔
1416
  res = pr_auth_cache_set(-1, 0);
1417
  ck_assert_msg(res < 0, "Failed to handle invalid setting");
1✔
1418
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1419
    strerror(errno), errno);
1✔
1420

1421
  res = pr_auth_cache_set(TRUE, flags);
1422
  ck_assert_msg(res == 0, "Failed to enable all auth cache settings: %s",
1✔
1423
    strerror(errno));
1✔
1424

1425
  res = pr_auth_cache_set(FALSE, flags);
1426
  ck_assert_msg(res == 0, "Failed to disable all auth cache settings: %s",
1✔
1427
    strerror(errno));
1✔
1428

1429
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_DEFAULT);
1430
}
1✔
1431
END_TEST
1✔
1432

1433
START_TEST (auth_clear_auth_only_module_test) {
1434
  int res;
1✔
1435

1✔
1436
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1437

1✔
1438
  res = pr_auth_clear_auth_only_modules();
1439
  ck_assert_msg(res < 0, "Failed to handle no auth module list");
1✔
1440
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1441
    strerror(errno), errno);
1✔
1442
}
1443
END_TEST
1✔
1444

1445
START_TEST (auth_add_auth_only_module_test) {
1446
  int res;
1✔
1447
  const char *name = "foo.bar";
1✔
1448

1✔
1449
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1450

1✔
1451
  res = pr_auth_add_auth_only_module(NULL);
1452
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
1453
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1454
    strerror(errno), errno);
1✔
1455

1456
  res = pr_auth_add_auth_only_module(name);
1457
  ck_assert_msg(res == 0, "Failed to add auth-only module '%s': %s", name,
1✔
1458
    strerror(errno));
1✔
1459

1460
  res = pr_auth_add_auth_only_module(name);
1461
  ck_assert_msg(res < 0, "Failed to handle duplicate auth-only module");
1✔
1462
  ck_assert_msg(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1✔
1463
    strerror(errno), errno);
1✔
1464

1465
  res = pr_auth_clear_auth_only_modules();
1466
  ck_assert_msg(res == 0, "Failed to clear auth-only modules: %s",
1✔
1467
    strerror(errno));
1✔
1468
}
1469
END_TEST
1✔
1470

1471
START_TEST (auth_remove_auth_only_module_test) {
1472
  int res;
1✔
1473
  const char *name = "foo.bar";
1✔
1474

1✔
1475
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1476

1✔
1477
  res = pr_auth_remove_auth_only_module(NULL);
1478
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
1479
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1480
    strerror(errno), errno);
1✔
1481

1482
  res = pr_auth_remove_auth_only_module(name);
1483
  ck_assert_msg(res < 0, "Failed to handle empty auth-only module list");
1✔
1484
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
1485
    strerror(errno), errno);
1✔
1486

1487
  res = pr_auth_add_auth_only_module(name);
1488
  ck_assert_msg(res == 0, "Failed to add auth-only module '%s': %s", name,
1✔
1489
    strerror(errno));
1✔
1490

1491
  res = pr_auth_remove_auth_only_module(name);
1492
  ck_assert_msg(res == 0, "Failed to remove auth-only module '%s': %s", name,
1✔
1493
    strerror(errno));
1✔
1494

1495
  (void) pr_auth_clear_auth_only_modules();
1496
}
1✔
1497
END_TEST
1✔
1498

1499
START_TEST (auth_authenticate_test) {
1500
  int res;
1✔
1501
  authtable authtab;
1✔
1502
  char *sym_name = "auth";
1✔
1503

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

1509
  res = pr_auth_authenticate(p, NULL, NULL);
1510
  ck_assert_msg(res < 0, "Failed to handle null name");
1✔
1511
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1512
    strerror(errno), errno);
1✔
1513

1514
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, NULL);
1515
  ck_assert_msg(res < 0, "Failed to handle null password");
1✔
1516
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1517
    strerror(errno), errno);
1✔
1518

1519
  /* Load the appropriate AUTH symbol, and call it. */
1520

1521
  memset(&authtab, 0, sizeof(authtab));
1522
  authtab.name = sym_name;
1✔
1523
  authtab.handler = handle_authn;
1✔
1524
  authtab.m = &testsuite_module;
1✔
1525
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1526
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1527
    strerror(errno));
1✔
1528

1529
  res = pr_auth_authenticate(p, "other", "foobar");
1530
  ck_assert_msg(res == PR_AUTH_NOPWD,
1✔
1531
    "Authenticated user 'other' unexpectedly (expected %d, got %d)",
1✔
1532
    PR_AUTH_NOPWD, res);
1533

1534
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, "foobar");
1535
  ck_assert_msg(res == PR_AUTH_BADPWD,
1✔
1536
    "Authenticated user '%s' unexpectedly (expected %d, got %d)",
1✔
1537
    PR_TEST_AUTH_NAME, PR_AUTH_BADPWD, res);
1538

1539
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1540
  ck_assert_msg(res == PR_AUTH_OK,
1✔
1541
    "Failed to authenticate user '%s' (expected %d, got %d)",
1✔
1542
    PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1543

1544
  authtab.auth_flags |= PR_AUTH_FL_REQUIRED;
1545
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1✔
1546
  ck_assert_msg(res == PR_AUTH_OK,
1✔
1547
    "Failed to authenticate user '%s' (expected %d, got %d)",
1✔
1548
    PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1549
  authtab.auth_flags &= ~PR_AUTH_FL_REQUIRED;
1550

1✔
1551
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1552

1✔
1553
  res = pr_auth_add_auth_only_module("foo.bar");
1554
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1555

1✔
1556
  res = pr_auth_add_auth_only_module("mod_testsuite.c");
1557
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1558

1✔
1559
  res = pr_module_load(&testsuite_module);
1560
  ck_assert_msg(res == 0, "Failed to load module: %s", strerror(errno));
1✔
1561

1✔
1562
  res = pr_auth_authenticate(p, "foo", "bar");
1563
  ck_assert_msg(res == PR_AUTH_NOPWD,
1✔
1564
    "Failed to handle unknown user 'foo' (expected %d, got %d)", PR_AUTH_NOPWD,
1✔
1565
    res);
1566

1567
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, "bar");
1568
  ck_assert_msg(res == PR_AUTH_BADPWD,
1✔
1569
    "Failed to handle user '%s' with bad password (expected %d, got %d)",
1✔
1570
    PR_TEST_AUTH_NAME, PR_AUTH_BADPWD, res);
1571

1572
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1573
  ck_assert_msg(res == PR_AUTH_OK,
1✔
1574
    "Failed to authenticate user '%s' (expected %d, got %d)",
1✔
1575
    PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1576

1577
  authn_rfc2228 = TRUE;
1578
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1✔
1579
  ck_assert_msg(res == PR_AUTH_RFC2228_OK,
1✔
1580
    "Failed to authenticate user '%s' (expected %d, got %d)",
1✔
1581
    PR_TEST_AUTH_NAME, PR_AUTH_RFC2228_OK, res);
1582

1583
  pr_auth_clear_auth_only_modules();
1584
  pr_module_unload(&testsuite_module);
1✔
1585

1✔
1586
  authn_rfc2228 = TRUE;
1587
  res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1✔
1588
  ck_assert_msg(res == PR_AUTH_RFC2228_OK,
1✔
1589
    "Failed to authenticate user '%s' (expected %d, got %d)",
1✔
1590
    PR_TEST_AUTH_NAME, PR_AUTH_RFC2228_OK, res);
1591

1592
  authn_rfc2228 = FALSE;
1593
}
1✔
1594
END_TEST
1✔
1595

1596
START_TEST (auth_authorize_test) {
1597
  int res;
1✔
1598
  authtable authtab;
1✔
1599
  char *sym_name = "authorize";
1✔
1600

1✔
1601
  res = pr_auth_authorize(NULL, NULL);
1602
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
1603
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1604
    strerror(errno), errno);
1✔
1605

1606
  res = pr_auth_authorize(p, NULL);
1607
  ck_assert_msg(res < 0, "Failed to handle null name");
1✔
1608
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1609
    strerror(errno), errno);
1✔
1610

1611
  res = pr_auth_authorize(p, PR_TEST_AUTH_NAME);
1612
  ck_assert_msg(res > 0, "Failed to handle missing handler");
1✔
1613

1✔
1614
  /* Load the appropriate AUTH symbol, and call it. */
1615

1616
  memset(&authtab, 0, sizeof(authtab));
1617
  authtab.name = sym_name;
1✔
1618
  authtab.handler = handle_authz;
1✔
1619
  authtab.m = &testsuite_module;
1✔
1620
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1621
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1622
    strerror(errno));
1✔
1623

1624
  res = pr_auth_authorize(p, "other");
1625
  ck_assert_msg(res == PR_AUTH_NOPWD,
1✔
1626
    "Authorized user 'other' unexpectedly (expected %d, got %d)",
1✔
1627
    PR_AUTH_NOPWD, res);
1628

1629
  res = pr_auth_authorize(p, PR_TEST_AUTH_NAME);
1630
  ck_assert_msg(res == PR_AUTH_OK,
1✔
1631
    "Failed to authorize user '%s' (expected %d, got %d)",
1✔
1632
    PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1633

1634
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1635

1✔
1636
  res = pr_auth_add_auth_only_module("foo.bar");
1637
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1638

1✔
1639
  res = pr_auth_add_auth_only_module(testsuite_module.name);
1640
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1641

1✔
1642
  res = pr_auth_authorize(p, PR_TEST_AUTH_NAME);
1643
  ck_assert_msg(res == PR_AUTH_OK,
1✔
1644
    "Failed to authorize user '%s' (expected %d, got %d)",
1✔
1645
    PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1646

1647
  (void) pr_auth_clear_auth_only_modules();
1648
}
1✔
1649
END_TEST
1✔
1650

1651
static int test_check_errorcode = PR_AUTH_BADPWD;
1652

1653
MODRET handle_check_error(cmd_rec *cmd) {
1654
  return PR_ERROR_INT(cmd, test_check_errorcode);
13✔
1655
}
13✔
1656

1657
START_TEST (auth_check_errors_test) {
1658
  register unsigned int i;
1✔
1659
  int res;
1✔
1660
  const char *cleartext_passwd, *name;
1✔
1661
  authtable authtab;
1✔
1662
  char *sym_name = "check";
1✔
1663
  int test_errorcodes[] = {
1✔
1664
    PR_AUTH_ERROR,
1✔
1665
    PR_AUTH_NOPWD,
1666
    PR_AUTH_BADPWD,
1667
    PR_AUTH_AGEPWD,
1668
    PR_AUTH_DISABLEDPWD,
1669
    PR_AUTH_CRED_INSUFFICIENT,
1670
    PR_AUTH_CRED_UNAVAIL,
1671
    PR_AUTH_CRED_ERROR,
1672
    PR_AUTH_INFO_UNAVAIL,
1673
    PR_AUTH_MAX_ATTEMPTS_EXCEEDED,
1674
    PR_AUTH_INIT_ERROR,
1675
    PR_AUTH_NEW_TOKEN_REQUIRED,
1676
    0
1677
  };
1678

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

1685
  mark_point();
1686
  res = pr_auth_check(p, NULL, NULL, NULL);
1✔
1687
  ck_assert_msg(res < 0, "Failed to handle null name");
1✔
1688
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1689
    strerror(errno), errno);
1✔
1690

1691
  mark_point();
1692
  name = PR_TEST_AUTH_NAME;
1✔
1693
  res = pr_auth_check(p, NULL, name, NULL);
1✔
1694
  ck_assert_msg(res < 0, "Failed to handle null cleartext password");
1✔
1695
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1696
    strerror(errno), errno);
1✔
1697

1698
  mark_point();
1699
  cleartext_passwd = PR_TEST_AUTH_PASSWD;
1✔
1700
  res = pr_auth_check(p, NULL, name, cleartext_passwd);
1✔
1701
  ck_assert_msg(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1✔
1702
    res);
1✔
1703

1704
  res = pr_module_load(&testsuite_module);
1705
  ck_assert_msg(res == 0, "Failed to load module: %s", strerror(errno));
1✔
1706

1✔
1707
  memset(&authtab, 0, sizeof(authtab));
1708
  authtab.name = sym_name;
1✔
1709
  authtab.handler = handle_check_error;
1✔
1710
  authtab.m = &testsuite_module;
1✔
1711
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1712
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1713
    strerror(errno));
1✔
1714

1715
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1716
  res = pr_auth_add_auth_only_module("mod_testsuite.c");
1✔
1717
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1718

1✔
1719
  for (i = 0; test_errorcodes[i] != 0; i++) {
1720
    mark_point();
14✔
1721
    test_check_errorcode = test_errorcodes[i];
12✔
1722
    res = pr_auth_check(p, "", name, cleartext_passwd);
12✔
1723
    ck_assert_msg(res == test_check_errorcode, "Expected %d, got %d",
12✔
1724
      test_check_errorcode, res);
12✔
1725
  }
1726

1727
  mark_point();
1728
  test_check_errorcode = PR_AUTH_OK_NO_PASS;
1✔
1729
  res = pr_auth_check(p, "", name, cleartext_passwd);
1✔
1730
  ck_assert_msg(res == test_check_errorcode, "Expected %d, got %d",
1✔
1731
    test_check_errorcode, res);
1✔
1732

1733
  res = pr_module_unload(&testsuite_module);
1734
  ck_assert_msg(res == 0, "Failed to unload module: %s", strerror(errno));
1✔
1735
  (void) pr_auth_clear_auth_only_modules();
1✔
1736
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1✔
1737
}
1✔
1738
END_TEST
1✔
1739

1740
START_TEST (auth_check_valid_test) {
1741
  int res;
1✔
1742
  const char *cleartext_passwd, *ciphertext_passwd, *name;
1✔
1743
  authtable authtab;
1✔
1744
  char *sym_name = "check";
1✔
1745

1✔
1746
  /* Load the appropriate AUTH symbol, and call it. */
1747

1748
  memset(&authtab, 0, sizeof(authtab));
1749
  authtab.name = sym_name;
1✔
1750
  authtab.handler = handle_check;
1✔
1751
  authtab.m = &testsuite_module;
1✔
1752
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1753
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1754
    strerror(errno));
1✔
1755

1756
  mark_point();
1757
  cleartext_passwd = PR_TEST_AUTH_PASSWD;
1✔
1758
  res = pr_auth_check(p, NULL, "other", cleartext_passwd);
1✔
1759
  ck_assert_msg(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1✔
1760
    res);
1✔
1761

1762
  mark_point();
1763
  name = PR_TEST_AUTH_NAME;
1✔
1764
  res = pr_auth_check(p, "foo", name, cleartext_passwd);
1✔
1765
  ck_assert_msg(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1✔
1766
    res);
1✔
1767

1768
  mark_point();
1769
  res = pr_auth_check(p, NULL, name, cleartext_passwd);
1✔
1770
  ck_assert_msg(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1✔
1771
    res);
1✔
1772

1773
  mark_point();
1774
  ciphertext_passwd = PR_TEST_AUTH_PASSWD;
1✔
1775
  res = pr_auth_check(p, ciphertext_passwd, name, cleartext_passwd);
1✔
1776
  ck_assert_msg(res == PR_AUTH_OK, "Expected %d, got %d", PR_AUTH_OK, res);
1✔
1777

1✔
1778
  (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1779

1✔
1780
  res = pr_auth_add_auth_only_module("foo.bar");
1781
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1782

1✔
1783
  res = pr_auth_add_auth_only_module("mod_testsuite.c");
1784
  ck_assert_msg(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1✔
1785

1✔
1786
  mark_point();
1787
  check_rfc2228 = TRUE;
1✔
1788
  res = pr_auth_check(p, ciphertext_passwd, name, cleartext_passwd);
1✔
1789
  ck_assert_msg(res == PR_AUTH_RFC2228_OK,
1✔
1790
    "Failed to check user '%s' (expected %d, got %d)", name,
1✔
1791
    PR_AUTH_RFC2228_OK, res);
1792

1793
  (void) pr_auth_clear_auth_only_modules();
1794
  pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1✔
1795
}
1✔
1796
END_TEST
1✔
1797

1798
START_TEST (auth_requires_pass_test) {
1799
  int res;
1✔
1800
  const char *name;
1✔
1801
  authtable authtab;
1✔
1802
  char *sym_name = "requires_pass";
1✔
1803

1✔
1804
  res = pr_auth_requires_pass(NULL, NULL);
1805
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
1806
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1807
    strerror(errno), errno);
1✔
1808

1809
  res = pr_auth_requires_pass(p, NULL);
1810
  ck_assert_msg(res < 0, "Failed to handle null name");
1✔
1811
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1812
    strerror(errno), errno);
1✔
1813

1814
  name = "other";
1815
  res = pr_auth_requires_pass(p, name);
1✔
1816
  ck_assert_msg(res == TRUE, "Unknown users should require passwords (got %d)",
1✔
1817
    res);
1✔
1818

1819
  /* Load the appropriate AUTH symbol, and call it. */
1820

1821
  memset(&authtab, 0, sizeof(authtab));
1822
  authtab.name = sym_name;
1✔
1823
  authtab.handler = handle_requires_pass;
1✔
1824
  authtab.m = &testsuite_module;
1✔
1825
  res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1✔
1826
  ck_assert_msg(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1✔
1827
    strerror(errno));
1✔
1828

1829
  res = pr_auth_requires_pass(p, name);
1830
  ck_assert_msg(res == TRUE, "Unknown users should require passwords (got %d)",
1✔
1831
    res);
1✔
1832

1833
  name = PR_TEST_AUTH_NAME;
1834
  res = pr_auth_requires_pass(p, name);
1✔
1835
  ck_assert_msg(res == FALSE, "Known users should NOT require passwords (got %d)",
1✔
1836
    res);
1✔
1837
}
1838
END_TEST
1✔
1839

1840
START_TEST (auth_get_anon_config_test) {
1841
  config_rec *anon_config, *c, *c2, *res;
1✔
1842
  const char *login_user = "test";
1✔
1843
  char *real_user = NULL, *anon_user = NULL;
1✔
1844

1✔
1845
  mark_point();
1846
  login_user = "test";
1✔
1847
  res = pr_auth_get_anon_config(NULL, NULL, NULL, NULL);
1✔
1848
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
1849

1✔
1850
  mark_point();
1851
  /* UserAlias alias realname */
1✔
1852
  c = add_config_param_set(&(test_server->conf), "UserAlias", 2, NULL, NULL);
1853
  c->argv[0] = pstrdup(c->pool, "bar");
1✔
1854
  c->argv[1] = pstrdup(c->pool, "foo");
1✔
1855

1✔
1856
  c2 = add_config_param_set(&(test_server->conf), "AuthAliasOnly", 1, NULL);
1857
  c2->argv[0] = palloc(c2->pool, sizeof(unsigned char));
1✔
1858
  *((unsigned char *) c2->argv[0]) = TRUE;
1✔
1859

1✔
1860
  login_user = "test";
1861
  anon_user = "anon";
1✔
1862
  res = pr_auth_get_anon_config(p, &login_user, &real_user, &anon_user);
1✔
1863
  ck_assert_msg(res == NULL, "Failed to handle UserAlias with mismatched alias");
1✔
1864
  ck_assert_msg(login_user == NULL, "Failed to set login_user to null");
1✔
1865
  ck_assert_msg(anon_user == NULL, "Failed to set anon_user to null");
1✔
1866

1✔
1867
  mark_point();
1868
  login_user = "test";
1✔
1869
  c->argv[0] = pstrdup(c->pool, "*");
1✔
1870
  res = pr_auth_get_anon_config(p, &login_user, &real_user, &anon_user);
1✔
1871
  ck_assert_msg(res == NULL, "Failed to handle UserAlias with globbed alias");
1✔
1872

1✔
1873
  mark_point();
1874
  login_user = "test";
1✔
1875
  c->argv[0] = pstrdup(c->pool, login_user);
1✔
1876
  res = pr_auth_get_anon_config(p, &login_user, &real_user, &anon_user);
1✔
1877
  ck_assert_msg(res == NULL, "Failed to handle UserAlias with matching alias");
1✔
1878

1✔
1879
  mark_point();
1880
  login_user = "test";
1✔
1881
  anon_config = pcalloc(p, sizeof(config_rec));
1✔
1882
  anon_config->config_type = CONF_ANON;
1✔
1883
  c2 = add_config_param_set(&(anon_config->subset), "AuthAliasOnly", 1, NULL);
1✔
1884
  c2->argv[0] = palloc(c2->pool, sizeof(unsigned char));
1✔
1885
  *((unsigned char *) c2->argv[0]) = TRUE;
1✔
1886
  c->parent = anon_config;
1✔
1887
  res = pr_auth_get_anon_config(p, &login_user, &real_user, &anon_user);
1✔
1888
  ck_assert_msg(res != NULL, "Failed to handle UserAlias with matching alias and <Anonymous> config");
1✔
1889
  ck_assert_msg(res == anon_config, "Expected <Anonymous> config %p, got %p",
1✔
1890
    anon_config, res);
1✔
1891

1892
  mark_point();
1893
  login_user = "test";
1✔
1894
  real_user = "foo";
1✔
1895

1✔
1896
  c2 = add_config_param_set(&(anon_config->subset), "UserName", 1, NULL);
1897
  c2->argv[0] = pstrdup(c2->pool, "BAZ");
1✔
1898
  res = pr_auth_get_anon_config(p, &login_user, &real_user, &anon_user);
1✔
1899

1✔
1900
  ck_assert_msg(res != NULL, "Failed to handle UserAlias with matching alias and <Anonymous> config");
1901
  ck_assert_msg(res == anon_config, "Expected <Anonymous> config %p, got %p",
1✔
1902
    anon_config, res);
1✔
1903
  ck_assert_msg(real_user != NULL, "Expected real_user, got NULL");
1904
  ck_assert_msg(strcmp(real_user, "BAZ") == 0, "Expected real_user 'BAZ', got '%s'", real_user);
1✔
1905

1✔
1906
  (void) remove_config(test_server->conf, "AuthAliasOnly", TRUE);
1907
  (void) remove_config(test_server->conf, "UserAlias", FALSE);
1✔
1908
}
1✔
1909
END_TEST
1✔
1910

1911
START_TEST (auth_chroot_test) {
1912
  int res;
1✔
1913
  const char *path;
1✔
1914

1✔
1915
  mark_point();
1916
  res = pr_auth_chroot(NULL);
1✔
1917
  ck_assert_msg(res < 0, "Failed to handle null argument");
1✔
1918
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
1919
    strerror(errno), errno);
1✔
1920

1921
  mark_point();
1922
  path = "tmp";
1✔
1923
  res = pr_auth_chroot(path);
1✔
1924
  ck_assert_msg(res < 0, "Failed to chroot to '%s': %s", path, strerror(errno));
1✔
1925
  ck_assert_msg(errno == EINVAL || errno == ENOENT,
1✔
1926
    "Expected EINVAL (%d) or ENOENT (%d), got %s (%d)", EINVAL, ENOENT,
1✔
1927
    strerror(errno), errno);
1928

1929
  /* This first time, we do not have session.pool set, so the setting of the
1930
   * TZ environment variable will fail.
1931
   */
1932
  mark_point();
1933
  path = "/tmp";
1✔
1934
  res = pr_auth_chroot(path);
1✔
1935
  ck_assert_msg(res < 0, "Failed to chroot to '%s': %s", path, strerror(errno));
1✔
1936
  ck_assert_msg(errno == ENOENT || errno == EPERM || errno == EINVAL,
1✔
1937
    "Expected ENOENT (%d), EPERM (%d) or EINVAL (%d), got %s (%d)",
1✔
1938
    ENOENT, EPERM, EINVAL, strerror(errno), errno);
1939

1940
  /* We should now set the TZ environment variable, but still fail. */
1941
  mark_point();
1942
  session.pool = p;
1✔
1943
  path = "/tmp";
1✔
1944
  res = pr_auth_chroot(path);
1✔
1945
  ck_assert_msg(res < 0, "Failed to chroot to '%s': %s", path, strerror(errno));
1✔
1946
  ck_assert_msg(errno == ENOENT || errno == EPERM || errno == EINVAL,
1✔
1947
    "Expected ENOENT (%d), EPERM (%d) or EINVAL (%d), got %s (%d)",
1✔
1948
    ENOENT, EPERM, EINVAL, strerror(errno), errno);
1949

1950
  /* Last, the TZ environment variable should already be set. */
1951
  mark_point();
1952
  path = "/tmp";
1✔
1953
  res = pr_auth_chroot(path);
1✔
1954
  ck_assert_msg(res < 0, "Failed to chroot to '%s': %s", path, strerror(errno));
1✔
1955
  ck_assert_msg(errno == ENOENT || errno == EPERM || errno == EINVAL,
1✔
1956
    "Expected ENOENT (%d), EPERM (%d) or EINVAL (%d), got %s (%d)",
1✔
1957
    ENOENT, EPERM, EINVAL, strerror(errno), errno);
1958

1959
  session.pool = NULL;
1960
}
1✔
1961
END_TEST
1✔
1962

1963
START_TEST (auth_banned_by_ftpusers_test) {
1964
  const char *name;
1✔
1965
  int res;
1✔
1966
  config_rec *c;
1✔
1967

1✔
1968
  mark_point();
1969
  res = pr_auth_banned_by_ftpusers(NULL, NULL);
1✔
1970
  ck_assert_msg(res == FALSE, "Failed to handle null arguments");
1✔
1971

1✔
1972
  mark_point();
1973
  res = pr_auth_banned_by_ftpusers(test_server->conf, NULL);
1✔
1974
  ck_assert_msg(res == FALSE, "Failed to handle null user");
1✔
1975

1✔
1976
  mark_point();
1977
  name = "testsuite";
1✔
1978
  res = pr_auth_banned_by_ftpusers(test_server->conf, name);
1✔
1979
  ck_assert_msg(res == FALSE, "Expected FALSE, got %d", res);
1✔
1980

1✔
1981
  /* UseFtpUsers off */
1982
  mark_point();
1983
  c = add_config_param_set(&(test_server->conf), "UseFtpUsers", 1, NULL);
1✔
1984
  c->argv[0] = pcalloc(c->pool, sizeof(unsigned char));
1✔
1985
  *((unsigned char *) c->argv[0]) = FALSE;
1✔
1986

1✔
1987
  res = pr_auth_banned_by_ftpusers(test_server->conf, name);
1988
  ck_assert_msg(res == FALSE, "Failed to handle UseFtpUsers off (got %d)",
1✔
1989
    res);
1✔
1990

1991
  (void) remove_config(test_server->conf, "UseFtpUsers", FALSE);
1992
}
1✔
1993
END_TEST
1✔
1994

1995
START_TEST (auth_is_valid_shell_test) {
1996
  const char *shell;
1✔
1997
  int res;
1✔
1998
  config_rec *c;
1✔
1999

1✔
2000
  mark_point();
2001
  res = pr_auth_is_valid_shell(NULL, NULL);
1✔
2002
  ck_assert_msg(res == TRUE, "Failed to handle null arguments");
1✔
2003

1✔
2004
  mark_point();
2005
  res = pr_auth_is_valid_shell(test_server->conf, NULL);
1✔
2006
  ck_assert_msg(res == TRUE, "Failed to handle null shell");
1✔
2007

1✔
2008
  shell = "/foo/bar";
2009
  res = pr_auth_is_valid_shell(test_server->conf, shell);
1✔
2010
  ck_assert_msg(res == FALSE, "Failed to handle invalid shell '%s' (got %d)",
1✔
2011
    shell, res);
1✔
2012

2013
  mark_point();
2014
  shell = "/bin/sh";
1✔
2015
  res = pr_auth_is_valid_shell(test_server->conf, shell);
1✔
2016
  ck_assert_msg(res == TRUE, "Failed to handle valid shell '%s' (got %d)",
1✔
2017
    shell, res);
1✔
2018

2019
  /* RequireValidShell off */
2020
  mark_point();
2021
  c = add_config_param_set(&(test_server->conf), "RequireValidShell", 1, NULL);
1✔
2022
  c->argv[0] = pcalloc(c->pool, sizeof(unsigned char));
1✔
2023
  *((unsigned char *) c->argv[0]) = FALSE;
1✔
2024

1✔
2025
  shell = "/foo/bar";
2026
  res = pr_auth_is_valid_shell(test_server->conf, shell);
1✔
2027
  ck_assert_msg(res == TRUE, "Failed to handle RequireValidShell off (got %d)",
1✔
2028
    res);
1✔
2029

2030
  (void) remove_config(test_server->conf, "RequireValidShell", FALSE);
2031
}
1✔
2032
END_TEST
1✔
2033

2034
START_TEST (auth_set_groups_test) {
2035
  int res;
1✔
2036

1✔
2037
  if (getuid() == PR_ROOT_UID) {
2038
    gid_t gid;
1✔
2039

1✔
2040
    gid = getgid();
2041

1✔
2042
    mark_point();
2043
    res = set_groups(NULL, 0, NULL);
1✔
2044
    ck_assert_msg(res == 0, "Failed to handle zero primary gid: %s",
1✔
2045
      strerror(errno));
1✔
2046

2047
    mark_point();
2048
    res = set_groups(p, 0, NULL);
1✔
2049
    ck_assert_msg(res == 0, "Failed to handle zero primary gid: %s",
1✔
2050
      strerror(errno));
1✔
2051

2052
    mark_point();
2053
    res = set_groups(NULL, gid, NULL);
1✔
2054
    ck_assert_msg(res == 0, "Failed to handle current primary gid: %s",
1✔
2055
      strerror(errno));
1✔
2056

2057
  } else {
2058
    mark_point();
2059
    res = set_groups(NULL, 0, NULL);
×
2060
    ck_assert_msg(res < 0, "Failed to handle zero primary gid: %s",
×
2061
      strerror(errno));
×
2062
    ck_assert_msg(errno == ENOSYS, "Expected ENOSYS (%d), got %s (%d)", ENOSYS,
2063
      strerror(errno), errno);
×
2064

2065
    mark_point();
2066
    res = set_groups(p, 0, NULL);
×
2067
    ck_assert_msg(res < 0, "Failed to handle zero primary gid: %s",
×
2068
      strerror(errno));
×
2069
    ck_assert_msg(errno == ENOSYS, "Expected ENOSYS (%d), got %s (%d)", ENOSYS,
2070
      strerror(errno), errno);
×
2071

2072
    mark_point();
2073
    res = set_groups(p, 1, NULL);
×
2074
    ck_assert_msg(res < 0, "Failed to handle non-root primary gid: %s",
×
2075
      strerror(errno));
×
2076
    ck_assert_msg(errno == ENOSYS, "Expected ENOSYS (%d), got %s (%d)", ENOSYS,
2077
      strerror(errno), errno);
×
2078

2079
    mark_point();
2080
    res = set_groups(p, getgid(), NULL);
×
2081
    ck_assert_msg(res < 0, "Failed to handle current primary gid: %s",
×
2082
      strerror(errno));
×
2083
    ck_assert_msg(errno == ENOSYS, "Expected ENOSYS (%d), got %s (%d)", ENOSYS,
2084
      strerror(errno), errno);
×
2085
  }
2086
}
2087
END_TEST
1✔
2088

2089
START_TEST (auth_get_home_test) {
2090
  const char *home, *res;
1✔
2091
  config_rec *c;
1✔
2092

1✔
2093
  res = pr_auth_get_home(NULL, NULL);
2094
  ck_assert_msg(res == NULL, "Failed to handle null arguments");
1✔
2095
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2096
    strerror(errno), errno);
1✔
2097

2098
  res = pr_auth_get_home(p, NULL);
2099
  ck_assert_msg(res == NULL, "Failed to handle null home");
1✔
2100
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
2101
    strerror(errno), errno);
1✔
2102

2103
  home = "/testsuite";
2104
  res = pr_auth_get_home(p, home);
1✔
2105
  ck_assert_msg(res != NULL, "Failed to get home: %s", strerror(errno));
1✔
2106
  ck_assert_msg(strcmp(home, res) == 0, "Expected '%s', got '%s'", home, res);
1✔
2107

1✔
2108
  /* RewriteHome off */
2109
  mark_point();
2110
  c = add_config_param_set(&(test_server->conf), "RewriteHome", 1);
1✔
2111
  c->argv[0] = pcalloc(c->pool, sizeof(unsigned char));
1✔
2112
  *((int *) c->argv[0]) = FALSE;
1✔
2113

1✔
2114
  res = pr_auth_get_home(p, home);
2115
  ck_assert_msg(res != NULL, "Failed to get home: %s", strerror(errno));
1✔
2116
  ck_assert_msg(strcmp(home, res) == 0,
1✔
2117
    "Failed to handle RewriteHome off, got '%s'", res);
1✔
2118

2119
  /* RewriteHome on */
2120
  mark_point();
2121
  *((int *) c->argv[0]) = TRUE;
1✔
2122
  res = pr_auth_get_home(p, home);
1✔
2123
  ck_assert_msg(res != NULL, "Failed to get home: %s", strerror(errno));
1✔
2124
  ck_assert_msg(strcmp(home, res) == 0,
1✔
2125
    "Failed to handle RewriteHome on, got '%s'", res);
1✔
2126

2127
  mark_point();
2128
  session.notes = pr_table_alloc(p, 2);
1✔
2129
  res = pr_auth_get_home(p, home);
1✔
2130
  ck_assert_msg(res != NULL, "Failed to get home: %s", strerror(errno));
1✔
2131
  ck_assert_msg(strcmp(home, res) == 0,
1✔
2132
    "Failed to handle RewriteHome on, got '%s'", res);
1✔
2133

2134
  (void) pr_table_empty(session.notes);
2135
  (void) pr_table_free(session.notes);
1✔
2136
  session.notes = NULL;
1✔
2137

1✔
2138
  (void) remove_config(test_server->conf, "RewriteHome", FALSE);
2139
}
1✔
2140
END_TEST
1✔
2141

2142
START_TEST (auth_set_max_password_len_test) {
2143
  int checked;
1✔
2144
  size_t res;
1✔
2145

1✔
2146
  res = pr_auth_set_max_password_len(p, 1);
2147
  ck_assert_msg(res == PR_TUNABLE_PASSWORD_MAX,
1✔
2148
    "Expected %lu, got %lu", (unsigned long) PR_TUNABLE_PASSWORD_MAX,
1✔
2149
    (unsigned long) res);
2150

2151
  checked = pr_auth_check(p, NULL, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
2152
  ck_assert_msg(checked < 0, "Failed to reject too-long password");
1✔
2153
  ck_assert_msg(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1✔
2154
    strerror(errno), errno);
1✔
2155

2156
  res = pr_auth_set_max_password_len(p, 0);
2157
  ck_assert_msg(res == 1, "Expected %d, got %lu", 1, (unsigned long) res);
1✔
2158

1✔
2159
  res = pr_auth_set_max_password_len(p, 0);
2160
  ck_assert_msg(res == PR_TUNABLE_PASSWORD_MAX,
1✔
2161
    "Expected %lu, got %lu", (unsigned long) PR_TUNABLE_PASSWORD_MAX,
1✔
2162
    (unsigned long) res);
2163
}
2164
END_TEST
1✔
2165

2166
START_TEST (auth_bcrypt_test) {
2167
  char *res;
1✔
2168
  size_t hashed_len;
1✔
2169

1✔
2170
  res = pr_auth_bcrypt(NULL, NULL, NULL, NULL);
2171
  ck_assert_msg(res == NULL, "Failed to handle null pool argument");
1✔
2172
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1✔
2173
    strerror(errno), errno);
1✔
2174

2175
  res = pr_auth_bcrypt(p, NULL, NULL, NULL);
2176
  ck_assert_msg(res == NULL, "Failed to handle null key argument");
1✔
2177
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1✔
2178
    strerror(errno), errno);
1✔
2179

2180
  res = pr_auth_bcrypt(p, "", NULL, NULL);
2181
  ck_assert_msg(res == NULL, "Failed to handle null salt argument");
1✔
2182
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1✔
2183
    strerror(errno), errno);
1✔
2184

2185
  res = pr_auth_bcrypt(p, "", "", NULL);
2186
  ck_assert_msg(res == NULL, "Failed to handle null hashed_len argument");
1✔
2187
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1✔
2188
    strerror(errno), errno);
1✔
2189

2190
  res = pr_auth_bcrypt(p, "", "", &hashed_len);
2191
  ck_assert_msg(res == NULL, "Failed to handle empty strings");
1✔
2192
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1✔
2193
    strerror(errno), errno);
1✔
2194

2195
  res = pr_auth_bcrypt(p, "foo", "$1", &hashed_len);
2196
  ck_assert_msg(res == NULL, "Failed to handle invalid salt");
1✔
2197
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1✔
2198
    strerror(errno), errno);
1✔
2199

2200
  /* TODO: Add more tests of the invalid salt constructions: bcrypt version
2201
   * numbers, rounds, salt too short, etc.
2202
   */
2203

2204
  res = pr_auth_bcrypt(p, "password",
2205
    "$2b$12$IoFxXvbRQUKssPqFacJFFuZl1KXl5ULppqf0aLFjwCFnLRh3NbYSG",
1✔
2206
    &hashed_len);
2207
  ck_assert_msg(res != NULL, "Failed to handle valid key and salt");
2208
}
1✔
2209
END_TEST
1✔
2210

2211
Suite *tests_get_auth_suite(void) {
2212
  Suite *suite;
889✔
2213
  TCase *testcase;
889✔
2214

889✔
2215
  suite = suite_create("auth");
2216

889✔
2217
  testcase = tcase_create("base");
2218
  tcase_add_checked_fixture(testcase, set_up, tear_down);
889✔
2219

889✔
2220
  /* pwent* et al */
2221
  tcase_add_test(testcase, auth_setpwent_test);
2222
  tcase_add_test(testcase, auth_endpwent_test);
889✔
2223
  tcase_add_test(testcase, auth_getpwent_test);
889✔
2224
  tcase_add_test(testcase, auth_getpwnam_test);
889✔
2225
  tcase_add_test(testcase, auth_getpwuid_test);
889✔
2226
  tcase_add_test(testcase, auth_name2uid_test);
889✔
2227
  tcase_add_test(testcase, auth_uid2name_test);
889✔
2228

889✔
2229
  /* grent* et al */
2230
  tcase_add_test(testcase, auth_setgrent_test);
2231
  tcase_add_test(testcase, auth_endgrent_test);
889✔
2232
  tcase_add_test(testcase, auth_getgrent_test);
889✔
2233
  tcase_add_test(testcase, auth_getgrnam_test);
889✔
2234
  tcase_add_test(testcase, auth_getgrgid_test);
889✔
2235
  tcase_add_test(testcase, auth_gid2name_test);
889✔
2236
  tcase_add_test(testcase, auth_name2gid_test);
889✔
2237
  tcase_add_test(testcase, auth_getgroups_test);
889✔
2238

889✔
2239
  /* Caching tests */
2240
  tcase_add_test(testcase, auth_cache_uid2name_test);
2241
  tcase_add_test(testcase, auth_cache_gid2name_test);
889✔
2242
  tcase_add_test(testcase, auth_cache_uid2name_failed_test);
889✔
2243
  tcase_add_test(testcase, auth_cache_gid2name_failed_test);
889✔
2244
  tcase_add_test(testcase, auth_cache_name2uid_failed_test);
889✔
2245
  tcase_add_test(testcase, auth_cache_name2gid_failed_test);
889✔
2246
  tcase_add_test(testcase, auth_cache_clear_test);
889✔
2247
  tcase_add_test(testcase, auth_cache_set_test);
889✔
2248

889✔
2249
  /* Auth modules */
2250
  tcase_add_test(testcase, auth_clear_auth_only_module_test);
2251
  tcase_add_test(testcase, auth_add_auth_only_module_test);
889✔
2252
  tcase_add_test(testcase, auth_remove_auth_only_module_test);
889✔
2253

889✔
2254
  /* Authorization */
2255
  tcase_add_test(testcase, auth_authenticate_test);
2256
  tcase_add_test(testcase, auth_authorize_test);
889✔
2257
  tcase_add_test(testcase, auth_check_errors_test);
889✔
2258
  tcase_add_test(testcase, auth_check_valid_test);
889✔
2259
  tcase_add_test(testcase, auth_requires_pass_test);
889✔
2260

889✔
2261
  /* Misc */
2262
  tcase_add_test(testcase, auth_get_anon_config_test);
2263
  tcase_add_test(testcase, auth_chroot_test);
889✔
2264
  tcase_add_test(testcase, auth_banned_by_ftpusers_test);
889✔
2265
  tcase_add_test(testcase, auth_is_valid_shell_test);
889✔
2266
  tcase_add_test(testcase, auth_set_groups_test);
889✔
2267
  tcase_add_test(testcase, auth_get_home_test);
889✔
2268
  tcase_add_test(testcase, auth_set_max_password_len_test);
889✔
2269
  tcase_add_test(testcase, auth_bcrypt_test);
889✔
2270

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