LCOV - code coverage report
Current view: top level - tests/cwrap - test_wrapper_pam_sss.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 190 210 90.5 %
Date: 2015-10-19 Functions: 22 22 100.0 %

          Line data    Source code
       1             : /*
       2             :     Copyright (C) 2015 Red Hat
       3             : 
       4             :     SSSD tests: PAM tests
       5             : 
       6             :     This program is free software; you can redistribute it and/or modify
       7             :     it under the terms of the GNU General Public License as published by
       8             :     the Free Software Foundation; either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     This program is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :     GNU General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU General Public License
      17             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include <popt.h>
      21             : #include <libpamtest.h>
      22             : 
      23             : #include "util/util.h"
      24             : #include "tests/cmocka/common_mock.h"
      25             : 
      26          14 : static void assert_pam_test(enum pamtest_err perr,
      27             :                             const enum pamtest_err perr_exp,
      28             :                             struct pamtest_case *tests)
      29             : {
      30             :     const struct pamtest_case *tc;
      31             : 
      32          14 :     if (perr != perr_exp) {
      33           0 :         tc = pamtest_failed_case(tests);
      34           0 :         if (tc == NULL) {
      35             :             /* Probably pam_start/pam_end failed..*/
      36           0 :             fail_msg("PAM test with pamtest err %d\n", perr);
      37             :         }
      38             : 
      39             :         /* FIXME - would be nice to print index..*/
      40           0 :         fail_msg("PAM test expected %d returned %d\n",
      41             :                  tc->expected_rv, tc->op_rv);
      42             :     }
      43          14 : }
      44             : 
      45           6 : static char *service_arg(TALLOC_CTX *mem_ctx,
      46             :                          const char *src_file,
      47             :                          const char *dst_file,
      48             :                          const char *arg)
      49             : {
      50             :     TALLOC_CTX *tmp_ctx;
      51             :     const char *dir;
      52             :     char *dst;
      53             :     char *src;
      54             :     errno_t ret;
      55             :     struct stat sb;
      56             :     char *svc;
      57           6 :     int src_fd = -1;
      58           6 :     FILE *dst_f = NULL;
      59             :     ssize_t nb;
      60             :     char *line;
      61           6 :     size_t nlines = 0;
      62             :     size_t i;
      63             : 
      64           6 :     dir = getenv("PWRAP_TEST_CONF_DIR");
      65           6 :     if (dir == NULL) {
      66           0 :         return NULL;
      67             :     }
      68             : 
      69           6 :     tmp_ctx = talloc_new(NULL);
      70           6 :     if (tmp_ctx == NULL) {
      71           0 :         return NULL;
      72             :     }
      73             : 
      74           6 :     src = talloc_asprintf(tmp_ctx, "%s/%s", dir, src_file);
      75           6 :     dst = talloc_asprintf(tmp_ctx, "%s/%s", dir, dst_file);
      76           6 :     if (dst == NULL || src == NULL) {
      77             :         goto fail;
      78             :     }
      79             : 
      80           6 :     ret = stat(src, &sb);
      81           6 :     if (ret == -1) {
      82           0 :         goto fail;
      83             :     }
      84             : 
      85           6 :     svc = talloc_size(tmp_ctx, sb.st_size); /* This is OK, the file is small..*/
      86           6 :     if (svc == NULL) {
      87           0 :         goto fail;
      88             :     }
      89             : 
      90           6 :     src_fd = open(src, O_RDONLY);
      91           6 :     if (src_fd == -1) {
      92           0 :         goto fail;
      93             :     }
      94             : 
      95           6 :     dst_f = fopen(dst, "w");
      96           6 :     if (dst_f == NULL) {
      97           0 :         goto fail;
      98             :     }
      99             : 
     100           6 :     nb = sss_atomic_read_s(src_fd, svc, sb.st_size);
     101           6 :     if (nb < sb.st_size) {
     102           0 :         goto fail;
     103             :     }
     104             : 
     105           6 :     line = strchr(svc, '\n');
     106          33 :     while (line != NULL) {
     107          21 :         *line = '\0';
     108          21 :         line++;
     109          21 :         nlines++;
     110             : 
     111          21 :         line = strchr(line, '\n');
     112             :     }
     113             : 
     114           6 :     line = svc;
     115          27 :     for (i = 0; i < nlines; i++) {
     116          21 :         nb = fprintf(dst_f, "%s %s\n", line, arg);
     117          21 :         if (nb < 0) {
     118           0 :             goto fail;
     119             :         }
     120          21 :         line += strlen(line) + 1;
     121             :     }
     122             : 
     123           6 :     ret = EOK;
     124           6 :     fflush(dst_f);
     125           6 :     fclose(dst_f);
     126           6 :     talloc_steal(mem_ctx, dst);
     127           6 :     return dst;
     128             : fail:
     129           0 :     if (dst_f) {
     130           0 :         fclose(dst_f);
     131             :     }
     132           0 :     talloc_free(tmp_ctx);
     133           0 :     return NULL;
     134             : }
     135             : 
     136             : struct test_svc {
     137             :     const char *svc_file;
     138             : };
     139             : 
     140           6 : static const char *find_string_in_list(char **list, const char *key)
     141           6 : {
     142           6 :     char key_eq[strlen(key)+1+1]; /* trailing NULL and '=' */
     143             : 
     144           6 :     if (list == NULL || key == NULL) {
     145           2 :         return NULL;
     146             :     }
     147             : 
     148           4 :     snprintf(key_eq, sizeof(key_eq), "%s=", key);
     149           6 :     for (size_t i = 0; list[i] != NULL; i++) {
     150           5 :         if (strncmp(list[i], key_eq, sizeof(key_eq)-1) == 0) {
     151           3 :             return list[i] + sizeof(key_eq)-1;
     152             :         }
     153             :     }
     154             : 
     155           1 :     return NULL;
     156             : }
     157             : 
     158           3 : static void assert_in_env(struct pamtest_case *test,
     159             :                           const char *key,
     160             :                           const char *val)
     161             : {
     162             :     const char *v;
     163             : 
     164           3 :     v = find_string_in_list(test->case_out.envlist, key);
     165           3 :     assert_non_null(v);
     166           3 :     assert_string_equal(v, val);
     167           3 : }
     168             : 
     169           3 : static void assert_not_in_env(struct pamtest_case *test,
     170             :                               const char *key)
     171             : {
     172             :     const char *v;
     173             : 
     174           3 :     v = find_string_in_list(test->case_out.envlist, key);
     175           3 :     assert_null(v);
     176           3 : }
     177             : 
     178           6 : static int setup_svc(void **state)
     179             : {
     180             :     struct test_svc *svc;
     181             : 
     182           6 :     svc = talloc_zero(NULL, struct test_svc);
     183           6 :     if (svc == NULL) {
     184           0 :         return 1;
     185             :     }
     186             : 
     187           6 :     *state = svc;
     188           6 :     return 0;
     189             : }
     190             : 
     191           6 : static int teardown_svc(void **state)
     192             : {
     193           6 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     194             : 
     195           6 :     if (svc != NULL && svc->svc_file != NULL) {
     196           6 :         unlink(svc->svc_file);
     197             :     }
     198           6 :     return 0;
     199             : }
     200             : 
     201           2 : static void test_pam_authenticate(void **state)
     202             : {
     203             :     enum pamtest_err perr;
     204             :     const char *v;
     205           2 :     const char *testuser_authtoks[] = {
     206             :         "secret",
     207             :         NULL,
     208             :     };
     209           2 :     struct pamtest_case tests[] = {
     210             :         { PAMTEST_AUTHENTICATE, PAM_SUCCESS, 0, 0 },
     211             :         { PAMTEST_SETCRED, PAM_SUCCESS, 0, 0 },
     212             :         { PAMTEST_GETENVLIST, PAM_SUCCESS, 0, 0 },
     213             :         { PAMTEST_OPEN_SESSION, PAM_SUCCESS, 0, 0 },
     214             :         { PAMTEST_GETENVLIST, PAM_SUCCESS, 0, 0 },
     215             :         { PAMTEST_CLOSE_SESSION, PAM_SUCCESS, 0, 0 },
     216             :         { PAMTEST_GETENVLIST, PAM_SUCCESS, 0, 0 },
     217             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     218             :     };
     219             : 
     220             :     (void) state;       /* unused */
     221             : 
     222           2 :     perr = pamtest("test_pam_sss", "testuser", testuser_authtoks, tests);
     223           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     224             : 
     225           1 :     assert_not_in_env(&tests[0], "CREDS");
     226           1 :     assert_not_in_env(&tests[0], "SESSION");
     227             : 
     228           1 :     assert_in_env(&tests[2], "CREDS", "set");
     229           1 :     assert_not_in_env(&tests[2], "SESSION");
     230             : 
     231           1 :     assert_in_env(&tests[4], "CREDS", "set");
     232           1 :     assert_in_env(&tests[4], "SESSION", "open");
     233           1 : }
     234             : 
     235           1 : static void test_pam_authenticate_err(void **state)
     236             : {
     237             :     enum pamtest_err perr;
     238           1 :     const char *testuser_authtoks[] = {
     239             :         "wrong_secret",
     240             :         NULL,
     241             :     };
     242           1 :     struct pamtest_case tests[] = {
     243             :         { PAMTEST_AUTHENTICATE, PAM_AUTH_ERR, 0, 0 },
     244             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     245             :     };
     246             : 
     247             :     (void) state;       /* unused */
     248             : 
     249           1 :     perr = pamtest("test_pam_sss", "testuser", testuser_authtoks, tests);
     250           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     251           1 : }
     252             : 
     253           1 : static void test_pam_acct(void **state)
     254             : {
     255             :     enum pamtest_err perr;
     256           1 :     struct pamtest_case tests[] = {
     257             :         { PAMTEST_ACCOUNT, PAM_SUCCESS, 0, 0 },
     258             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     259             :     };
     260             : 
     261             :     (void) state;       /* unused */
     262             : 
     263           1 :     perr = pamtest("test_pam_sss", "allowed_user", NULL, tests);
     264           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     265           1 : }
     266             : 
     267           1 : static void test_pam_acct_err(void **state)
     268             : {
     269             :     enum pamtest_err perr;
     270           1 :     struct pamtest_case tests[] = {
     271             :         { PAMTEST_ACCOUNT, PAM_PERM_DENIED, 0, 0 },
     272             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     273             :     };
     274             : 
     275             :     (void) state;       /* unused */
     276             : 
     277           1 :     perr = pamtest("test_pam_sss", "denied_user", NULL, tests);
     278           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     279           1 : }
     280             : 
     281           1 : static void test_pam_chauthtok(void **state)
     282             : {
     283             :     enum pamtest_err perr;
     284           1 :     const char *testuser_authtoks[] = {
     285             :         "secret",
     286             :         "new_secret",
     287             :         "new_secret",
     288             :         NULL,
     289             :     };
     290           1 :     struct pamtest_case tests[] = {
     291             :         { PAMTEST_CHAUTHTOK, PAM_SUCCESS, 0, 0 },
     292             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     293             :     };
     294             : 
     295             :     (void) state;       /* unused */
     296             : 
     297           1 :     perr = pamtest("test_pam_sss", "testuser", testuser_authtoks, tests);
     298           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     299           1 : }
     300             : 
     301           1 : static void test_pam_chauthtok_prelim_fail(void **state)
     302             : {
     303             :     enum pamtest_err perr;
     304           1 :     const char *testuser_authtoks[] = {
     305             :         "wrong_secret",
     306             :         NULL,
     307             :     };
     308           1 :     struct pamtest_case tests[] = {
     309             :         { PAMTEST_CHAUTHTOK, PAM_AUTH_ERR, 0, 0 },
     310             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     311             :     };
     312             : 
     313             :     (void) state;       /* unused */
     314             : 
     315           1 :     perr = pamtest("test_pam_sss", "testuser", testuser_authtoks, tests);
     316           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     317           1 : }
     318             : 
     319           1 : static void test_pam_chauthtok_diff_authtoks(void **state)
     320             : {
     321             :     enum pamtest_err perr;
     322           1 :     const char *testuser_authtoks[] = {
     323             :         "secret",
     324             :         "new_secret",
     325             :         "different_secret",
     326             :         NULL,
     327             :     };
     328           1 :     struct pamtest_case tests[] = {
     329             :         { PAMTEST_CHAUTHTOK, PAM_CRED_ERR, 0, 0 },
     330             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     331             :     };
     332             : 
     333             :     (void) state;       /* unused */
     334             : 
     335           1 :     perr = pamtest("test_pam_sss", "testuser", testuser_authtoks, tests);
     336           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     337           1 : }
     338             : 
     339           1 : static void test_pam_authenticate_root(void **state)
     340             : {
     341             :     enum pamtest_err perr;
     342           1 :     struct pamtest_case tests[] = {
     343             :         { PAMTEST_AUTHENTICATE, PAM_USER_UNKNOWN, 0, 0 },
     344             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     345             :     };
     346             : 
     347             :     (void) state;       /* unused */
     348             : 
     349           1 :     perr = pamtest("test_pam_sss_ignore", "root", NULL, tests);
     350           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     351           1 : }
     352             : 
     353           1 : static void test_pam_authenticate_root_ignore(void **state)
     354             : {
     355           1 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     356             :     enum pamtest_err perr;
     357           1 :     struct pamtest_case tests[] = {
     358             :         { PAMTEST_AUTHENTICATE, PAM_IGNORE, 0, 0 },
     359             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     360             :     };
     361           1 :     const char *svcname = "test_pam_sss_ignore_arg";
     362             : 
     363             :     /* Copy file from the previous test and just add an argument. The retval
     364             :      * will be different this time
     365             :      */
     366           1 :     svc->svc_file = service_arg(svc, "test_pam_sss_ignore",
     367             :                                 svcname, "ignore_unknown_user");
     368           1 :     assert_non_null(svc->svc_file);
     369             : 
     370           1 :     perr = pamtest(svcname, "root", NULL, tests);
     371           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     372           1 : }
     373             : 
     374           1 : static void test_pam_authenticate_domains(void **state)
     375             : {
     376           1 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     377             :     enum pamtest_err perr;
     378           1 :     const char *authtoks[] = {
     379             :         "secret",
     380             :         NULL,
     381             :     };
     382           1 :     struct pamtest_case tests[] = {
     383             :         { PAMTEST_AUTHENTICATE, PAM_SUCCESS, 0, 0 },
     384             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     385             :     };
     386           1 :     const char *svcname = "test_pam_sss_domains";
     387             : 
     388             :     /* Copy file from the previous test and just add an argument. The retval
     389             :      * will be different this time
     390             :      */
     391           1 :     svc->svc_file = service_arg(svc, "test_pam_sss",
     392             :                                 svcname, "domains=mydomain");
     393           1 :     assert_non_null(svc->svc_file);
     394             : 
     395           1 :     perr = pamtest(svcname, "domtest", authtoks, tests);
     396           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     397           1 : }
     398             : 
     399           1 : static void test_pam_authenticate_domains_err(void **state)
     400             : {
     401           1 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     402             :     enum pamtest_err perr;
     403           1 :     struct pamtest_case tests[] = {
     404             :         { PAMTEST_AUTHENTICATE, PAM_SYSTEM_ERR, 0, 0 },
     405             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     406             :     };
     407           1 :     const char *svcname = "test_pam_sss_domains_err";
     408             : 
     409             :     /* Copy file from the previous test and just add an argument. The retval
     410             :      * will be different this time
     411             :      */
     412           1 :     svc->svc_file = service_arg(svc, "test_pam_sss",
     413             :                                 svcname, "domains=");
     414           1 :     assert_non_null(svc->svc_file);
     415             : 
     416           1 :     perr = pamtest(svcname, "domtest", NULL, tests);
     417           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     418           1 : }
     419             : 
     420           1 : static void test_pam_authenticate_retry(void **state)
     421             : {
     422           1 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     423             :     enum pamtest_err perr;
     424           1 :     const char *authtoks[] = {
     425             :         "wrong_secret",
     426             :         "retried_secret",
     427             :         NULL,
     428             :     };
     429           1 :     struct pamtest_case tests[] = {
     430             :         { PAMTEST_AUTHENTICATE, PAM_SUCCESS, 0, 0 },
     431             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     432             :     };
     433           1 :     const char *svcname = "test_pam_sss_retry";
     434             : 
     435             :     /* Copy file from the previous test and just add an argument. The retval
     436             :      * will be different this time
     437             :      */
     438           1 :     svc->svc_file = service_arg(svc, "test_pam_sss",
     439             :                                 svcname, "retry=1");
     440           1 :     assert_non_null(svc->svc_file);
     441             : 
     442           1 :     perr = pamtest(svcname, "retrytest", authtoks, tests);
     443           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     444           1 : }
     445             : 
     446           1 : static void test_pam_authenticate_retry_neg(void **state)
     447             : {
     448           1 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     449             :     enum pamtest_err perr;
     450           1 :     const char *authtoks[] = {
     451             :         "wrong_secret",
     452             :         "retried_secret",
     453             :         NULL,
     454             :     };
     455           1 :     struct pamtest_case tests[] = {
     456             :         { PAMTEST_AUTHENTICATE, PAM_AUTH_ERR, 0, 0 },
     457             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     458             :     };
     459           1 :     const char *svcname = "test_pam_sss_retry";
     460             : 
     461             :     /* Copy file from the previous test and just add an argument. The retval
     462             :      * will be different this time
     463             :      */
     464           1 :     svc->svc_file = service_arg(svc, "test_pam_sss",
     465             :                                 svcname, "retry=-1");
     466           1 :     assert_non_null(svc->svc_file);
     467             : 
     468           1 :     perr = pamtest(svcname, "retrytest", authtoks, tests);
     469           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     470           1 : }
     471             : 
     472           1 : static void test_pam_authenticate_retry_eparse(void **state)
     473             : {
     474           1 :     struct test_svc *svc = talloc_get_type(*state, struct test_svc);
     475             :     enum pamtest_err perr;
     476           1 :     const char *authtoks[] = {
     477             :         "wrong_secret",
     478             :         "retried_secret",
     479             :         NULL,
     480             :     };
     481           1 :     struct pamtest_case tests[] = {
     482             :         { PAMTEST_AUTHENTICATE, PAM_AUTH_ERR, 0, 0 },
     483             :         { PAMTEST_SENTINEL, 0, 0, 0 },
     484             :     };
     485           1 :     const char *svcname = "test_pam_sss_retry";
     486             : 
     487             :     /* Copy file from the previous test and just add an argument. The retval
     488             :      * will be different this time
     489             :      */
     490           1 :     svc->svc_file = service_arg(svc, "test_pam_sss",
     491             :                                 svcname, "retry=");
     492           1 :     assert_non_null(svc->svc_file);
     493             : 
     494           1 :     perr = pamtest(svcname, "retrytest", authtoks, tests);
     495           1 :     assert_pam_test(perr, PAMTEST_ERR_OK, tests);
     496           1 : }
     497             : 
     498           2 : int main(int argc, const char *argv[])
     499             : {
     500             :     poptContext pc;
     501             :     int opt;
     502          12 :     struct poptOption long_options[] = {
     503             :         POPT_AUTOHELP
     504          10 :         SSSD_DEBUG_OPTS
     505             :         POPT_TABLEEND
     506             :     };
     507             : 
     508           2 :     const struct CMUnitTest tests[] = {
     509             :         cmocka_unit_test(test_pam_authenticate),
     510             :         cmocka_unit_test(test_pam_authenticate_err),
     511             :         cmocka_unit_test(test_pam_acct),
     512             :         cmocka_unit_test(test_pam_acct_err),
     513             :         cmocka_unit_test(test_pam_chauthtok),
     514             :         cmocka_unit_test(test_pam_chauthtok_prelim_fail),
     515             :         cmocka_unit_test(test_pam_chauthtok_diff_authtoks),
     516             :         cmocka_unit_test(test_pam_authenticate_root),
     517             :         cmocka_unit_test_setup_teardown(test_pam_authenticate_root_ignore,
     518             :                                         setup_svc,
     519             :                                         teardown_svc),
     520             :         cmocka_unit_test_setup_teardown(test_pam_authenticate_domains,
     521             :                                         setup_svc,
     522             :                                         teardown_svc),
     523             :         cmocka_unit_test_setup_teardown(test_pam_authenticate_domains_err,
     524             :                                         setup_svc,
     525             :                                         teardown_svc),
     526             :         cmocka_unit_test_setup_teardown(test_pam_authenticate_retry,
     527             :                                         setup_svc,
     528             :                                         teardown_svc),
     529             :         cmocka_unit_test_setup_teardown(test_pam_authenticate_retry_neg,
     530             :                                         setup_svc,
     531             :                                         teardown_svc),
     532             :         cmocka_unit_test_setup_teardown(test_pam_authenticate_retry_eparse,
     533             :                                         setup_svc,
     534             :                                         teardown_svc),
     535             :     };
     536             : 
     537             :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     538           2 :     debug_level = SSSDBG_INVALID;
     539             : 
     540           2 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     541           2 :     while((opt = poptGetNextOpt(pc)) != -1) {
     542             :         switch(opt) {
     543             :         default:
     544           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     545             :                     poptBadOption(pc, 0), poptStrerror(opt));
     546           0 :             poptPrintUsage(pc, stderr, 0);
     547           0 :             return 1;
     548             :         }
     549             :     }
     550           2 :     poptFreeContext(pc);
     551             : 
     552           2 :     DEBUG_CLI_INIT(debug_level);
     553           2 :     tests_set_cwd();
     554             : 
     555           2 :     setenv("PAM_WRAPPER", "1", 1);
     556           2 :     return cmocka_run_group_tests(tests, NULL, NULL);
     557             : }

Generated by: LCOV version 1.10