LCOV - code coverage report
Current view: top level - tests - check_and_open-tests.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 108 108 100.0 %
Date: 2012-11-29 Functions: 13 13 100.0 %
Branches: 3 4 75.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :     SSSD
       3                 :            : 
       4                 :            :     Utilities tests check_and_open
       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 <check.h>
      27                 :            : #include <unistd.h>
      28                 :            : #include <sys/types.h>
      29                 :            : #include <sys/stat.h>
      30                 :            : 
      31                 :            : #include "util/util.h"
      32                 :            : #include "tests/common.h"
      33                 :            : 
      34                 :            : #define SUFFIX ".symlink"
      35                 :            : 
      36                 :            : #define FILENAME_TEMPLATE "check_and_open-tests-XXXXXX"
      37                 :            : char *filename;
      38                 :            : uid_t uid;
      39                 :            : gid_t gid;
      40                 :            : mode_t mode;
      41                 :            : int fd;
      42                 :            : 
      43                 :          9 : void setup_check_and_open(void)
      44                 :            : {
      45                 :            :     int ret;
      46                 :            :     mode_t old_umask;
      47                 :            : 
      48         [ +  - ]:          9 :     filename = strdup(FILENAME_TEMPLATE);
      49                 :          9 :     fail_unless(filename != NULL, "strdup failed");
      50                 :            : 
      51                 :          9 :     old_umask = umask(077);
      52                 :          9 :     ret = mkstemp(filename);
      53                 :          9 :     umask(old_umask);
      54                 :          9 :     fail_unless(ret != -1, "mkstemp failed [%d][%s]", errno, strerror(errno));
      55                 :          9 :     close(ret);
      56                 :            : 
      57                 :          9 :     uid = getuid();
      58                 :          9 :     gid = getgid();
      59                 :          9 :     mode = (S_IRUSR | S_IWUSR);
      60                 :          9 :     fd = -1;
      61                 :          9 : }
      62                 :            : 
      63                 :          9 : void teardown_check_and_open(void)
      64                 :            : {
      65                 :            :     int ret;
      66                 :            : 
      67         [ +  + ]:          9 :     if (fd != -1) {
      68                 :          2 :         ret = close(fd);
      69                 :          2 :         fail_unless(ret == 0, "close failed [%d][%s]", errno, strerror(errno));
      70                 :            :     }
      71                 :            : 
      72                 :          9 :     fail_unless(filename != NULL, "unknown filename");
      73                 :          9 :     ret = unlink(filename);
      74                 :          9 :     free(filename);
      75                 :          9 :     fail_unless(ret == 0, "unlink failed [%d][%s]", errno, strerror(errno));
      76                 :          9 : }
      77                 :            : 
      78                 :          1 : START_TEST(test_wrong_filename)
      79                 :            : {
      80                 :            :     int ret;
      81                 :            : 
      82                 :          1 :     ret = check_and_open_readonly("/bla/bla/bla", &fd, uid, gid, mode, CHECK_REG);
      83                 :          1 :     fail_unless(ret == ENOENT,
      84                 :            :                 "check_and_open_readonly succeeded on non-existing file");
      85                 :          1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
      86                 :            : }
      87                 :          1 : END_TEST
      88                 :            : 
      89                 :          1 : START_TEST(test_symlink)
      90                 :            : {
      91                 :            :     int ret;
      92                 :            :     char *newpath;
      93                 :            :     size_t newpath_length;
      94                 :            : 
      95                 :          1 :     newpath_length = strlen(filename) + strlen(SUFFIX) + 1;
      96                 :          1 :     newpath = malloc((newpath_length) * sizeof(char));
      97                 :          1 :     fail_unless(newpath != NULL, "malloc failed");
      98                 :            : 
      99                 :          1 :     ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX);
     100                 :          1 :     fail_unless(ret == newpath_length - 1,
     101                 :            :                 "snprintf failed: expected [%d] got [%d]", newpath_length -1,
     102                 :            :                                                            ret);
     103                 :            : 
     104                 :          1 :     ret = symlink(filename, newpath);
     105                 :          1 :     fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno));
     106                 :            : 
     107                 :          1 :     ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL, false);
     108                 :          1 :     unlink(newpath);
     109                 :            : 
     110                 :          1 :     fail_unless(ret == EINVAL,
     111                 :            :                 "check_and_open_readonly succeeded on symlink");
     112                 :            : }
     113                 :          1 : END_TEST
     114                 :            : 
     115                 :          1 : START_TEST(test_follow_symlink)
     116                 :            : {
     117                 :            :     int ret;
     118                 :            :     char *newpath;
     119                 :            :     size_t newpath_length;
     120                 :            : 
     121                 :          1 :     newpath_length = strlen(filename) + strlen(SUFFIX) + 1;
     122                 :          1 :     newpath = malloc((newpath_length) * sizeof(char));
     123                 :          1 :     fail_unless(newpath != NULL, "malloc failed");
     124                 :            : 
     125                 :          1 :     ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX);
     126                 :          1 :     fail_unless(ret == newpath_length - 1,
     127                 :            :                 "snprintf failed: expected [%d] got [%d]", newpath_length -1,
     128                 :            :                                                            ret);
     129                 :            : 
     130                 :          1 :     ret = symlink(filename, newpath);
     131                 :          1 :     fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno));
     132                 :            : 
     133                 :          1 :     ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL, true);
     134                 :          1 :     unlink(newpath);
     135                 :            : 
     136                 :          1 :     fail_unless(ret == EOK,
     137                 :            :                 "check_and_open_readonly failed on symlink with follow=true");
     138                 :            : }
     139                 :          1 : END_TEST
     140                 :            : 
     141                 :          1 : START_TEST(test_not_regular_file)
     142                 :            : {
     143                 :            :     int ret;
     144                 :            : 
     145                 :          1 :     ret = check_and_open_readonly("/dev/null", &fd, uid, gid, mode, CHECK_REG);
     146                 :          1 :     fail_unless(ret == EINVAL,
     147                 :            :                 "check_and_open_readonly succeeded on non-regular file");
     148                 :          1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     149                 :            : }
     150                 :          1 : END_TEST
     151                 :            : 
     152                 :          1 : START_TEST(test_wrong_uid)
     153                 :            : {
     154                 :            :     int ret;
     155                 :            : 
     156                 :          1 :     ret = check_and_open_readonly(filename, &fd, uid+1, gid, mode, CHECK_REG);
     157                 :          1 :     fail_unless(ret == EINVAL,
     158                 :            :                 "check_and_open_readonly succeeded with wrong uid");
     159                 :          1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     160                 :            : }
     161                 :          1 : END_TEST
     162                 :            : 
     163                 :          1 : START_TEST(test_wrong_gid)
     164                 :            : {
     165                 :            :     int ret;
     166                 :            : 
     167                 :          1 :     ret = check_and_open_readonly(filename, &fd, uid, gid+1, mode, CHECK_REG);
     168                 :          1 :     fail_unless(ret == EINVAL,
     169                 :            :                 "check_and_open_readonly succeeded with wrong gid");
     170                 :          1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     171                 :            : }
     172                 :          1 : END_TEST
     173                 :            : 
     174                 :          1 : START_TEST(test_wrong_permission)
     175                 :            : {
     176                 :            :     int ret;
     177                 :            : 
     178                 :          1 :     ret = check_and_open_readonly(filename, &fd, uid, gid, (mode|S_IWOTH),
     179                 :            :                                   CHECK_REG);
     180                 :          1 :     fail_unless(ret == EINVAL,
     181                 :            :                 "check_and_open_readonly succeeded with wrong mode");
     182                 :          1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     183                 :            : }
     184                 :          1 : END_TEST
     185                 :            : 
     186                 :          1 : START_TEST(test_ok)
     187                 :            : {
     188                 :            :     int ret;
     189                 :            : 
     190                 :          1 :     ret = check_and_open_readonly(filename, &fd, uid, gid, mode, CHECK_REG);
     191                 :          1 :     fail_unless(ret == EOK,
     192                 :            :                 "check_and_open_readonly failed");
     193                 :          1 :     fail_unless(fd >= 0,
     194                 :            :                 "check_and_open_readonly returned illegal file descriptor");
     195                 :            : }
     196                 :          1 : END_TEST
     197                 :            : 
     198                 :          1 : START_TEST(test_write)
     199                 :            : {
     200                 :            :     int ret;
     201                 :            :     ssize_t size;
     202                 :            :     errno_t my_errno;
     203                 :            : 
     204                 :          1 :     ret = check_and_open_readonly(filename, &fd, uid, gid, mode, CHECK_REG);
     205                 :          1 :     fail_unless(ret == EOK,
     206                 :            :                 "check_and_open_readonly failed");
     207                 :          1 :     fail_unless(fd >= 0,
     208                 :            :                 "check_and_open_readonly returned illegal file descriptor");
     209                 :            : 
     210                 :          1 :     size = write(fd, "abc", 3);
     211                 :          1 :     my_errno = errno;
     212                 :          1 :     fail_unless(size == -1, "check_and_open_readonly file is not readonly");
     213                 :          1 :     fail_unless(my_errno == EBADF,
     214                 :            :                 "write failed for other reason than readonly");
     215                 :            : }
     216                 :          1 : END_TEST
     217                 :            : 
     218                 :         10 : Suite *check_and_open_suite (void)
     219                 :            : {
     220                 :         10 :     Suite *s = suite_create ("check_and_open");
     221                 :            : 
     222                 :         10 :     TCase *tc_check_and_open_readonly = tcase_create ("check_and_open_readonly");
     223                 :         10 :     tcase_add_checked_fixture (tc_check_and_open_readonly,
     224                 :            :                                setup_check_and_open,
     225                 :            :                                teardown_check_and_open);
     226                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_filename);
     227                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_not_regular_file);
     228                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_symlink);
     229                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_follow_symlink);
     230                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_uid);
     231                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_gid);
     232                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_permission);
     233                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_ok);
     234                 :         10 :     tcase_add_test (tc_check_and_open_readonly, test_write);
     235                 :         10 :     suite_add_tcase (s, tc_check_and_open_readonly);
     236                 :            : 
     237                 :         10 :     return s;
     238                 :            : }
     239                 :            : 
     240                 :         10 : int main(void)
     241                 :            : {
     242                 :            :   int number_failed;
     243                 :            : 
     244                 :         10 :   tests_set_cwd();
     245                 :            : 
     246                 :         10 :   Suite *s = check_and_open_suite ();
     247                 :         10 :   SRunner *sr = srunner_create (s);
     248                 :            :   /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
     249                 :         10 :   srunner_run_all(sr, CK_ENV);
     250                 :          1 :   number_failed = srunner_ntests_failed (sr);
     251                 :          1 :   srunner_free (sr);
     252                 :          1 :   return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
     253                 :            : }
     254                 :            : 

Generated by: LCOV version 1.9