LCOV - code coverage report
Current view: top level - tests - krb5_utils-tests.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 340 420 81.0 %
Date: 2015-10-19 Functions: 27 30 90.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Kerberos 5 Backend Module -- Utilities tests
       5             : 
       6             :     Authors:
       7             :         Sumit Bose <sbose@redhat.com>
       8             : 
       9             :     Copyright (C) 2009 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include <stdlib.h>
      26             : #include <popt.h>
      27             : #include <check.h>
      28             : 
      29             : #include "providers/krb5/krb5_utils.h"
      30             : #include "providers/krb5/krb5_ccache.h"
      31             : #include "providers/krb5/krb5_auth.h"
      32             : #include "util/sss_utf8.h"
      33             : #include "tests/common.h"
      34             : 
      35             : #define TESTS_PATH "tp_" BASE_FILE_STEM
      36             : 
      37             : #define BASE "/abc/def"
      38             : #define FILENAME "ghi"
      39             : 
      40             : #define USERNAME "testuser"
      41             : #define UID "12345"
      42             : #define PRINCIPAL_NAME "testuser@EXAMPLE.COM"
      43             : #define REALM "REALM.ORG"
      44             : #define HOME_DIRECTORY "/home/testuser"
      45             : #define CCACHE_DIR "/var/tmp"
      46             : #define PID "4321"
      47             : 
      48             : extern struct dp_option default_krb5_opts[];
      49             : 
      50             : TALLOC_CTX *tmp_ctx = NULL;
      51             : struct krb5child_req *kr;
      52             : 
      53             : #define RMDIR(__dir__) do { \
      54             :     ret = rmdir(__dir__); \
      55             :     fail_unless(ret == EOK, "rmdir [%s] failed, [%d][%s].", __dir__, \
      56             :                 errno, strerror(errno)); \
      57             : } while(0)
      58             : 
      59           2 : void setup_create_dir(void)
      60             : {
      61           2 :     fail_unless(tmp_ctx == NULL, "Talloc context already initialized.");
      62           2 :     tmp_ctx = talloc_new(NULL);
      63           2 :     fail_unless(tmp_ctx != NULL, "Cannot create talloc context.");
      64           2 : }
      65             : 
      66           2 : void teardown_create_dir(void)
      67             : {
      68             :     int ret;
      69           2 :     fail_unless(tmp_ctx != NULL, "Talloc context already freed.");
      70           2 :     ret = talloc_free(tmp_ctx);
      71           2 :     tmp_ctx = NULL;
      72           2 :     fail_unless(ret == 0, "Cannot free talloc context.");
      73           2 : }
      74             : 
      75           0 : static void check_dir(const char *dirname, uid_t uid, gid_t gid, mode_t mode)
      76             : {
      77             :     struct stat stat_buf;
      78             :     int ret;
      79             : 
      80           0 :     ret = stat(dirname, &stat_buf);
      81           0 :     fail_unless(ret == EOK, "stat failed [%d][%s].", errno, strerror(errno));
      82             : 
      83           0 :     fail_unless(S_ISDIR(stat_buf.st_mode), "[%s] is not a directory.", dirname);
      84           0 :     fail_unless(stat_buf.st_uid == uid, "uid does not match, "
      85             :                                         "expected [%d], got [%d].",
      86             :                                         uid, stat_buf.st_uid);
      87           0 :     fail_unless(stat_buf.st_gid == gid, "gid does not match, "
      88             :                                         "expected [%d], got [%d].",
      89             :                                         gid, stat_buf.st_gid);
      90           0 :     fail_unless((stat_buf.st_mode & ~S_IFMT) == mode,
      91             :                                            "mode of [%s] does not match, "
      92             :                                            "expected [%o], got [%o].", dirname,
      93             :                                             mode, (stat_buf.st_mode & ~S_IFMT));
      94           0 : }
      95             : 
      96           0 : START_TEST(test_private_ccache_dir_in_user_dir)
      97             : {
      98             :     int ret;
      99             :     char *cwd;
     100             :     char *user_dir;
     101             :     char *dn1;
     102             :     char *dn2;
     103             :     char *dn3;
     104             :     char *filename;
     105           0 :     uid_t uid = getuid();
     106           0 :     gid_t gid = getgid();
     107             : 
     108           0 :     if (uid == 0) {
     109           0 :         uid = 12345;
     110           0 :         gid = 12345;
     111             :     }
     112             : 
     113           0 :     cwd = getcwd(NULL, 0);
     114           0 :     fail_unless(cwd != NULL, "getcwd failed.");
     115             : 
     116           0 :     user_dir = talloc_asprintf(tmp_ctx, "%s/%s/user", cwd, TESTS_PATH);
     117           0 :     free(cwd);
     118           0 :     fail_unless(user_dir != NULL, "talloc_asprintf failed.");
     119           0 :     ret = mkdir(user_dir, 0700);
     120           0 :     fail_unless(ret == EOK, "mkdir failed.");
     121           0 :     ret = chown(user_dir, uid, gid);
     122           0 :     fail_unless(ret == EOK, "chown failed.");
     123             : 
     124           0 :     dn1 = talloc_asprintf(tmp_ctx, "%s/a", user_dir);
     125           0 :     fail_unless(dn1 != NULL, "talloc_asprintf failed.");
     126           0 :     dn2 = talloc_asprintf(tmp_ctx, "%s/b", dn1);
     127           0 :     fail_unless(dn2 != NULL, "talloc_asprintf failed.");
     128           0 :     dn3 = talloc_asprintf(tmp_ctx, "%s/c", dn2);
     129           0 :     fail_unless(dn3 != NULL, "talloc_asprintf failed.");
     130           0 :     filename = talloc_asprintf(tmp_ctx, "%s/ccfile", dn3);
     131           0 :     fail_unless(filename != NULL, "talloc_asprintf failed.");
     132             : 
     133           0 :     ret = chmod(user_dir, 0600);
     134           0 :     fail_unless(ret == EOK, "chmod failed.");
     135           0 :     ret = sss_krb5_precreate_ccache(filename, uid, gid);
     136           0 :     fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL "
     137             :                                "while x-bit is missing.");
     138             : 
     139           0 :     ret = chmod(user_dir, 0700);
     140           0 :     fail_unless(ret == EOK, "chmod failed.");
     141           0 :     ret = sss_krb5_precreate_ccache(filename, uid, gid);
     142           0 :     fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed.");
     143             : 
     144           0 :     check_dir(dn3, uid, gid, 0700);
     145           0 :     RMDIR(dn3);
     146           0 :     check_dir(dn2, uid, gid, 0700);
     147           0 :     RMDIR(dn2);
     148           0 :     check_dir(dn1, uid, gid, 0700);
     149           0 :     RMDIR(dn1);
     150           0 :     RMDIR(user_dir);
     151             : }
     152           0 : END_TEST
     153             : 
     154           0 : START_TEST(test_private_ccache_dir_in_wrong_user_dir)
     155             : {
     156             :     int ret;
     157             :     char *cwd;
     158             :     char *dirname;
     159             :     char *subdirname;
     160             :     char *filename;
     161             : 
     162           0 :     fail_unless(getuid() == 0, "This test must be run as root.");
     163             : 
     164           0 :     cwd = getcwd(NULL, 0);
     165           0 :     fail_unless(cwd != NULL, "getcwd failed.");
     166             : 
     167           0 :     dirname = talloc_asprintf(tmp_ctx, "%s/%s/priv_ccdir", cwd, TESTS_PATH);
     168           0 :     free(cwd);
     169           0 :     fail_unless(dirname != NULL, "talloc_asprintf failed.");
     170           0 :     ret = mkdir(dirname, 0700);
     171           0 :     fail_unless(ret == EOK, "mkdir failed.\n");
     172           0 :     ret = chown(dirname, 12346, 12346);
     173           0 :     fail_unless(ret == EOK, "chown failed.\n");
     174           0 :     subdirname = talloc_asprintf(tmp_ctx, "%s/subdir", dirname);
     175           0 :     fail_unless(subdirname != NULL, "talloc_asprintf failed.");
     176           0 :     filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname);
     177           0 :     fail_unless(filename != NULL, "talloc_asprintf failed.");
     178             : 
     179           0 :     ret = sss_krb5_precreate_ccache(filename, 12345, 12345);
     180           0 :     fail_unless(ret == EINVAL, "Creating private ccache dir in wrong user "
     181             :                                "dir does not failed with EINVAL.");
     182             : 
     183           0 :     RMDIR(dirname);
     184             : }
     185           0 : END_TEST
     186             : 
     187           1 : START_TEST(test_illegal_patterns)
     188             : {
     189             :     char *cwd;
     190             :     char *dirname;
     191             :     char *filename;
     192             :     pcre *illegal_re;
     193             :     const char *errstr;
     194             :     int errval;
     195             :     int errpos;
     196           1 :     char *result = NULL;
     197             : 
     198           1 :     illegal_re = pcre_compile2(ILLEGAL_PATH_PATTERN, 0,
     199             :                                &errval, &errstr, &errpos, NULL);
     200           1 :     fail_unless(illegal_re != NULL, "Invalid Regular Expression pattern at "
     201             :                                     " position %d. (Error: %d [%s])\n",
     202             :                                     errpos, errval, errstr);
     203             : 
     204           1 :     cwd = getcwd(NULL, 0);
     205           1 :     fail_unless(cwd != NULL, "getcwd failed.");
     206             : 
     207           1 :     dirname = talloc_asprintf(tmp_ctx, "%s/%s/priv_ccdir", cwd, TESTS_PATH);
     208           1 :     free(cwd);
     209           1 :     fail_unless(dirname != NULL, "talloc_asprintf failed.");
     210             : 
     211           1 :     result = expand_ccname_template(tmp_ctx, kr, "abc/./ccfile", illegal_re, true, true);
     212           1 :     fail_unless(result == NULL, "expand_ccname_template allowed relative path\n");
     213             : 
     214           1 :     filename = talloc_asprintf(tmp_ctx, "%s/abc/./ccfile", dirname);
     215           1 :     fail_unless(filename != NULL, "talloc_asprintf failed.");
     216           1 :     result = expand_ccname_template(tmp_ctx, kr, filename, illegal_re, true, true);
     217           1 :     fail_unless(result == NULL, "expand_ccname_template allowed "
     218             :                                 "illegal pattern '/./'\n");
     219             : 
     220           1 :     filename = talloc_asprintf(tmp_ctx, "%s/abc/../ccfile", dirname);
     221           1 :     fail_unless(filename != NULL, "talloc_asprintf failed.");
     222           1 :     result = expand_ccname_template(tmp_ctx, kr, filename, illegal_re, true, true);
     223           1 :     fail_unless(result == NULL, "expand_ccname_template allowed "
     224             :                                 "illegal pattern '/../' in filename [%s].",
     225             :                                 filename);
     226             : 
     227           1 :     filename = talloc_asprintf(tmp_ctx, "%s/abc//ccfile", dirname);
     228           1 :     fail_unless(filename != NULL, "talloc_asprintf failed.");
     229           1 :     result = expand_ccname_template(tmp_ctx, kr, filename, illegal_re, true, true);
     230           1 :     fail_unless(result == NULL, "expand_ccname_template allowed "
     231             :                                 "illegal pattern '//' in filename [%s].",
     232             :                                 filename);
     233             : 
     234           1 :     pcre_free(illegal_re);
     235             : }
     236           1 : END_TEST
     237             : 
     238           1 : START_TEST(test_cc_dir_create)
     239             : {
     240             :     char *residual;
     241             :     char *dirname;
     242             :     char *cwd;
     243           1 :     uid_t uid = getuid();
     244           1 :     gid_t gid = getgid();
     245             :     errno_t ret;
     246             : 
     247           1 :     cwd = getcwd(NULL, 0);
     248           1 :     fail_unless(cwd != NULL, "getcwd failed.");
     249             : 
     250           1 :     dirname = talloc_asprintf(tmp_ctx, "%s/%s/user_dir",
     251             :                               cwd, TESTS_PATH);
     252           1 :     fail_unless(dirname != NULL, "talloc_asprintf failed.");
     253           1 :     residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir");
     254           1 :     fail_unless(residual != NULL, "talloc_asprintf failed.");
     255             : 
     256           1 :     ret = sss_krb5_precreate_ccache(residual, uid, gid);
     257           1 :     fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n");
     258           1 :     ret = rmdir(dirname);
     259           1 :     if (ret < 0) ret = errno;
     260           1 :     fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret));
     261           1 :     talloc_free(residual);
     262             : 
     263           1 :     dirname = talloc_asprintf(tmp_ctx, "%s/%s/user_dir2",
     264             :                               cwd, TESTS_PATH);
     265           1 :     fail_unless(dirname != NULL, "talloc_asprintf failed.");
     266           1 :     residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir/");
     267           1 :     fail_unless(residual != NULL, "talloc_asprintf failed.");
     268             : 
     269           1 :     ret = sss_krb5_precreate_ccache(residual, uid, gid);
     270           1 :     fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n");
     271           1 :     ret = rmdir(dirname);
     272           1 :     if (ret < 0) ret = errno;
     273           1 :     fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret));
     274           1 :     talloc_free(residual);
     275           1 :     free(cwd);
     276             : }
     277           1 : END_TEST
     278             : 
     279             : 
     280          14 : void setup_talloc_context(void)
     281             : {
     282             :     int ret;
     283             :     int i;
     284             : 
     285             :     struct pam_data *pd;
     286             :     struct krb5_ctx *krb5_ctx;
     287          14 :     fail_unless(tmp_ctx == NULL, "Talloc context already initialized.");
     288          14 :     tmp_ctx = talloc_new(NULL);
     289          14 :     fail_unless(tmp_ctx != NULL, "Cannot create talloc context.");
     290             : 
     291          14 :     kr = talloc_zero(tmp_ctx, struct krb5child_req);
     292          14 :     fail_unless(kr != NULL, "Cannot create krb5child_req structure.");
     293             : 
     294          14 :     pd = create_pam_data(tmp_ctx);
     295          14 :     fail_unless(pd != NULL, "Cannot create pam_data structure.");
     296             : 
     297          14 :     krb5_ctx = talloc_zero(tmp_ctx, struct krb5_ctx);
     298          14 :     fail_unless(pd != NULL, "Cannot create krb5_ctx structure.");
     299             : 
     300          14 :     pd->user = discard_const(USERNAME);
     301          14 :     kr->uid = atoi(UID);
     302          14 :     kr->upn = discard_const(PRINCIPAL_NAME);
     303          14 :     pd->cli_pid = atoi(PID);
     304             : 
     305          14 :     krb5_ctx->opts = talloc_zero_array(tmp_ctx, struct dp_option, KRB5_OPTS);
     306          14 :     fail_unless(krb5_ctx->opts != NULL, "Cannot created options.");
     307         294 :     for (i = 0; i < KRB5_OPTS; i++) {
     308         280 :         krb5_ctx->opts[i].opt_name = default_krb5_opts[i].opt_name;
     309         280 :         krb5_ctx->opts[i].type = default_krb5_opts[i].type;
     310         280 :         krb5_ctx->opts[i].def_val = default_krb5_opts[i].def_val;
     311             :     }
     312          14 :     ret = dp_opt_set_string(krb5_ctx->opts, KRB5_REALM, REALM);
     313          14 :     fail_unless(ret == EOK, "Failed to set Realm");
     314          14 :     ret = dp_opt_set_string(krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR);
     315          14 :     fail_unless(ret == EOK, "Failed to set Ccache dir");
     316             : 
     317          14 :     kr->homedir = HOME_DIRECTORY;
     318             : 
     319          14 :     kr->pd = pd;
     320          14 :     kr->krb5_ctx = krb5_ctx;
     321             : 
     322          14 : }
     323             : 
     324          14 : void free_talloc_context(void)
     325             : {
     326             :     int ret;
     327          14 :     fail_unless(tmp_ctx != NULL, "Talloc context already freed.");
     328          14 :     ret = talloc_free(tmp_ctx);
     329          14 :     tmp_ctx = NULL;
     330          14 :     fail_unless(ret == 0, "Cannot free talloc context.");
     331          14 : }
     332             : 
     333          16 : static void do_test(const char *file_template, const char *dir_template,
     334             :                     const char *expected)
     335             : {
     336             :     char *result;
     337             :     int ret;
     338             : 
     339          16 :     ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, dir_template);
     340          16 :     fail_unless(ret == EOK, "Failed to set Ccache dir");
     341             : 
     342          16 :     result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true);
     343             : 
     344          16 :     fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
     345          16 :     fail_unless(strcmp(result, expected) == 0,
     346             :                 "Expansion failed, result [%s], expected [%s].",
     347             :                 result, expected);
     348          16 : }
     349             : 
     350           1 : START_TEST(test_multiple_substitutions)
     351             : {
     352           1 :     do_test(BASE"_%u_%U_%u", CCACHE_DIR, BASE"_"USERNAME"_"UID"_"USERNAME);
     353           1 :     do_test("%d/"FILENAME, BASE"_%u_%U_%u",
     354             :             BASE"_"USERNAME"_"UID"_"USERNAME"/"FILENAME);
     355             : }
     356           1 : END_TEST
     357             : 
     358           1 : START_TEST(test_username)
     359             : {
     360           1 :     do_test(BASE"_%u", CCACHE_DIR, BASE"_"USERNAME);
     361           1 :     do_test("%d/"FILENAME, BASE"_%u", BASE"_"USERNAME"/"FILENAME);
     362             : }
     363           1 : END_TEST
     364             : 
     365           1 : START_TEST(test_case_sensitive)
     366             : {
     367             :     char *result;
     368             :     int ret;
     369           1 :     const char *file_template = BASE"_%u";
     370           1 :     const char *expected_cs = BASE"_TestUser";
     371           1 :     const char *expected_ci = BASE"_testuser";
     372             : 
     373           1 :     kr->pd->user = discard_const("TestUser");
     374           1 :     ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR);
     375           1 :     fail_unless(ret == EOK, "Failed to set Ccache dir");
     376             : 
     377           1 :     result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true);
     378             : 
     379           1 :     fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
     380           1 :     fail_unless(strcmp(result, expected_cs) == 0,
     381             :                 "Expansion failed, result [%s], expected [%s].",
     382             :                 result, expected_cs);
     383             : 
     384           1 :     result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, false);
     385             : 
     386           1 :     fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
     387           1 :     fail_unless(strcmp(result, expected_ci) == 0,
     388             :                 "Expansion failed, result [%s], expected [%s].",
     389             :                 result, expected_ci);
     390             : }
     391           1 : END_TEST
     392             : 
     393           1 : START_TEST(test_uid)
     394             : {
     395           1 :     do_test(BASE"_%U", CCACHE_DIR, BASE"_"UID);
     396           1 :     do_test("%d/"FILENAME, BASE"_%U", BASE"_"UID"/"FILENAME);
     397             : }
     398           1 : END_TEST
     399             : 
     400           1 : START_TEST(test_upn)
     401             : {
     402           1 :     do_test(BASE"_%p", CCACHE_DIR, BASE"_"PRINCIPAL_NAME);
     403           1 :     do_test("%d/"FILENAME, BASE"_%p", BASE"_"PRINCIPAL_NAME"/"FILENAME);
     404             : }
     405           1 : END_TEST
     406             : 
     407           1 : START_TEST(test_realm)
     408             : {
     409           1 :     do_test(BASE"_%r", CCACHE_DIR, BASE"_"REALM);
     410           1 :     do_test("%d/"FILENAME, BASE"_%r", BASE"_"REALM"/"FILENAME);
     411             : }
     412           1 : END_TEST
     413             : 
     414           1 : START_TEST(test_home)
     415             : {
     416           1 :     do_test(BASE"_%h", CCACHE_DIR, BASE"_"HOME_DIRECTORY);
     417           1 :     do_test("%d/"FILENAME, BASE"_%h", BASE"_"HOME_DIRECTORY"/"FILENAME);
     418             : }
     419           1 : END_TEST
     420             : 
     421           1 : START_TEST(test_ccache_dir)
     422             : {
     423             :     char *result;
     424             :     int ret;
     425             : 
     426           1 :     do_test(BASE"_%d", CCACHE_DIR, BASE"_"CCACHE_DIR);
     427             : 
     428           1 :     ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, BASE"_%d");
     429           1 :     fail_unless(ret == EOK, "Failed to set Ccache dir");
     430             : 
     431           1 :     result = expand_ccname_template(tmp_ctx, kr, "%d/"FILENAME, NULL, true, true);
     432             : 
     433           1 :     fail_unless(result == NULL, "Using %%d in ccache dir should fail.");
     434             : }
     435           1 : END_TEST
     436             : 
     437           1 : START_TEST(test_pid)
     438             : {
     439             :     char *result;
     440             :     int ret;
     441             : 
     442           1 :     do_test(BASE"_%P", CCACHE_DIR, BASE"_"PID);
     443             : 
     444           1 :     ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, BASE"_%P");
     445           1 :     fail_unless(ret == EOK, "Failed to set Ccache dir");
     446             : 
     447           1 :     result = expand_ccname_template(tmp_ctx, kr, "%d/"FILENAME, NULL, true, true);
     448             : 
     449           1 :     fail_unless(result == NULL, "Using %%P in ccache dir should fail.");
     450             : }
     451           1 : END_TEST
     452             : 
     453           1 : START_TEST(test_percent)
     454             : {
     455           1 :     do_test(BASE"_%%", CCACHE_DIR, BASE"_%");
     456           1 :     do_test("%d/"FILENAME, BASE"_%%", BASE"_%/"FILENAME);
     457             : }
     458           1 : END_TEST
     459             : 
     460           1 : START_TEST(test_unknown_template)
     461             : {
     462           1 :     const char *test_template = BASE"_%X";
     463             :     char *result;
     464             :     int ret;
     465             : 
     466           1 :     result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true);
     467             : 
     468           1 :     fail_unless(result == NULL, "Unknown template [%s] should fail.",
     469             :                 test_template);
     470             : 
     471           1 :     ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, BASE"_%X");
     472           1 :     fail_unless(ret == EOK, "Failed to set Ccache dir");
     473           1 :     test_template = "%d/"FILENAME;
     474           1 :     result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true);
     475             : 
     476           1 :     fail_unless(result == NULL, "Unknown template [%s] should fail.",
     477             :                 test_template);
     478             : }
     479           1 : END_TEST
     480             : 
     481           1 : START_TEST(test_NULL)
     482             : {
     483           1 :     char *test_template = NULL;
     484             :     char *result;
     485             : 
     486           1 :     result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true);
     487             : 
     488           1 :     fail_unless(result == NULL, "Expected NULL as a result for an empty input.",
     489             :                 test_template);
     490             : }
     491           1 : END_TEST
     492             : 
     493           1 : START_TEST(test_no_substitution)
     494             : {
     495           1 :     const char *test_template = BASE;
     496             :     char *result;
     497             : 
     498           1 :     result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true);
     499             : 
     500           1 :     fail_unless(result != NULL, "Cannot expand template [%s].", test_template);
     501           1 :     fail_unless(strcmp(result, test_template) == 0,
     502             :                 "Expansion failed, result [%s], expected [%s].",
     503             :                 result, test_template);
     504             : }
     505           1 : END_TEST
     506             : 
     507           1 : START_TEST(test_krb5_style_expansion)
     508             : {
     509             :     char *result;
     510             :     const char *file_template;
     511             :     const char *expected;
     512             : 
     513           1 :     file_template = BASE"/%{uid}/%{USERID}/%{euid}/%{username}";
     514           1 :     expected = BASE"/"UID"/"UID"/"UID"/"USERNAME;
     515           1 :     result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true);
     516             : 
     517           1 :     fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
     518           1 :     fail_unless(strcmp(result, expected) == 0,
     519             :                 "Expansion failed, result [%s], expected [%s].",
     520             :                 result, expected);
     521             : 
     522           1 :     file_template = BASE"/%{unknown}";
     523           1 :     expected = BASE"/%{unknown}";
     524           1 :     result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true);
     525             : 
     526           1 :     fail_unless(result != NULL, "Cannot expand template [%s].", file_template);
     527           1 :     fail_unless(strcmp(result, expected) == 0,
     528             :                 "Expansion failed, result [%s], expected [%s].",
     529             :                 result, expected);
     530             : }
     531           1 : END_TEST
     532             : 
     533           1 : START_TEST(test_compare_principal_realm)
     534             : {
     535             :     int ret;
     536             :     bool different_realm;
     537             : 
     538           1 :     ret = compare_principal_realm(NULL, "a", &different_realm);
     539           1 :     fail_unless(ret == EINVAL, "NULL upn does not cause EINVAL.");
     540             : 
     541           1 :     ret = compare_principal_realm("a", NULL, &different_realm);
     542           1 :     fail_unless(ret == EINVAL, "NULL realm does not cause EINVAL.");
     543             : 
     544           1 :     ret = compare_principal_realm("a", "b", NULL);
     545           1 :     fail_unless(ret == EINVAL, "NULL different_realmbool " \
     546             :                                "does not cause EINVAL.");
     547             : 
     548           1 :     ret = compare_principal_realm("", "a", &different_realm);
     549           1 :     fail_unless(ret == EINVAL, "Empty upn does not cause EINVAL.");
     550             : 
     551           1 :     ret = compare_principal_realm("a", "", &different_realm);
     552           1 :     fail_unless(ret == EINVAL, "Empty realm does not cause EINVAL.");
     553             : 
     554           1 :     ret = compare_principal_realm("ABC", "ABC", &different_realm);
     555           1 :     fail_unless(ret == EINVAL, "Short UPN does not cause EINVAL.");
     556             : 
     557           1 :     ret = compare_principal_realm("userABC", "ABC", &different_realm);
     558           1 :     fail_unless(ret == EINVAL, "Missing '@' does not cause EINVAL.");
     559             : 
     560           1 :     ret = compare_principal_realm("user@ABC", "ABC", &different_realm);
     561           1 :     fail_unless(ret == EOK, "Failure with same realm");
     562           1 :     fail_unless(different_realm == false, "Same realm but " \
     563             :                                           "different_realm is not false.");
     564             : 
     565           1 :     ret = compare_principal_realm("user@ABC", "DEF", &different_realm);
     566           1 :     fail_unless(ret == EOK, "Failure with different realm");
     567           1 :     fail_unless(different_realm == true, "Different realm but " \
     568             :                                           "different_realm is not true.");
     569             : 
     570           1 :     ret = compare_principal_realm("user@ABC", "REALMNAMELONGERTHANUPN",
     571             :                                  &different_realm);
     572           1 :     fail_unless(ret == EOK, "Failure with long realm name.");
     573           1 :     fail_unless(different_realm == true, "Realm name longer than UPN but "
     574             :                                          "different_realm is not true.");
     575             : }
     576           1 : END_TEST
     577             : 
     578             : static void
     579           2 : compare_map_id_name_to_krb_primary(struct map_id_name_to_krb_primary *a,
     580             :                                    const char **str,
     581             :                                    size_t len)
     582             : {
     583           2 :     int i = 0;
     584             :     errno_t ret;
     585             : 
     586          10 :     while (a[i].id_name != NULL && a[i].krb_primary != NULL) {
     587           6 :         fail_unless(i < len);
     588           6 :         ret = sss_utf8_case_eq((const uint8_t*)a[i].id_name,
     589           6 :                                (const uint8_t*)str[i*2]);
     590           6 :         fail_unless(ret == EOK,
     591             :                     "%s does not match %s", a[i].id_name, str[i*2]);
     592             : 
     593           6 :         ret = sss_utf8_case_eq((const uint8_t*)a[i].krb_primary,
     594           6 :                                (const uint8_t*)str[i*2+1]);
     595           6 :         fail_unless(ret == EOK, "%s does not match %s",
     596             :                     a[i].krb_primary, str[i*2+1]);
     597           6 :         i++;
     598             :     }
     599           2 :     fail_unless(len == i, "%u != %u", len, i);
     600           2 : }
     601             : 
     602           1 : START_TEST(test_parse_krb5_map_user)
     603             : {
     604             :     errno_t ret;
     605             :     TALLOC_CTX *mem_ctx;
     606             :     struct map_id_name_to_krb_primary *name_to_primary;
     607             : 
     608           1 :     mem_ctx = talloc_new(NULL);
     609             : 
     610             :     /* empty input */
     611             :     {
     612           1 :         check_leaks_push(mem_ctx);
     613           1 :         ret = parse_krb5_map_user(mem_ctx, NULL, &name_to_primary);
     614           1 :         fail_unless(ret == EOK);
     615           1 :         fail_unless(name_to_primary[0].id_name == NULL &&
     616             :                     name_to_primary[0].krb_primary == NULL);
     617           1 :         talloc_free(name_to_primary);
     618             : 
     619           1 :         ret = parse_krb5_map_user(mem_ctx, "", &name_to_primary);
     620           2 :         fail_unless(ret == EOK);
     621           1 :         fail_unless(name_to_primary[0].id_name == NULL &&
     622             :                     name_to_primary[0].krb_primary == NULL);
     623           1 :         talloc_free(name_to_primary);
     624             : 
     625           1 :         ret = parse_krb5_map_user(mem_ctx, ",", &name_to_primary);
     626           2 :         fail_unless(ret == EOK);
     627           1 :         fail_unless(name_to_primary[0].id_name == NULL &&
     628             :                     name_to_primary[0].krb_primary == NULL);
     629           1 :         talloc_free(name_to_primary);
     630             : 
     631           1 :         ret = parse_krb5_map_user(mem_ctx, ",,", &name_to_primary);
     632           2 :         fail_unless(ret == EOK);
     633           1 :         fail_unless(name_to_primary[0].id_name == NULL &&
     634             :                     name_to_primary[0].krb_primary == NULL);
     635           1 :         talloc_free(name_to_primary);
     636             : 
     637           1 :         check_leaks_pop(mem_ctx);
     638             :     }
     639             :     /* valid input */
     640             :     {
     641           1 :         check_leaks_push(mem_ctx);
     642           1 :         const char *p = "pája:preichl,joe:juser,jdoe:ßlack";
     643           1 :         const char *p2 = " pája  : preichl , joe:\njuser,jdoe\t:   ßlack ";
     644           1 :         const char *expected[] = {"pája", "preichl", "joe", "juser", "jdoe", "ßlack"};
     645           1 :         ret = parse_krb5_map_user(mem_ctx, p, &name_to_primary);
     646           2 :         fail_unless(ret == EOK);
     647           1 :         compare_map_id_name_to_krb_primary(name_to_primary, expected,
     648             :                                          sizeof(expected)/sizeof(const char*)/2);
     649           1 :         talloc_free(name_to_primary);
     650             : 
     651           1 :         ret = parse_krb5_map_user(mem_ctx, p2, &name_to_primary);
     652           1 :         fail_unless(ret == EOK);
     653           1 :         compare_map_id_name_to_krb_primary(name_to_primary,  expected,
     654             :                                          sizeof(expected)/sizeof(const char*)/2);
     655           1 :         talloc_free(name_to_primary);
     656           1 :         check_leaks_pop(mem_ctx);
     657             :     }
     658             :     /* invalid input */
     659             :     {
     660           1 :         check_leaks_push(mem_ctx);
     661             : 
     662           1 :         ret = parse_krb5_map_user(mem_ctx, ":", &name_to_primary);
     663           1 :         fail_unless(ret == EINVAL);
     664             : 
     665           1 :         ret = parse_krb5_map_user(mem_ctx, "joe:", &name_to_primary);
     666           1 :         fail_unless(ret == EINVAL);
     667             : 
     668           1 :         ret = parse_krb5_map_user(mem_ctx, ":joe", &name_to_primary);
     669           1 :         fail_unless(ret == EINVAL);
     670             : 
     671           1 :         ret = parse_krb5_map_user(mem_ctx, "joe:,", &name_to_primary);
     672           1 :         fail_unless(ret == EINVAL);
     673             : 
     674           1 :         ret = parse_krb5_map_user(mem_ctx, ",joe", &name_to_primary);
     675           1 :         fail_unless(ret == EINVAL);
     676             : 
     677           1 :         ret = parse_krb5_map_user(mem_ctx, "joe:j:user", &name_to_primary);
     678           1 :         fail_unless(ret == EINVAL);
     679             : 
     680           1 :         check_leaks_pop(mem_ctx);
     681             :     }
     682             : 
     683           1 :     talloc_free(mem_ctx);
     684             : }
     685           1 : END_TEST
     686             : 
     687           1 : START_TEST(test_sss_krb5_realm_has_proxy)
     688             : {
     689           1 :     fail_unless(sss_krb5_realm_has_proxy(NULL) == false);
     690             : 
     691           1 :     setenv("KRB5_CONFIG", "/dev/null", 1);
     692           1 :     fail_unless(sss_krb5_realm_has_proxy("REALM") == false);
     693             : 
     694           1 :     setenv("KRB5_CONFIG", ABS_SRC_DIR"/src/tests/krb5_proxy_check_test_data.conf", 1);
     695           1 :     fail_unless(sss_krb5_realm_has_proxy("REALM") == false);
     696           1 :     fail_unless(sss_krb5_realm_has_proxy("REALM_PROXY") == true);
     697             : }
     698           1 : END_TEST
     699             : 
     700           1 : Suite *krb5_utils_suite (void)
     701             : {
     702           1 :     Suite *s = suite_create ("krb5_utils");
     703             : 
     704           1 :     TCase *tc_ccname_template = tcase_create ("ccname_template");
     705           1 :     tcase_add_checked_fixture (tc_ccname_template, setup_talloc_context,
     706             :                                free_talloc_context);
     707           1 :     tcase_add_test (tc_ccname_template, test_no_substitution);
     708           1 :     tcase_add_test (tc_ccname_template, test_NULL);
     709           1 :     tcase_add_test (tc_ccname_template, test_unknown_template);
     710           1 :     tcase_add_test (tc_ccname_template, test_username);
     711           1 :     tcase_add_test (tc_ccname_template, test_case_sensitive);
     712           1 :     tcase_add_test (tc_ccname_template, test_uid);
     713           1 :     tcase_add_test (tc_ccname_template, test_upn);
     714           1 :     tcase_add_test (tc_ccname_template, test_realm);
     715           1 :     tcase_add_test (tc_ccname_template, test_home);
     716           1 :     tcase_add_test (tc_ccname_template, test_ccache_dir);
     717           1 :     tcase_add_test (tc_ccname_template, test_pid);
     718           1 :     tcase_add_test (tc_ccname_template, test_percent);
     719           1 :     tcase_add_test (tc_ccname_template, test_multiple_substitutions);
     720           1 :     tcase_add_test (tc_ccname_template, test_krb5_style_expansion);
     721           1 :     suite_add_tcase (s, tc_ccname_template);
     722             : 
     723           1 :     TCase *tc_create_dir = tcase_create("create_dir");
     724           1 :     tcase_add_checked_fixture (tc_create_dir, setup_create_dir,
     725             :                                teardown_create_dir);
     726           1 :     tcase_add_test (tc_create_dir, test_illegal_patterns);
     727           1 :     tcase_add_test (tc_create_dir, test_cc_dir_create);
     728           1 :     if (getuid() == 0) {
     729           0 :         tcase_add_test (tc_create_dir, test_private_ccache_dir_in_user_dir);
     730           0 :         tcase_add_test (tc_create_dir, test_private_ccache_dir_in_wrong_user_dir);
     731             :     } else {
     732           1 :         printf("Run as root to enable more tests.\n");
     733             :     }
     734           1 :     suite_add_tcase (s, tc_create_dir);
     735             : 
     736           1 :     TCase *tc_krb5_helpers = tcase_create("Helper functions");
     737           1 :     tcase_add_test(tc_krb5_helpers, test_compare_principal_realm);
     738           1 :     tcase_add_test(tc_krb5_helpers, test_parse_krb5_map_user);
     739           1 :     tcase_add_test(tc_krb5_helpers, test_sss_krb5_realm_has_proxy);
     740           1 :     suite_add_tcase(s, tc_krb5_helpers);
     741             : 
     742           1 :     return s;
     743             : }
     744             : 
     745           1 : int main(int argc, const char *argv[])
     746             : {
     747             :     int ret;
     748             :     int opt;
     749             :     poptContext pc;
     750             :     int number_failed;
     751             : 
     752           1 :     tests_set_cwd();
     753             : 
     754           6 :     struct poptOption long_options[] = {
     755             :         POPT_AUTOHELP
     756           5 :         SSSD_MAIN_OPTS
     757             :         POPT_TABLEEND
     758             :     };
     759             : 
     760             :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     761           1 :     debug_level = SSSDBG_INVALID;
     762             : 
     763           1 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     764           1 :     while((opt = poptGetNextOpt(pc)) != -1) {
     765             :         switch(opt) {
     766             :         default:
     767           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     768             :                     poptBadOption(pc, 0), poptStrerror(opt));
     769           0 :             poptPrintUsage(pc, stderr, 0);
     770           0 :             return 1;
     771             :         }
     772             :     }
     773           1 :     poptFreeContext(pc);
     774             : 
     775           1 :     DEBUG_CLI_INIT(debug_level);
     776             : 
     777           1 :     ret = mkdir(TESTS_PATH, 0775);
     778           1 :     if (ret != EOK) {
     779           0 :         fprintf(stderr, "Could not create empty directory [%s]. ", TESTS_PATH);
     780           0 :         if (errno == EEXIST) {
     781           0 :             fprintf(stderr, "Please remove [%s].\n", TESTS_PATH);
     782             :         } else {
     783           0 :             fprintf(stderr, "[%d][%s].\n", errno, strerror(errno));
     784             :         }
     785             : 
     786           0 :         return 1;
     787             :     }
     788             : 
     789           1 :     Suite *s = krb5_utils_suite ();
     790           1 :     SRunner *sr = srunner_create (s);
     791             :     /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
     792           1 :     srunner_run_all(sr, CK_ENV);
     793           1 :     number_failed = srunner_ntests_failed (sr);
     794           1 :     srunner_free (sr);
     795           1 :     if (number_failed == 0) {
     796           1 :         ret = rmdir(TESTS_PATH);
     797           1 :         if (ret != EOK) {
     798           0 :             fprintf(stderr, "Cannot remove [%s]: [%d][%s].\n", TESTS_PATH,
     799           0 :                             errno, strerror(errno));
     800           0 :             return EXIT_FAILURE;
     801             :         }
     802             : 
     803           1 :         return EXIT_SUCCESS;
     804             :     }
     805             : 
     806           0 :     return EXIT_FAILURE;
     807             : }
     808             : 

Generated by: LCOV version 1.10