1 /*
2  * ProFTPD - FTP server testsuite
3  * Copyright (c) 2014-2020 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, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 /* Auth API tests */
26 
27 #include "tests.h"
28 
29 #define PR_TEST_AUTH_NAME		"testsuite_user"
30 #define PR_TEST_AUTH_NOBODY		"testsuite_nobody"
31 #define PR_TEST_AUTH_NOBODY2		"testsuite_nobody2"
32 #define PR_TEST_AUTH_NOGROUP		"testsuite_nogroup"
33 #define PR_TEST_AUTH_UID		500
34 #define PR_TEST_AUTH_UID_STR		"500"
35 #define PR_TEST_AUTH_NOUID		666
36 #define PR_TEST_AUTH_NOUID2		667
37 #define PR_TEST_AUTH_GID		500
38 #define PR_TEST_AUTH_GID_STR		"500"
39 #define PR_TEST_AUTH_NOGID		666
40 #define PR_TEST_AUTH_HOME		"/tmp"
41 #define PR_TEST_AUTH_SHELL		"/bin/bash"
42 #define PR_TEST_AUTH_PASSWD		"password"
43 
44 static pool *p = 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 
handle_setpwent(cmd_rec * cmd)91 MODRET handle_setpwent(cmd_rec *cmd) {
92   setpwent_count++;
93   return PR_HANDLED(cmd);
94 }
95 
handle_endpwent(cmd_rec * cmd)96 MODRET handle_endpwent(cmd_rec *cmd) {
97   endpwent_count++;
98   return PR_HANDLED(cmd);
99 }
100 
handle_getpwent(cmd_rec * cmd)101 MODRET handle_getpwent(cmd_rec *cmd) {
102   getpwent_count++;
103 
104   if (getpwent_count == 1) {
105     test_pwd.pw_uid = PR_TEST_AUTH_UID;
106     test_pwd.pw_gid = PR_TEST_AUTH_GID;
107     return mod_create_data(cmd, &test_pwd);
108   }
109 
110   if (getpwent_count == 2) {
111     test_pwd.pw_uid = (uid_t) -1;
112     test_pwd.pw_gid = PR_TEST_AUTH_GID;
113     return mod_create_data(cmd, &test_pwd);
114   }
115 
116   if (getpwent_count == 3) {
117     test_pwd.pw_uid = PR_TEST_AUTH_UID;
118     test_pwd.pw_gid = (gid_t) -1;
119     return mod_create_data(cmd, &test_pwd);
120   }
121 
122   return PR_DECLINED(cmd);
123 }
124 
handle_getpwnam(cmd_rec * cmd)125 MODRET handle_getpwnam(cmd_rec *cmd) {
126   const char *name;
127 
128   name = cmd->argv[0];
129   getpwnam_count++;
130 
131   if (strcmp(name, PR_TEST_AUTH_NAME) == 0) {
132     test_pwd.pw_uid = PR_TEST_AUTH_UID;
133     test_pwd.pw_gid = PR_TEST_AUTH_GID;
134     return mod_create_data(cmd, &test_pwd);
135   }
136 
137   if (strcmp(name, PR_TEST_AUTH_NOBODY) == 0) {
138     test_pwd.pw_uid = (uid_t) -1;
139     test_pwd.pw_gid = PR_TEST_AUTH_GID;
140     return mod_create_data(cmd, &test_pwd);
141   }
142 
143   if (strcmp(name, PR_TEST_AUTH_NOBODY2) == 0) {
144     test_pwd.pw_uid = PR_TEST_AUTH_UID;
145     test_pwd.pw_gid = (gid_t) -1;
146     return mod_create_data(cmd, &test_pwd);
147   }
148 
149   return PR_DECLINED(cmd);
150 }
151 
handle_getpwuid(cmd_rec * cmd)152 MODRET handle_getpwuid(cmd_rec *cmd) {
153   uid_t uid;
154 
155   uid = *((uid_t *) cmd->argv[0]);
156   getpwuid_count++;
157 
158   if (uid == PR_TEST_AUTH_UID) {
159     test_pwd.pw_uid = PR_TEST_AUTH_UID;
160     test_pwd.pw_gid = PR_TEST_AUTH_GID;
161     return mod_create_data(cmd, &test_pwd);
162   }
163 
164   if (uid == PR_TEST_AUTH_NOUID) {
165     test_pwd.pw_uid = (uid_t) -1;
166     test_pwd.pw_gid = PR_TEST_AUTH_GID;
167     return mod_create_data(cmd, &test_pwd);
168   }
169 
170   if (uid == PR_TEST_AUTH_NOUID2) {
171     test_pwd.pw_uid = PR_TEST_AUTH_UID;
172     test_pwd.pw_gid = (gid_t) -1;
173     return mod_create_data(cmd, &test_pwd);
174   }
175 
176   return PR_DECLINED(cmd);
177 }
178 
decline_name2uid(cmd_rec * cmd)179 MODRET decline_name2uid(cmd_rec *cmd) {
180   name2uid_count++;
181   return PR_DECLINED(cmd);
182 }
183 
handle_name2uid(cmd_rec * cmd)184 MODRET handle_name2uid(cmd_rec *cmd) {
185   const char *name;
186 
187   name = cmd->argv[0];
188   name2uid_count++;
189 
190   if (strcmp(name, PR_TEST_AUTH_NAME) != 0) {
191     return PR_DECLINED(cmd);
192   }
193 
194   return mod_create_data(cmd, (void *) &(test_pwd.pw_uid));
195 }
196 
decline_uid2name(cmd_rec * cmd)197 MODRET decline_uid2name(cmd_rec *cmd) {
198   uid2name_count++;
199   return PR_DECLINED(cmd);
200 }
201 
handle_uid2name(cmd_rec * cmd)202 MODRET handle_uid2name(cmd_rec *cmd) {
203   uid_t uid;
204 
205   uid = *((uid_t *) cmd->argv[0]);
206   uid2name_count++;
207 
208   if (uid != PR_TEST_AUTH_UID) {
209     return PR_DECLINED(cmd);
210   }
211 
212   return mod_create_data(cmd, test_pwd.pw_name);
213 }
214 
handle_setgrent(cmd_rec * cmd)215 MODRET handle_setgrent(cmd_rec *cmd) {
216   setgrent_count++;
217   return PR_HANDLED(cmd);
218 }
219 
handle_endgrent(cmd_rec * cmd)220 MODRET handle_endgrent(cmd_rec *cmd) {
221   endgrent_count++;
222   return PR_HANDLED(cmd);
223 }
224 
handle_getgrent(cmd_rec * cmd)225 MODRET handle_getgrent(cmd_rec *cmd) {
226   getgrent_count++;
227 
228   if (getgrent_count == 1) {
229     test_grp.gr_gid = PR_TEST_AUTH_GID;
230     return mod_create_data(cmd, &test_grp);
231   }
232 
233   if (getgrent_count == 2) {
234     test_grp.gr_gid = (gid_t) -1;
235     return mod_create_data(cmd, &test_grp);
236   }
237 
238   return PR_DECLINED(cmd);
239 }
240 
handle_getgrnam(cmd_rec * cmd)241 MODRET handle_getgrnam(cmd_rec *cmd) {
242   const char *name;
243 
244   name = cmd->argv[0];
245   getgrnam_count++;
246 
247   if (strcmp(name, PR_TEST_AUTH_NAME) == 0) {
248     test_grp.gr_gid = PR_TEST_AUTH_GID;
249     return mod_create_data(cmd, &test_grp);
250   }
251 
252   if (strcmp(name, PR_TEST_AUTH_NOGROUP) == 0) {
253     test_grp.gr_gid = (gid_t) -1;
254     return mod_create_data(cmd, &test_grp);
255   }
256 
257   return PR_DECLINED(cmd);
258 }
259 
handle_getgrgid(cmd_rec * cmd)260 MODRET handle_getgrgid(cmd_rec *cmd) {
261   gid_t gid;
262 
263   gid = *((gid_t *) cmd->argv[0]);
264   getgrgid_count++;
265 
266   if (gid == PR_TEST_AUTH_GID) {
267     test_grp.gr_gid = PR_TEST_AUTH_GID;
268     return mod_create_data(cmd, &test_grp);
269   }
270 
271   if (gid == PR_TEST_AUTH_NOGID) {
272     test_grp.gr_gid = (gid_t) -1;
273     return mod_create_data(cmd, &test_grp);
274   }
275 
276   return PR_DECLINED(cmd);
277 }
278 
decline_name2gid(cmd_rec * cmd)279 MODRET decline_name2gid(cmd_rec *cmd) {
280   name2gid_count++;
281   return PR_DECLINED(cmd);
282 }
283 
handle_name2gid(cmd_rec * cmd)284 MODRET handle_name2gid(cmd_rec *cmd) {
285   const char *name;
286 
287   name = cmd->argv[0];
288   name2gid_count++;
289 
290   if (strcmp(name, PR_TEST_AUTH_NAME) != 0) {
291     return PR_DECLINED(cmd);
292   }
293 
294   return mod_create_data(cmd, (void *) &(test_grp.gr_gid));
295 }
296 
decline_gid2name(cmd_rec * cmd)297 MODRET decline_gid2name(cmd_rec *cmd) {
298   gid2name_count++;
299   return PR_DECLINED(cmd);
300 }
301 
handle_gid2name(cmd_rec * cmd)302 MODRET handle_gid2name(cmd_rec *cmd) {
303   gid_t gid;
304 
305   gid = *((gid_t *) cmd->argv[0]);
306   gid2name_count++;
307 
308   if (gid != PR_TEST_AUTH_GID) {
309     return PR_DECLINED(cmd);
310   }
311 
312   return mod_create_data(cmd, test_grp.gr_name);
313 }
314 
handle_getgroups(cmd_rec * cmd)315 MODRET handle_getgroups(cmd_rec *cmd) {
316   const char *name;
317   array_header *gids = NULL, *names = NULL;
318 
319   name = (char *) cmd->argv[0];
320 
321   if (cmd->argv[1]) {
322     gids = (array_header *) cmd->argv[1];
323   }
324 
325   if (cmd->argv[2]) {
326     names = (array_header *) cmd->argv[2];
327   }
328 
329   getgroups_count++;
330 
331   if (strcmp(name, PR_TEST_AUTH_NAME) != 0) {
332     return PR_DECLINED(cmd);
333   }
334 
335   if (gids) {
336     *((gid_t *) push_array(gids)) = PR_TEST_AUTH_GID;
337   }
338 
339   if (names) {
340     *((char **) push_array(names)) = pstrdup(p, PR_TEST_AUTH_NAME);
341   }
342 
343   return mod_create_data(cmd, (void *) &gids->nelts);
344 }
345 
346 static int authn_rfc2228 = FALSE;
347 
handle_authn(cmd_rec * cmd)348 MODRET handle_authn(cmd_rec *cmd) {
349   const char *user, *cleartext_passwd;
350 
351   user = cmd->argv[0];
352   cleartext_passwd = cmd->argv[1];
353 
354   if (strcmp(user, PR_TEST_AUTH_NAME) == 0) {
355     if (strcmp(cleartext_passwd, PR_TEST_AUTH_PASSWD) == 0) {
356       if (authn_rfc2228) {
357         authn_rfc2228 = FALSE;
358         return mod_create_data(cmd, (void *) PR_AUTH_RFC2228_OK);
359       }
360 
361       return PR_HANDLED(cmd);
362     }
363 
364     return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);
365   }
366 
367   return PR_DECLINED(cmd);
368 }
369 
handle_authz(cmd_rec * cmd)370 MODRET handle_authz(cmd_rec *cmd) {
371   const char *user;
372 
373   user = cmd->argv[0];
374 
375   if (strcmp(user, PR_TEST_AUTH_NAME) == 0) {
376     return PR_HANDLED(cmd);
377   }
378 
379   return PR_ERROR_INT(cmd, PR_AUTH_NOPWD);
380 }
381 
382 static int check_rfc2228 = FALSE;
383 
handle_check(cmd_rec * cmd)384 MODRET handle_check(cmd_rec *cmd) {
385   const char *user, *cleartext_passwd, *ciphertext_passwd;
386 
387   ciphertext_passwd = cmd->argv[0];
388   user = cmd->argv[1];
389   cleartext_passwd = cmd->argv[2];
390 
391   if (strcmp(user, PR_TEST_AUTH_NAME) == 0) {
392     if (ciphertext_passwd != NULL &&
393         strcmp(ciphertext_passwd, cleartext_passwd) == 0) {
394       if (check_rfc2228) {
395         check_rfc2228 = FALSE;
396         return mod_create_data(cmd, (void *) PR_AUTH_RFC2228_OK);
397       }
398 
399       return PR_HANDLED(cmd);
400     }
401 
402     return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);
403   }
404 
405   return PR_DECLINED(cmd);
406 }
407 
handle_requires_pass(cmd_rec * cmd)408 MODRET handle_requires_pass(cmd_rec *cmd) {
409   const char *name;
410 
411   name = cmd->argv[0];
412 
413   if (strcmp(name, PR_TEST_AUTH_NAME) == 0) {
414     return mod_create_data(cmd, (void *) PR_AUTH_RFC2228_OK);
415   }
416 
417   return PR_DECLINED(cmd);
418 }
419 
420 /* Fixtures */
421 
set_up(void)422 static void set_up(void) {
423   server_rec *s = NULL;
424 
425   if (p == NULL) {
426     p = permanent_pool = make_sub_pool(NULL);
427   }
428 
429   init_stash();
430   init_auth();
431   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_DEFAULT);
432 
433   if (getenv("TEST_VERBOSE") != NULL) {
434     pr_trace_set_levels("auth", 1, 20);
435   }
436 
437   s = pcalloc(p, sizeof(server_rec));
438   tests_stubs_set_main_server(s);
439 
440   test_pwd.pw_name = PR_TEST_AUTH_NAME;
441   test_pwd.pw_uid = PR_TEST_AUTH_UID;
442   test_pwd.pw_gid = PR_TEST_AUTH_GID;
443   test_pwd.pw_dir = PR_TEST_AUTH_HOME;
444   test_pwd.pw_shell = PR_TEST_AUTH_SHELL;
445 
446   test_grp.gr_name = PR_TEST_AUTH_NAME;
447   test_grp.gr_gid = PR_TEST_AUTH_GID;
448 
449   /* Reset counters. */
450   setpwent_count = 0;
451   endpwent_count = 0;
452   getpwent_count = 0;
453   getpwnam_count = 0;
454   getpwuid_count = 0;
455   name2uid_count = 0;
456   uid2name_count = 0;
457 
458   setgrent_count = 0;
459   endgrent_count = 0;
460   getgrent_count = 0;
461   getgrnam_count = 0;
462   getgrgid_count = 0;
463   name2gid_count = 0;
464   gid2name_count = 0;
465   getgroups_count = 0;
466 
467   pr_auth_cache_clear();
468 }
469 
tear_down(void)470 static void tear_down(void) {
471   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_DEFAULT);
472 
473   if (getenv("TEST_VERBOSE") != NULL) {
474     pr_trace_set_levels("auth", 0, 0);
475   }
476 
477   if (p) {
478     destroy_pool(p);
479     p = permanent_pool = NULL;
480   }
481 
482   tests_stubs_set_main_server(NULL);
483 }
484 
485 /* Tests */
486 
START_TEST(auth_setpwent_test)487 START_TEST (auth_setpwent_test) {
488   int res;
489   authtable authtab;
490   char *sym_name = "setpwent";
491 
492   pr_auth_setpwent(p);
493   fail_unless(setpwent_count == 0, "Expected call count 0, got %u",
494     setpwent_count);
495   mark_point();
496 
497   /* Load the appropriate AUTH symbol, and call it. */
498 
499   memset(&authtab, 0, sizeof(authtab));
500   authtab.name = sym_name;
501   authtab.handler = handle_setpwent;
502   authtab.m = &testsuite_module;
503   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
504   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
505     strerror(errno));
506 
507   pr_auth_setpwent(p);
508   fail_unless(setpwent_count == 1, "Expected call count 1, got %u",
509     setpwent_count);
510 
511   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
512 }
513 END_TEST
514 
START_TEST(auth_endpwent_test)515 START_TEST (auth_endpwent_test) {
516   int res;
517   authtable authtab;
518   char *sym_name = "endpwent";
519 
520   pr_auth_endpwent(p);
521   fail_unless(endpwent_count == 0, "Expected call count 0, got %u",
522     endpwent_count);
523   mark_point();
524 
525   /* Load the appropriate AUTH symbol, and call it. */
526 
527   memset(&authtab, 0, sizeof(authtab));
528   authtab.name = sym_name;
529   authtab.handler = handle_endpwent;
530   authtab.m = &testsuite_module;
531   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
532   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
533     strerror(errno));
534 
535   pr_auth_endpwent(p);
536   fail_unless(endpwent_count == 1, "Expected call count 1, got %u",
537     endpwent_count);
538 
539   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
540 }
541 END_TEST
542 
START_TEST(auth_getpwent_test)543 START_TEST (auth_getpwent_test) {
544   int res;
545   struct passwd *pw;
546   authtable authtab;
547   char *sym_name = "getpwent";
548 
549   getpwent_count = 0;
550 
551   pw = pr_auth_getpwent(NULL);
552   fail_unless(pw == NULL, "Found pwent unexpectedly");
553   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
554     errno, strerror(errno));
555 
556   pw = pr_auth_getpwent(p);
557   fail_unless(pw == NULL, "Found pwent unexpectedly");
558   fail_unless(getpwent_count == 0, "Expected call count 0, got %u",
559     getpwent_count);
560   mark_point();
561 
562   /* Load the appropriate AUTH symbol, and call it. */
563 
564   memset(&authtab, 0, sizeof(authtab));
565   authtab.name = sym_name;
566   authtab.handler = handle_getpwent;
567   authtab.m = &testsuite_module;
568   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
569   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
570     strerror(errno));
571 
572   pw = pr_auth_getpwent(p);
573   fail_unless(pw != NULL, "Failed to find pwent: %s", strerror(errno));
574   fail_unless(getpwent_count == 1, "Expected call count 1, got %u",
575     getpwent_count);
576 
577   pw = pr_auth_getpwent(p);
578   fail_unless(pw == NULL, "Failed to avoid pwent with bad UID");
579   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
580     strerror(errno), errno);
581   fail_unless(getpwent_count == 2, "Expected call count 2, got %u",
582     getpwent_count);
583 
584   pw = pr_auth_getpwent(p);
585   fail_unless(pw == NULL, "Failed to avoid pwent with bad GID");
586   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
587     strerror(errno), errno);
588   fail_unless(getpwent_count == 3, "Expected call count 3, got %u",
589     getpwent_count);
590 
591   pr_auth_endpwent(p);
592   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
593 }
594 END_TEST
595 
START_TEST(auth_getpwnam_test)596 START_TEST (auth_getpwnam_test) {
597   int res;
598   struct passwd *pw;
599   authtable authtab;
600   char *sym_name = "getpwnam";
601 
602   pw = pr_auth_getpwnam(NULL, NULL);
603   fail_unless(pw == NULL, "Found pwnam unexpectedly");
604   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
605     errno, strerror(errno));
606 
607   pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME);
608   fail_unless(pw == NULL, "Found pwnam unexpectedly");
609   fail_unless(getpwnam_count == 0, "Expected call count 0, got %u",
610     getpwnam_count);
611   mark_point();
612 
613   /* Load the appropriate AUTH symbol, and call it. */
614 
615   memset(&authtab, 0, sizeof(authtab));
616   authtab.name = sym_name;
617   authtab.handler = handle_getpwnam;
618   authtab.m = &testsuite_module;
619   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
620   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
621     strerror(errno));
622 
623   mark_point();
624 
625   pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NOBODY);
626   fail_unless(pw == NULL, "Found user '%s' unexpectedly", PR_TEST_AUTH_NOBODY);
627   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
628     strerror(errno), errno);
629 
630   pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NOBODY2);
631   fail_unless(pw == NULL, "Found user '%s' unexpectedly", PR_TEST_AUTH_NOBODY2);
632   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
633     strerror(errno), errno);
634 
635   pw = pr_auth_getpwnam(p, PR_TEST_AUTH_NAME);
636   fail_unless(pw != NULL, "Failed to find user '%s': %s", PR_TEST_AUTH_NAME,
637     strerror(errno));
638   fail_unless(getpwnam_count == 3, "Expected call count 3, got %u",
639     getpwnam_count);
640 
641   mark_point();
642 
643   pw = pr_auth_getpwnam(p, "other");
644   fail_unless(pw == NULL, "Found pwnam for user 'other' unexpectedly");
645   fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
646     errno, strerror(errno));
647   fail_unless(getpwnam_count == 4, "Expected call count 4, got %u",
648     getpwnam_count);
649 
650   pr_auth_endpwent(p);
651   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
652 }
653 END_TEST
654 
START_TEST(auth_getpwuid_test)655 START_TEST (auth_getpwuid_test) {
656   int res;
657   struct passwd *pw;
658   authtable authtab;
659   char *sym_name = "getpwuid";
660 
661   pw = pr_auth_getpwuid(NULL, -1);
662   fail_unless(pw == NULL, "Found pwuid unexpectedly");
663   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
664     errno, strerror(errno));
665 
666   pw = pr_auth_getpwuid(p, PR_TEST_AUTH_UID);
667   fail_unless(pw == NULL, "Found pwuid unexpectedly");
668   fail_unless(getpwuid_count == 0, "Expected call count 0, got %u",
669     getpwuid_count);
670   mark_point();
671 
672   /* Load the appropriate AUTH symbol, and call it. */
673 
674   memset(&authtab, 0, sizeof(authtab));
675   authtab.name = sym_name;
676   authtab.handler = handle_getpwuid;
677   authtab.m = &testsuite_module;
678   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
679   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
680     strerror(errno));
681 
682   mark_point();
683 
684   pw = pr_auth_getpwuid(p, PR_TEST_AUTH_UID);
685   fail_unless(pw != NULL, "Failed to find pwuid: %s", strerror(errno));
686   fail_unless(getpwuid_count == 1, "Expected call count 1, got %u",
687     getpwuid_count);
688 
689   pw = pr_auth_getpwuid(p, PR_TEST_AUTH_NOUID);
690   fail_unless(pw == NULL, "Found pwuid for NOUID unexpectedly");
691   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
692     strerror(errno), errno);
693 
694   pw = pr_auth_getpwuid(p, PR_TEST_AUTH_NOUID2);
695   fail_unless(pw == NULL, "Found pwuid for NOUID2 unexpectedly");
696   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
697     strerror(errno), errno);
698 
699   mark_point();
700 
701   pw = pr_auth_getpwuid(p, 5);
702   fail_unless(pw == NULL, "Found pwuid for UID 5 unexpectedly");
703   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
704     strerror(errno), errno);
705 
706   fail_unless(getpwuid_count == 4, "Expected call count 4, got %u",
707     getpwuid_count);
708 
709   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
710 }
711 END_TEST
712 
START_TEST(auth_name2uid_test)713 START_TEST (auth_name2uid_test) {
714   int res;
715   uid_t uid;
716   authtable authtab;
717   char *sym_name = "name2uid";
718 
719   pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_NAME2UID);
720 
721   uid = pr_auth_name2uid(NULL, NULL);
722   fail_unless(uid == (uid_t) -1, "Found UID unexpectedly");
723   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
724     errno, strerror(errno));
725 
726   uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
727   fail_unless(uid == (uid_t) -1, "Found UID unexpectedly");
728   fail_unless(name2uid_count == 0, "Expected call count 0, got %u",
729     name2uid_count);
730   mark_point();
731 
732   /* Load the appropriate AUTH symbol, and call it. */
733 
734   memset(&authtab, 0, sizeof(authtab));
735   authtab.name = sym_name;
736   authtab.handler = handle_name2uid;
737   authtab.m = &testsuite_module;
738   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
739   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
740     strerror(errno));
741 
742   mark_point();
743 
744   uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
745   fail_unless(uid == PR_TEST_AUTH_UID, "Expected UID %lu, got %lu",
746     (unsigned long) PR_TEST_AUTH_UID, (unsigned long) uid);
747   fail_unless(name2uid_count == 1, "Expected call count 1, got %u",
748     name2uid_count);
749 
750   mark_point();
751 
752   /* Call again; the call counter should NOT increment due to caching. */
753 
754   uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
755   fail_unless(uid == PR_TEST_AUTH_UID, "Expected UID %lu, got %lu",
756     (unsigned long) PR_TEST_AUTH_UID, (unsigned long) uid);
757   fail_unless(name2uid_count == 1, "Expected call count 1, got %u",
758     name2uid_count);
759 
760   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
761 }
762 END_TEST
763 
START_TEST(auth_uid2name_test)764 START_TEST (auth_uid2name_test) {
765   int res;
766   const char *name;
767   authtable authtab;
768   char *sym_name = "uid2name";
769 
770   pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_UID2NAME);
771 
772   name = pr_auth_uid2name(NULL, -1);
773   fail_unless(name == NULL, "Found name unexpectedly: %s", name);
774   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
775     errno, strerror(errno));
776   mark_point();
777 
778   name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
779   fail_unless(name != NULL, "Failed to find name for UID %lu: %s",
780     (unsigned long) PR_TEST_AUTH_UID, strerror(errno));
781   fail_unless(strcmp(name, PR_TEST_AUTH_UID_STR) == 0,
782      "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name);
783   fail_unless(uid2name_count == 0, "Expected call count 0, got %u",
784     uid2name_count);
785   mark_point();
786 
787   /* Load the appropriate AUTH symbol, and call it. */
788 
789   memset(&authtab, 0, sizeof(authtab));
790   authtab.name = sym_name;
791   authtab.handler = handle_uid2name;
792   authtab.m = &testsuite_module;
793   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
794   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
795     strerror(errno));
796 
797   mark_point();
798 
799   name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
800   fail_unless(name != NULL, "Expected name, got null");
801   fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0,
802     "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
803   fail_unless(uid2name_count == 1, "Expected call count 1, got %u",
804     uid2name_count);
805 
806   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
807 }
808 END_TEST
809 
START_TEST(auth_setgrent_test)810 START_TEST (auth_setgrent_test) {
811   int res;
812   authtable authtab;
813   char *sym_name = "setgrent";
814 
815   pr_auth_setgrent(p);
816   fail_unless(setgrent_count == 0, "Expected call count 0, got %u",
817     setgrent_count);
818   mark_point();
819 
820   /* Load the appropriate AUTH symbol, and call it. */
821 
822   memset(&authtab, 0, sizeof(authtab));
823   authtab.name = sym_name;
824   authtab.handler = handle_setgrent;
825   authtab.m = &testsuite_module;
826   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
827   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
828     strerror(errno));
829 
830   pr_auth_setgrent(p);
831   fail_unless(setgrent_count == 1, "Expected call count 1, got %u",
832     setgrent_count);
833 
834   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
835 }
836 END_TEST
837 
START_TEST(auth_endgrent_test)838 START_TEST (auth_endgrent_test) {
839   int res;
840   authtable authtab;
841   char *sym_name = "endgrent";
842 
843   pr_auth_endgrent(p);
844   fail_unless(endgrent_count == 0, "Expected call count 0, got %u",
845     endgrent_count);
846   mark_point();
847 
848   /* Load the appropriate AUTH symbol, and call it. */
849 
850   memset(&authtab, 0, sizeof(authtab));
851   authtab.name = sym_name;
852   authtab.handler = handle_endgrent;
853   authtab.m = &testsuite_module;
854   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
855   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
856     strerror(errno));
857 
858   pr_auth_endgrent(p);
859   fail_unless(endgrent_count == 1, "Expected call count 1, got %u",
860     endgrent_count);
861 
862   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
863 }
864 END_TEST
865 
START_TEST(auth_getgrent_test)866 START_TEST (auth_getgrent_test) {
867   int res;
868   struct group *gr;
869   authtable authtab;
870   char *sym_name = "getgrent";
871 
872   gr = pr_auth_getgrent(NULL);
873   fail_unless(gr == NULL, "Found grent unexpectedly");
874   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
875     errno, strerror(errno));
876 
877   gr = pr_auth_getgrent(p);
878   fail_unless(gr == NULL, "Found grent unexpectedly");
879   fail_unless(getgrent_count == 0, "Expected call count 0, got %u",
880     getgrent_count);
881   mark_point();
882 
883   /* Load the appropriate AUTH symbol, and call it. */
884 
885   memset(&authtab, 0, sizeof(authtab));
886   authtab.name = sym_name;
887   authtab.handler = handle_getgrent;
888   authtab.m = &testsuite_module;
889   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
890   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
891     strerror(errno));
892 
893   gr = pr_auth_getgrent(p);
894   fail_unless(gr != NULL, "Failed to find grent: %s", strerror(errno));
895   fail_unless(getgrent_count == 1, "Expected call count 1, got %u",
896     getgrent_count);
897 
898   gr = pr_auth_getgrent(p);
899   fail_unless(gr == NULL, "Failed to avoid grent with bad GID");
900   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
901     strerror(errno), errno);
902   fail_unless(getgrent_count == 2, "Expected call count 2, got %u",
903     getgrent_count);
904 
905   pr_auth_endgrent(p);
906   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
907 }
908 END_TEST
909 
START_TEST(auth_getgrnam_test)910 START_TEST (auth_getgrnam_test) {
911   int res;
912   struct group *gr;
913   authtable authtab;
914   char *sym_name = "getgrnam";
915 
916   gr = pr_auth_getgrnam(NULL, NULL);
917   fail_unless(gr == NULL, "Found grnam unexpectedly");
918   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
919     errno, strerror(errno));
920 
921   gr = pr_auth_getgrnam(p, PR_TEST_AUTH_NAME);
922   fail_unless(gr == NULL, "Found grnam unexpectedly");
923   fail_unless(getgrnam_count == 0, "Expected call count 0, got %u",
924     getgrnam_count);
925   mark_point();
926 
927   /* Load the appropriate AUTH symbol, and call it. */
928 
929   memset(&authtab, 0, sizeof(authtab));
930   authtab.name = sym_name;
931   authtab.handler = handle_getgrnam;
932   authtab.m = &testsuite_module;
933   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
934   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
935     strerror(errno));
936 
937   mark_point();
938 
939   gr = pr_auth_getgrnam(p, PR_TEST_AUTH_NOGROUP);
940   fail_unless(gr == NULL, "Found group '%s' unexpectedly",
941     PR_TEST_AUTH_NOGROUP);
942   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
943     strerror(errno), errno);
944 
945   gr = pr_auth_getgrnam(p, PR_TEST_AUTH_NAME);
946   fail_unless(gr != NULL, "Failed to find grnam: %s", strerror(errno));
947   fail_unless(getgrnam_count == 2, "Expected call count 2, got %u",
948     getgrnam_count);
949 
950   mark_point();
951 
952   gr = pr_auth_getgrnam(p, "other");
953   fail_unless(gr == NULL, "Found grnam for user 'other' unexpectedly");
954   fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
955     errno, strerror(errno));
956   fail_unless(getgrnam_count == 3, "Expected call count 3, got %u",
957     getgrnam_count);
958 
959   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
960 }
961 END_TEST
962 
START_TEST(auth_getgrgid_test)963 START_TEST (auth_getgrgid_test) {
964   int res;
965   struct group *gr;
966   authtable authtab;
967   char *sym_name = "getgrgid";
968 
969   gr = pr_auth_getgrgid(NULL, -1);
970   fail_unless(gr == NULL, "Found grgid unexpectedly");
971   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
972     errno, strerror(errno));
973 
974   gr = pr_auth_getgrgid(p, PR_TEST_AUTH_GID);
975   fail_unless(gr == NULL, "Found grgid unexpectedly");
976   fail_unless(getgrgid_count == 0, "Expected call count 0, got %u",
977     getgrgid_count);
978   mark_point();
979 
980   /* Load the appropriate AUTH symbol, and call it. */
981 
982   memset(&authtab, 0, sizeof(authtab));
983   authtab.name = sym_name;
984   authtab.handler = handle_getgrgid;
985   authtab.m = &testsuite_module;
986   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
987   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
988     strerror(errno));
989 
990   mark_point();
991 
992   gr = pr_auth_getgrgid(p, PR_TEST_AUTH_GID);
993   fail_unless(gr != NULL, "Failed to find grgid: %s", strerror(errno));
994   fail_unless(getgrgid_count == 1, "Expected call count 1, got %u",
995     getgrgid_count);
996 
997   gr = pr_auth_getgrgid(p, PR_TEST_AUTH_NOGID);
998   fail_unless(gr == NULL, "Found grgid for NOGID unexpectedly");
999   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1000     strerror(errno), errno);
1001 
1002   mark_point();
1003 
1004   gr = pr_auth_getgrgid(p, 5);
1005   fail_unless(gr == NULL, "Found grgid for GID 5 unexpectedly");
1006   fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1007     strerror(errno), errno);
1008 
1009   fail_unless(getgrgid_count == 3, "Expected call count 3, got %u",
1010     getgrgid_count);
1011 
1012   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1013 }
1014 END_TEST
1015 
START_TEST(auth_name2gid_test)1016 START_TEST (auth_name2gid_test) {
1017   int res;
1018   gid_t gid;
1019   authtable authtab;
1020   char *sym_name = "name2gid";
1021 
1022   pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_NAME2GID);
1023 
1024   gid = pr_auth_name2gid(NULL, NULL);
1025   fail_unless(gid == (gid_t) -1, "Found GID unexpectedly");
1026   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1027     errno, strerror(errno));
1028 
1029   gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1030   fail_unless(gid == (gid_t) -1, "Found GID unexpectedly");
1031   fail_unless(name2gid_count == 0, "Expected call count 0, got %u",
1032     name2gid_count);
1033   mark_point();
1034 
1035   /* Load the appropriate AUTH symbol, and call it. */
1036 
1037   memset(&authtab, 0, sizeof(authtab));
1038   authtab.name = sym_name;
1039   authtab.handler = handle_name2gid;
1040   authtab.m = &testsuite_module;
1041   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1042   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1043     strerror(errno));
1044 
1045   mark_point();
1046 
1047   gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1048   fail_unless(gid == PR_TEST_AUTH_GID, "Expected GID %lu, got %lu",
1049     (unsigned long) PR_TEST_AUTH_GID, (unsigned long) gid);
1050   fail_unless(name2gid_count == 1, "Expected call count 1, got %u",
1051     name2gid_count);
1052 
1053   mark_point();
1054 
1055   /* Call again; the call counter should NOT increment due to caching. */
1056 
1057   gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1058   fail_unless(gid == PR_TEST_AUTH_GID, "Expected GID %lu, got %lu",
1059     (unsigned long) PR_TEST_AUTH_GID, (unsigned long) gid);
1060   fail_unless(name2gid_count == 1, "Expected call count 1, got %u",
1061     name2gid_count);
1062 
1063   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1064 }
1065 END_TEST
1066 
START_TEST(auth_gid2name_test)1067 START_TEST (auth_gid2name_test) {
1068   int res;
1069   const char *name;
1070   authtable authtab;
1071   char *sym_name = "gid2name";
1072 
1073   pr_auth_cache_set(FALSE, PR_AUTH_CACHE_FL_BAD_GID2NAME);
1074 
1075   name = pr_auth_gid2name(NULL, -1);
1076   fail_unless(name == NULL, "Found name unexpectedly: %s", name);
1077   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1078     errno, strerror(errno));
1079   mark_point();
1080 
1081   name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1082   fail_unless(name != NULL, "Failed to find name for GID %lu: %s",
1083     (unsigned long) PR_TEST_AUTH_GID, strerror(errno));
1084   fail_unless(strcmp(name, PR_TEST_AUTH_GID_STR) == 0,
1085      "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name);
1086   fail_unless(gid2name_count == 0, "Expected call count 0, got %u",
1087     gid2name_count);
1088   mark_point();
1089 
1090   /* Load the appropriate AUTH symbol, and call it. */
1091 
1092   memset(&authtab, 0, sizeof(authtab));
1093   authtab.name = sym_name;
1094   authtab.handler = handle_gid2name;
1095   authtab.m = &testsuite_module;
1096   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1097   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1098     strerror(errno));
1099 
1100   mark_point();
1101 
1102   name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1103   fail_unless(name != NULL, "Expected name, got null");
1104   fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1105     "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1106   fail_unless(gid2name_count == 1, "Expected call count 1, got %u",
1107     gid2name_count);
1108 
1109   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1110 }
1111 END_TEST
1112 
START_TEST(auth_getgroups_test)1113 START_TEST (auth_getgroups_test) {
1114   int res;
1115   array_header *gids = NULL, *names = NULL;
1116   authtable authtab;
1117   char *sym_name = "getgroups";
1118 
1119   res = pr_auth_getgroups(NULL, NULL, NULL, NULL);
1120   fail_unless(res < 0, "Failed to handle null arguments");
1121   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
1122     errno, strerror(errno));
1123 
1124   res = pr_auth_getgroups(p, PR_TEST_AUTH_NAME, &gids, NULL);
1125   fail_unless(res < 0, "Found groups for '%s' unexpectedly", PR_TEST_AUTH_NAME);
1126   fail_unless(getgroups_count == 0, "Expected call count 0, got %u",
1127     getgroups_count);
1128   mark_point();
1129 
1130   /* Load the appropriate AUTH symbol, and call it. */
1131 
1132   memset(&authtab, 0, sizeof(authtab));
1133   authtab.name = sym_name;
1134   authtab.handler = handle_getgroups;
1135   authtab.m = &testsuite_module;
1136   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1137   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1138     strerror(errno));
1139 
1140   mark_point();
1141 
1142   res = pr_auth_getgroups(p, PR_TEST_AUTH_NAME, &gids, &names);
1143   fail_unless(res > 0, "Expected group count 1 for '%s', got %d: %s",
1144     PR_TEST_AUTH_NAME, res, strerror(errno));
1145   fail_unless(getgroups_count == 1, "Expected call count 1, got %u",
1146     getgroups_count);
1147 
1148   res = pr_auth_getgroups(p, "other", &gids, &names);
1149   fail_unless(res < 0, "Found groups for 'other' unexpectedly");
1150   fail_unless(getgroups_count == 2, "Expected call count 2, got %u",
1151     getgroups_count);
1152 
1153   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1154 }
1155 END_TEST
1156 
START_TEST(auth_cache_uid2name_test)1157 START_TEST (auth_cache_uid2name_test) {
1158   int res;
1159   const char *name;
1160   authtable authtab;
1161   char *sym_name = "uid2name";
1162 
1163   /* Load the appropriate AUTH symbol, and call it. */
1164 
1165   memset(&authtab, 0, sizeof(authtab));
1166   authtab.name = sym_name;
1167   authtab.handler = handle_uid2name;
1168   authtab.m = &testsuite_module;
1169   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1170   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1171     strerror(errno));
1172 
1173   mark_point();
1174 
1175   name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1176   fail_unless(name != NULL, "Expected name, got null");
1177   fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1178     "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1179   fail_unless(uid2name_count == 1, "Expected call count 1, got %u",
1180     uid2name_count);
1181 
1182   /* Call again; the call counter should NOT increment due to caching. */
1183 
1184   name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1185   fail_unless(name != NULL, "Expected name, got null");
1186   fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1187     "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1188   fail_unless(uid2name_count == 1, "Expected call count 1, got %u",
1189     uid2name_count);
1190 
1191   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1192 }
1193 END_TEST
1194 
START_TEST(auth_cache_gid2name_test)1195 START_TEST (auth_cache_gid2name_test) {
1196   int res;
1197   const char *name;
1198   authtable authtab;
1199   char *sym_name = "gid2name";
1200 
1201   /* Load the appropriate AUTH symbol, and call it. */
1202 
1203   memset(&authtab, 0, sizeof(authtab));
1204   authtab.name = sym_name;
1205   authtab.handler = handle_gid2name;
1206   authtab.m = &testsuite_module;
1207   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1208   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1209     strerror(errno));
1210 
1211   mark_point();
1212 
1213   name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1214   fail_unless(name != NULL, "Expected name, got null");
1215   fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1216     "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1217   fail_unless(gid2name_count == 1, "Expected call count 1, got %u",
1218     gid2name_count);
1219 
1220   /* Call again; the call counter should NOT increment due to caching. */
1221 
1222   name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1223   fail_unless(name != NULL, "Expected name, got null");
1224   fail_unless(strcmp(name, PR_TEST_AUTH_NAME) == 0,
1225     "Expected name '%s', got '%s'", PR_TEST_AUTH_NAME, name);
1226   fail_unless(gid2name_count == 1, "Expected call count 1, got %u",
1227     gid2name_count);
1228 
1229   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1230 }
1231 END_TEST
1232 
START_TEST(auth_cache_uid2name_failed_test)1233 START_TEST (auth_cache_uid2name_failed_test) {
1234   int res;
1235   const char *name;
1236   authtable authtab;
1237   char *sym_name = "uid2name";
1238 
1239   /* Load the appropriate AUTH symbol, and call it. */
1240 
1241   memset(&authtab, 0, sizeof(authtab));
1242   authtab.name = sym_name;
1243   authtab.handler = decline_uid2name;
1244   authtab.m = &testsuite_module;
1245   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1246   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1247     strerror(errno));
1248 
1249   mark_point();
1250 
1251   name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1252   fail_unless(name != NULL, "Expected name, got null");
1253   fail_unless(strcmp(name, PR_TEST_AUTH_UID_STR) == 0,
1254     "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name);
1255   fail_unless(uid2name_count == 1, "Expected call count 1, got %u",
1256     uid2name_count);
1257 
1258   /* Call again; the call counter should NOT increment due to caching. */
1259 
1260   name = pr_auth_uid2name(p, PR_TEST_AUTH_UID);
1261   fail_unless(name != NULL, "Expected name, got null");
1262   fail_unless(strcmp(name, PR_TEST_AUTH_UID_STR) == 0,
1263     "Expected name '%s', got '%s'", PR_TEST_AUTH_UID_STR, name);
1264   fail_unless(uid2name_count == 1, "Expected call count 1, got %u",
1265     uid2name_count);
1266 
1267   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1268 }
1269 END_TEST
1270 
START_TEST(auth_cache_gid2name_failed_test)1271 START_TEST (auth_cache_gid2name_failed_test) {
1272   int res;
1273   const char *name;
1274   authtable authtab;
1275   char *sym_name = "gid2name";
1276 
1277   /* Load the appropriate AUTH symbol, and call it. */
1278 
1279   memset(&authtab, 0, sizeof(authtab));
1280   authtab.name = sym_name;
1281   authtab.handler = decline_gid2name;
1282   authtab.m = &testsuite_module;
1283   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1284   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1285     strerror(errno));
1286 
1287   mark_point();
1288 
1289   name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1290   fail_unless(name != NULL, "Expected name, got null");
1291   fail_unless(strcmp(name, PR_TEST_AUTH_GID_STR) == 0,
1292     "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name);
1293   fail_unless(gid2name_count == 1, "Expected call count 1, got %u",
1294     gid2name_count);
1295 
1296   /* Call again; the call counter should NOT increment due to caching. */
1297 
1298   name = pr_auth_gid2name(p, PR_TEST_AUTH_GID);
1299   fail_unless(name != NULL, "Expected name, got null");
1300   fail_unless(strcmp(name, PR_TEST_AUTH_GID_STR) == 0,
1301     "Expected name '%s', got '%s'", PR_TEST_AUTH_GID_STR, name);
1302   fail_unless(gid2name_count == 1, "Expected call count 1, got %u",
1303     gid2name_count);
1304 
1305   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1306 }
1307 END_TEST
1308 
START_TEST(auth_cache_name2uid_failed_test)1309 START_TEST (auth_cache_name2uid_failed_test) {
1310   int res;
1311   uid_t uid;
1312   authtable authtab;
1313   char *sym_name = "name2uid";
1314 
1315   /* Load the appropriate AUTH symbol, and call it. */
1316 
1317   memset(&authtab, 0, sizeof(authtab));
1318   authtab.name = sym_name;
1319   authtab.handler = decline_name2uid;
1320   authtab.m = &testsuite_module;
1321   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1322   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1323     strerror(errno));
1324 
1325   mark_point();
1326 
1327   uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
1328   fail_unless(uid == (uid_t) -1, "Expected -1, got %lu", (unsigned long) uid);
1329   fail_unless(name2uid_count == 1, "Expected call count 1, got %u",
1330     name2uid_count);
1331 
1332   /* Call again; the call counter should NOT increment due to caching. */
1333 
1334   uid = pr_auth_name2uid(p, PR_TEST_AUTH_NAME);
1335   fail_unless(uid == (uid_t) -1, "Expected -1, got %lu", (unsigned long) uid);
1336   fail_unless(name2uid_count == 1, "Expected call count 1, got %u",
1337     name2uid_count);
1338 
1339   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1340 }
1341 END_TEST
1342 
START_TEST(auth_cache_name2gid_failed_test)1343 START_TEST (auth_cache_name2gid_failed_test) {
1344   int res;
1345   gid_t gid;
1346   authtable authtab;
1347   char *sym_name = "name2gid";
1348 
1349   /* Load the appropriate AUTH symbol, and call it. */
1350 
1351   memset(&authtab, 0, sizeof(authtab));
1352   authtab.name = sym_name;
1353   authtab.handler = decline_name2gid;
1354   authtab.m = &testsuite_module;
1355   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1356   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1357     strerror(errno));
1358 
1359   mark_point();
1360 
1361   gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1362   fail_unless(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid);
1363   fail_unless(name2gid_count == 1, "Expected call count 1, got %u",
1364     name2gid_count);
1365 
1366   /* Call again; the call counter should NOT increment due to caching. */
1367 
1368   gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1369   fail_unless(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid);
1370   fail_unless(name2gid_count == 1, "Expected call count 1, got %u",
1371     name2gid_count);
1372 
1373   pr_stash_remove_symbol(PR_SYM_AUTH, sym_name, &testsuite_module);
1374 }
1375 END_TEST
1376 
START_TEST(auth_cache_clear_test)1377 START_TEST (auth_cache_clear_test) {
1378   int res;
1379   gid_t gid;
1380   authtable authtab;
1381   char *sym_name = "name2gid";
1382 
1383   mark_point();
1384   pr_auth_cache_clear();
1385 
1386   /* Load the appropriate AUTH symbol, and call it. */
1387 
1388   memset(&authtab, 0, sizeof(authtab));
1389   authtab.name = sym_name;
1390   authtab.handler = decline_name2gid;
1391   authtab.m = &testsuite_module;
1392   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1393   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1394     strerror(errno));
1395 
1396   mark_point();
1397   gid = pr_auth_name2gid(p, PR_TEST_AUTH_NAME);
1398   fail_unless(gid == (gid_t) -1, "Expected -1, got %lu", (unsigned long) gid);
1399   fail_unless(name2gid_count == 1, "Expected call count 1, got %u",
1400     name2gid_count);
1401 
1402   mark_point();
1403   pr_auth_cache_clear();
1404 }
1405 END_TEST
1406 
START_TEST(auth_cache_set_test)1407 START_TEST (auth_cache_set_test) {
1408   int res;
1409   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;
1410 
1411   res = pr_auth_cache_set(-1, 0);
1412   fail_unless(res < 0, "Failed to handle invalid setting");
1413   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1414     strerror(errno), errno);
1415 
1416   res = pr_auth_cache_set(TRUE, flags);
1417   fail_unless(res == 0, "Failed to enable all auth cache settings: %s",
1418     strerror(errno));
1419 
1420   res = pr_auth_cache_set(FALSE, flags);
1421   fail_unless(res == 0, "Failed to disable all auth cache settings: %s",
1422     strerror(errno));
1423 
1424   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_DEFAULT);
1425 }
1426 END_TEST
1427 
START_TEST(auth_clear_auth_only_module_test)1428 START_TEST (auth_clear_auth_only_module_test) {
1429   int res;
1430 
1431   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1432 
1433   res = pr_auth_clear_auth_only_modules();
1434   fail_unless(res < 0, "Failed to handle no auth module list");
1435   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1436     strerror(errno), errno);
1437 }
1438 END_TEST
1439 
START_TEST(auth_add_auth_only_module_test)1440 START_TEST (auth_add_auth_only_module_test) {
1441   int res;
1442   const char *name = "foo.bar";
1443 
1444   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1445 
1446   res = pr_auth_add_auth_only_module(NULL);
1447   fail_unless(res < 0, "Failed to handle null arguments");
1448   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1449     strerror(errno), errno);
1450 
1451   res = pr_auth_add_auth_only_module(name);
1452   fail_unless(res == 0, "Failed to add auth-only module '%s': %s", name,
1453     strerror(errno));
1454 
1455   res = pr_auth_add_auth_only_module(name);
1456   fail_unless(res < 0, "Failed to handle duplicate auth-only module");
1457   fail_unless(errno == EEXIST, "Expected EEXIST (%d), got %s (%d)", EEXIST,
1458     strerror(errno), errno);
1459 
1460   res = pr_auth_clear_auth_only_modules();
1461   fail_unless(res == 0, "Failed to clear auth-only modules: %s",
1462     strerror(errno));
1463 }
1464 END_TEST
1465 
START_TEST(auth_remove_auth_only_module_test)1466 START_TEST (auth_remove_auth_only_module_test) {
1467   int res;
1468   const char *name = "foo.bar";
1469 
1470   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1471 
1472   res = pr_auth_remove_auth_only_module(NULL);
1473   fail_unless(res < 0, "Failed to handle null arguments");
1474   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1475     strerror(errno), errno);
1476 
1477   res = pr_auth_remove_auth_only_module(name);
1478   fail_unless(res < 0, "Failed to handle empty auth-only module list");
1479   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1480     strerror(errno), errno);
1481 
1482   res = pr_auth_add_auth_only_module(name);
1483   fail_unless(res == 0, "Failed to add auth-only module '%s': %s", name,
1484     strerror(errno));
1485 
1486   res = pr_auth_remove_auth_only_module(name);
1487   fail_unless(res == 0, "Failed to remove auth-only module '%s': %s", name,
1488     strerror(errno));
1489 
1490   (void) pr_auth_clear_auth_only_modules();
1491 }
1492 END_TEST
1493 
START_TEST(auth_authenticate_test)1494 START_TEST (auth_authenticate_test) {
1495   int res;
1496   authtable authtab;
1497   char *sym_name = "auth";
1498 
1499   res = pr_auth_authenticate(NULL, NULL, NULL);
1500   fail_unless(res < 0, "Failed to handle null arguments");
1501   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1502     strerror(errno), errno);
1503 
1504   res = pr_auth_authenticate(p, NULL, NULL);
1505   fail_unless(res < 0, "Failed to handle null name");
1506   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1507     strerror(errno), errno);
1508 
1509   res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, NULL);
1510   fail_unless(res < 0, "Failed to handle null password");
1511   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1512     strerror(errno), errno);
1513 
1514   /* Load the appropriate AUTH symbol, and call it. */
1515 
1516   memset(&authtab, 0, sizeof(authtab));
1517   authtab.name = sym_name;
1518   authtab.handler = handle_authn;
1519   authtab.m = &testsuite_module;
1520   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1521   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1522     strerror(errno));
1523 
1524   res = pr_auth_authenticate(p, "other", "foobar");
1525   fail_unless(res == PR_AUTH_NOPWD,
1526     "Authenticated user 'other' unexpectedly (expected %d, got %d)",
1527     PR_AUTH_NOPWD, res);
1528 
1529   res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, "foobar");
1530   fail_unless(res == PR_AUTH_BADPWD,
1531     "Authenticated user '%s' unexpectedly (expected %d, got %d)",
1532     PR_TEST_AUTH_NAME, PR_AUTH_BADPWD, res);
1533 
1534   res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1535   fail_unless(res == PR_AUTH_OK,
1536     "Failed to authenticate user '%s' (expected %d, got %d)",
1537     PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1538 
1539   authtab.auth_flags |= PR_AUTH_FL_REQUIRED;
1540   res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1541   fail_unless(res == PR_AUTH_OK,
1542     "Failed to authenticate user '%s' (expected %d, got %d)",
1543     PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1544   authtab.auth_flags &= ~PR_AUTH_FL_REQUIRED;
1545 
1546   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1547 
1548   res = pr_auth_add_auth_only_module("foo.bar");
1549   fail_unless(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1550 
1551   res = pr_auth_add_auth_only_module(testsuite_module.name);
1552   fail_unless(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1553 
1554   res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1555   fail_unless(res == PR_AUTH_OK,
1556     "Failed to authenticate user '%s' (expected %d, got %d)",
1557     PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1558 
1559   pr_auth_clear_auth_only_modules();
1560 
1561   authn_rfc2228 = TRUE;
1562   res = pr_auth_authenticate(p, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1563   fail_unless(res == PR_AUTH_RFC2228_OK,
1564     "Failed to authenticate user '%s' (expected %d, got %d)",
1565     PR_TEST_AUTH_NAME, PR_AUTH_RFC2228_OK, res);
1566 }
1567 END_TEST
1568 
START_TEST(auth_authorize_test)1569 START_TEST (auth_authorize_test) {
1570   int res;
1571   authtable authtab;
1572   char *sym_name = "authorize";
1573 
1574   res = pr_auth_authorize(NULL, NULL);
1575   fail_unless(res < 0, "Failed to handle null arguments");
1576   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1577     strerror(errno), errno);
1578 
1579   res = pr_auth_authorize(p, NULL);
1580   fail_unless(res < 0, "Failed to handle null name");
1581   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1582     strerror(errno), errno);
1583 
1584   res = pr_auth_authorize(p, PR_TEST_AUTH_NAME);
1585   fail_unless(res > 0, "Failed to handle missing handler");
1586 
1587   /* Load the appropriate AUTH symbol, and call it. */
1588 
1589   memset(&authtab, 0, sizeof(authtab));
1590   authtab.name = sym_name;
1591   authtab.handler = handle_authz;
1592   authtab.m = &testsuite_module;
1593   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1594   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1595     strerror(errno));
1596 
1597   res = pr_auth_authorize(p, "other");
1598   fail_unless(res == PR_AUTH_NOPWD,
1599     "Authorized user 'other' unexpectedly (expected %d, got %d)",
1600     PR_AUTH_NOPWD, res);
1601 
1602   res = pr_auth_authorize(p, PR_TEST_AUTH_NAME);
1603   fail_unless(res == PR_AUTH_OK,
1604     "Failed to authorize user '%s' (expected %d, got %d)",
1605     PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1606 
1607   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1608 
1609   res = pr_auth_add_auth_only_module("foo.bar");
1610   fail_unless(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1611 
1612   res = pr_auth_add_auth_only_module(testsuite_module.name);
1613   fail_unless(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1614 
1615   res = pr_auth_authorize(p, PR_TEST_AUTH_NAME);
1616   fail_unless(res == PR_AUTH_OK,
1617     "Failed to authorize user '%s' (expected %d, got %d)",
1618     PR_TEST_AUTH_NAME, PR_AUTH_OK, res);
1619 
1620   (void) pr_auth_clear_auth_only_modules();
1621 }
1622 END_TEST
1623 
START_TEST(auth_check_test)1624 START_TEST (auth_check_test) {
1625   int res;
1626   const char *cleartext_passwd, *ciphertext_passwd, *name;
1627   authtable authtab;
1628   char *sym_name = "check";
1629 
1630   res = pr_auth_check(NULL, NULL, NULL, NULL);
1631   fail_unless(res < 0, "Failed to handle null arguments");
1632   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1633     strerror(errno), errno);
1634 
1635   res = pr_auth_check(p, NULL, NULL, NULL);
1636   fail_unless(res < 0, "Failed to handle null name");
1637   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1638     strerror(errno), errno);
1639 
1640   name = PR_TEST_AUTH_NAME;
1641   res = pr_auth_check(p, NULL, name, NULL);
1642   fail_unless(res < 0, "Failed to handle null cleartext password");
1643   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1644     strerror(errno), errno);
1645 
1646   cleartext_passwd = PR_TEST_AUTH_PASSWD;
1647   res = pr_auth_check(p, NULL, name, cleartext_passwd);
1648   fail_unless(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1649     res);
1650 
1651   /* Load the appropriate AUTH symbol, and call it. */
1652 
1653   memset(&authtab, 0, sizeof(authtab));
1654   authtab.name = sym_name;
1655   authtab.handler = handle_check;
1656   authtab.m = &testsuite_module;
1657   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1658   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1659     strerror(errno));
1660 
1661   res = pr_auth_check(p, NULL, "other", cleartext_passwd);
1662   fail_unless(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1663     res);
1664 
1665   res = pr_auth_check(p, "foo", name, cleartext_passwd);
1666   fail_unless(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1667     res);
1668 
1669   res = pr_auth_check(p, NULL, name, cleartext_passwd);
1670   fail_unless(res == PR_AUTH_BADPWD, "Expected %d, got %d", PR_AUTH_BADPWD,
1671     res);
1672 
1673   ciphertext_passwd = PR_TEST_AUTH_PASSWD;
1674   res = pr_auth_check(p, ciphertext_passwd, name, cleartext_passwd);
1675   fail_unless(res == PR_AUTH_OK, "Expected %d, got %d", PR_AUTH_OK, res);
1676 
1677   (void) pr_auth_cache_set(TRUE, PR_AUTH_CACHE_FL_AUTH_MODULE);
1678 
1679   res = pr_auth_add_auth_only_module("foo.bar");
1680   fail_unless(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1681 
1682   res = pr_auth_add_auth_only_module(testsuite_module.name);
1683   fail_unless(res == 0, "Failed to add auth-only module: %s", strerror(errno));
1684 
1685   check_rfc2228 = TRUE;
1686   res = pr_auth_check(p, ciphertext_passwd, name, cleartext_passwd);
1687   fail_unless(res == PR_AUTH_RFC2228_OK,
1688     "Failed to check user '%s' (expected %d, got %d)", name,
1689     PR_AUTH_RFC2228_OK, res);
1690 
1691   (void) pr_auth_clear_auth_only_modules();
1692 }
1693 END_TEST
1694 
START_TEST(auth_requires_pass_test)1695 START_TEST (auth_requires_pass_test) {
1696   int res;
1697   const char *name;
1698   authtable authtab;
1699   char *sym_name = "requires_pass";
1700 
1701   res = pr_auth_requires_pass(NULL, NULL);
1702   fail_unless(res < 0, "Failed to handle null arguments");
1703   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1704     strerror(errno), errno);
1705 
1706   res = pr_auth_requires_pass(p, NULL);
1707   fail_unless(res < 0, "Failed to handle null name");
1708   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1709     strerror(errno), errno);
1710 
1711   name = "other";
1712   res = pr_auth_requires_pass(p, name);
1713   fail_unless(res == TRUE, "Unknown users should require passwords (got %d)",
1714     res);
1715 
1716   /* Load the appropriate AUTH symbol, and call it. */
1717 
1718   memset(&authtab, 0, sizeof(authtab));
1719   authtab.name = sym_name;
1720   authtab.handler = handle_requires_pass;
1721   authtab.m = &testsuite_module;
1722   res = pr_stash_add_symbol(PR_SYM_AUTH, &authtab);
1723   fail_unless(res == 0, "Failed to add '%s' AUTH symbol: %s", sym_name,
1724     strerror(errno));
1725 
1726   res = pr_auth_requires_pass(p, name);
1727   fail_unless(res == TRUE, "Unknown users should require passwords (got %d)",
1728     res);
1729 
1730   name = PR_TEST_AUTH_NAME;
1731   res = pr_auth_requires_pass(p, name);
1732   fail_unless(res == FALSE, "Known users should NOT require passwords (got %d)",
1733     res);
1734 }
1735 END_TEST
1736 
START_TEST(auth_get_anon_config_test)1737 START_TEST (auth_get_anon_config_test) {
1738   config_rec *c;
1739 
1740   c = pr_auth_get_anon_config(NULL, NULL, NULL, NULL);
1741   fail_unless(c == NULL, "Failed to handle null arguments");
1742 
1743   /* XXX Need to exercise more of this function. */
1744 }
1745 END_TEST
1746 
START_TEST(auth_chroot_test)1747 START_TEST (auth_chroot_test) {
1748   int res;
1749   const char *path;
1750 
1751   res = pr_auth_chroot(NULL);
1752   fail_unless(res < 0, "Failed to handle null argument");
1753   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1754     strerror(errno), errno);
1755 
1756   path = "tmp";
1757   res = pr_auth_chroot(path);
1758   fail_unless(res < 0, "Failed to chroot to '%s': %s", path, strerror(errno));
1759   fail_unless(errno == EINVAL || errno == ENOENT,
1760     "Expected EINVAL (%d) or ENOENT (%d), got %s (%d)", EINVAL, ENOENT,
1761     strerror(errno), errno);
1762 
1763   path = "/tmp";
1764   res = pr_auth_chroot(path);
1765   fail_unless(res < 0, "Failed to chroot to '%s': %s", path, strerror(errno));
1766   fail_unless(errno == ENOENT || errno == EPERM || errno == EINVAL,
1767     "Expected ENOENT (%d), EPERM (%d) or EINVAL (%d), got %s (%d)",
1768     ENOENT, EPERM, EINVAL, strerror(errno), errno);
1769 }
1770 END_TEST
1771 
START_TEST(auth_banned_by_ftpusers_test)1772 START_TEST (auth_banned_by_ftpusers_test) {
1773   const char *name;
1774   int res;
1775   xaset_t *ctx;
1776 
1777   res = pr_auth_banned_by_ftpusers(NULL, NULL);
1778   fail_unless(res == FALSE, "Failed to handle null arguments");
1779 
1780   ctx = xaset_create(p, NULL);
1781   res = pr_auth_banned_by_ftpusers(ctx, NULL);
1782   fail_unless(res == FALSE, "Failed to handle null user");
1783 
1784   name = "testsuite";
1785   res = pr_auth_banned_by_ftpusers(ctx, name);
1786   fail_unless(res == FALSE, "Expected FALSE, got %d", res);
1787 }
1788 END_TEST
1789 
START_TEST(auth_is_valid_shell_test)1790 START_TEST (auth_is_valid_shell_test) {
1791   const char *shell;
1792   int res;
1793   xaset_t *ctx;
1794 
1795   res = pr_auth_is_valid_shell(NULL, NULL);
1796   fail_unless(res == TRUE, "Failed to handle null arguments");
1797 
1798   ctx = xaset_create(p, NULL);
1799   res = pr_auth_is_valid_shell(ctx, NULL);
1800   fail_unless(res == TRUE, "Failed to handle null shell");
1801 
1802   shell = "/foo/bar";
1803   res = pr_auth_is_valid_shell(ctx, shell);
1804   fail_unless(res == FALSE, "Failed to handle invalid shell '%s' (got %d)",
1805     shell, res);
1806 
1807   shell = "/bin/sh";
1808   res = pr_auth_is_valid_shell(ctx, shell);
1809   fail_unless(res == TRUE, "Failed to handle valid shell '%s' (got %d)",
1810     shell, res);
1811 }
1812 END_TEST
1813 
START_TEST(auth_get_home_test)1814 START_TEST (auth_get_home_test) {
1815   const char *home, *res;
1816 
1817   res = pr_auth_get_home(NULL, NULL);
1818   fail_unless(res == NULL, "Failed to handle null arguments");
1819   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1820     strerror(errno), errno);
1821 
1822   res = pr_auth_get_home(p, NULL);
1823   fail_unless(res == NULL, "Failed to handle null home");
1824   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1825     strerror(errno), errno);
1826 
1827   home = "/testsuite";
1828   res = pr_auth_get_home(p, home);
1829   fail_unless(res != NULL, "Failed to get home: %s", strerror(errno));
1830   fail_unless(strcmp(home, res) == 0, "Expected '%s', got '%s'", home, res);
1831 }
1832 END_TEST
1833 
START_TEST(auth_set_max_password_len_test)1834 START_TEST (auth_set_max_password_len_test) {
1835   int checked;
1836   size_t res;
1837 
1838   res = pr_auth_set_max_password_len(p, 1);
1839   fail_unless(res == PR_TUNABLE_PASSWORD_MAX,
1840     "Expected %lu, got %lu", (unsigned long) PR_TUNABLE_PASSWORD_MAX,
1841     (unsigned long) res);
1842 
1843   checked = pr_auth_check(p, NULL, PR_TEST_AUTH_NAME, PR_TEST_AUTH_PASSWD);
1844   fail_unless(checked < 0, "Failed to reject too-long password");
1845   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
1846     strerror(errno), errno);
1847 
1848   res = pr_auth_set_max_password_len(p, 0);
1849   fail_unless(res == 1, "Expected %lu, got %lu", 1, (unsigned long) res);
1850 
1851   res = pr_auth_set_max_password_len(p, 0);
1852   fail_unless(res == PR_TUNABLE_PASSWORD_MAX,
1853     "Expected %lu, got %lu", (unsigned long) PR_TUNABLE_PASSWORD_MAX,
1854     (unsigned long) res);
1855 }
1856 END_TEST
1857 
START_TEST(auth_bcrypt_test)1858 START_TEST (auth_bcrypt_test) {
1859   char *res;
1860   size_t hashed_len;
1861 
1862   res = pr_auth_bcrypt(NULL, NULL, NULL, NULL);
1863   fail_unless(res == NULL, "Failed to handle null pool argument");
1864   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1865     strerror(errno), errno);
1866 
1867   res = pr_auth_bcrypt(p, NULL, NULL, NULL);
1868   fail_unless(res == NULL, "Failed to handle null key argument");
1869   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1870     strerror(errno), errno);
1871 
1872   res = pr_auth_bcrypt(p, "", NULL, NULL);
1873   fail_unless(res == NULL, "Failed to handle null salt argument");
1874   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1875     strerror(errno), errno);
1876 
1877   res = pr_auth_bcrypt(p, "", "", NULL);
1878   fail_unless(res == NULL, "Failed to handle null hashed_len argument");
1879   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1880     strerror(errno), errno);
1881 
1882   res = pr_auth_bcrypt(p, "", "", &hashed_len);
1883   fail_unless(res == NULL, "Failed to handle empty strings");
1884   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1885     strerror(errno), errno);
1886 
1887   res = pr_auth_bcrypt(p, "foo", "$1", &hashed_len);
1888   fail_unless(res == NULL, "Failed to handle invalid salt");
1889   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
1890     strerror(errno), errno);
1891 
1892   /* TODO: Add more tests of the invalid salt constructions: bcrypt version
1893    * numbers, rounds, salt too short, etc.
1894    */
1895 
1896   res = pr_auth_bcrypt(p, "password",
1897     "$2b$12$IoFxXvbRQUKssPqFacJFFuZl1KXl5ULppqf0aLFjwCFnLRh3NbYSG",
1898     &hashed_len);
1899   fail_unless(res != NULL, "Failed to handle valid key and salt");
1900 }
1901 END_TEST
1902 
tests_get_auth_suite(void)1903 Suite *tests_get_auth_suite(void) {
1904   Suite *suite;
1905   TCase *testcase;
1906 
1907   suite = suite_create("auth");
1908 
1909   testcase = tcase_create("base");
1910   tcase_add_checked_fixture(testcase, set_up, tear_down);
1911 
1912   /* pwent* et al */
1913   tcase_add_test(testcase, auth_setpwent_test);
1914   tcase_add_test(testcase, auth_endpwent_test);
1915   tcase_add_test(testcase, auth_getpwent_test);
1916   tcase_add_test(testcase, auth_getpwnam_test);
1917   tcase_add_test(testcase, auth_getpwuid_test);
1918   tcase_add_test(testcase, auth_name2uid_test);
1919   tcase_add_test(testcase, auth_uid2name_test);
1920 
1921   /* grent* et al */
1922   tcase_add_test(testcase, auth_setgrent_test);
1923   tcase_add_test(testcase, auth_endgrent_test);
1924   tcase_add_test(testcase, auth_getgrent_test);
1925   tcase_add_test(testcase, auth_getgrnam_test);
1926   tcase_add_test(testcase, auth_getgrgid_test);
1927   tcase_add_test(testcase, auth_gid2name_test);
1928   tcase_add_test(testcase, auth_name2gid_test);
1929   tcase_add_test(testcase, auth_getgroups_test);
1930 
1931   /* Caching tests */
1932   tcase_add_test(testcase, auth_cache_uid2name_test);
1933   tcase_add_test(testcase, auth_cache_gid2name_test);
1934   tcase_add_test(testcase, auth_cache_uid2name_failed_test);
1935   tcase_add_test(testcase, auth_cache_gid2name_failed_test);
1936   tcase_add_test(testcase, auth_cache_name2uid_failed_test);
1937   tcase_add_test(testcase, auth_cache_name2gid_failed_test);
1938   tcase_add_test(testcase, auth_cache_clear_test);
1939   tcase_add_test(testcase, auth_cache_set_test);
1940 
1941   /* Auth modules */
1942   tcase_add_test(testcase, auth_clear_auth_only_module_test);
1943   tcase_add_test(testcase, auth_add_auth_only_module_test);
1944   tcase_add_test(testcase, auth_remove_auth_only_module_test);
1945 
1946   /* Authorization */
1947   tcase_add_test(testcase, auth_authenticate_test);
1948   tcase_add_test(testcase, auth_authorize_test);
1949   tcase_add_test(testcase, auth_check_test);
1950   tcase_add_test(testcase, auth_requires_pass_test);
1951 
1952   /* Misc */
1953   tcase_add_test(testcase, auth_get_anon_config_test);
1954   tcase_add_test(testcase, auth_chroot_test);
1955   tcase_add_test(testcase, auth_banned_by_ftpusers_test);
1956   tcase_add_test(testcase, auth_is_valid_shell_test);
1957   tcase_add_test(testcase, auth_get_home_test);
1958   tcase_add_test(testcase, auth_set_max_password_len_test);
1959   tcase_add_test(testcase, auth_bcrypt_test);
1960 
1961   suite_add_tcase(suite, testcase);
1962   return suite;
1963 }
1964