LCOV - code coverage report
Current view: top level - tests - check_and_open-tests.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 110 110 100.0 %
Date: 2015-10-19 Functions: 13 13 100.0 %

          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(SSS_DFL_UMASK);
      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,
      83             :                                   uid, gid, S_IFREG|mode, 0);
      84           1 :     fail_unless(ret == ENOENT,
      85             :                 "check_and_open_readonly succeeded on non-existing file");
      86           1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
      87             : }
      88           1 : END_TEST
      89             : 
      90           1 : START_TEST(test_symlink)
      91             : {
      92             :     int ret;
      93             :     char *newpath;
      94             :     size_t newpath_length;
      95             : 
      96           1 :     newpath_length = strlen(filename) + strlen(SUFFIX) + 1;
      97           1 :     newpath = malloc((newpath_length) * sizeof(char));
      98           1 :     fail_unless(newpath != NULL, "malloc failed");
      99             : 
     100           1 :     ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX);
     101           1 :     fail_unless(ret == newpath_length - 1,
     102             :                 "snprintf failed: expected [%d] got [%d]", newpath_length -1,
     103             :                                                            ret);
     104             : 
     105           1 :     ret = symlink(filename, newpath);
     106           1 :     fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno));
     107             : 
     108           1 :     ret = check_file(newpath, uid, gid, S_IFREG|mode, 0, NULL, false);
     109           1 :     unlink(newpath);
     110             : 
     111           1 :     fail_unless(ret == EINVAL,
     112             :                 "check_and_open_readonly succeeded on symlink");
     113           1 :     free(newpath);
     114             : }
     115           1 : END_TEST
     116             : 
     117           1 : START_TEST(test_follow_symlink)
     118             : {
     119             :     int ret;
     120             :     char *newpath;
     121             :     size_t newpath_length;
     122             : 
     123           1 :     newpath_length = strlen(filename) + strlen(SUFFIX) + 1;
     124           1 :     newpath = malloc((newpath_length) * sizeof(char));
     125           1 :     fail_unless(newpath != NULL, "malloc failed");
     126             : 
     127           1 :     ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX);
     128           1 :     fail_unless(ret == newpath_length - 1,
     129             :                 "snprintf failed: expected [%d] got [%d]", newpath_length -1,
     130             :                                                            ret);
     131             : 
     132           1 :     ret = symlink(filename, newpath);
     133           1 :     fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno));
     134             : 
     135           1 :     ret = check_file(newpath, uid, gid, S_IFREG|mode, 0, NULL, true);
     136           1 :     unlink(newpath);
     137             : 
     138           1 :     fail_unless(ret == EOK,
     139             :                 "check_and_open_readonly failed on symlink with follow=true");
     140           1 :     free(newpath);
     141             : }
     142           1 : END_TEST
     143             : 
     144           1 : START_TEST(test_not_regular_file)
     145             : {
     146             :     int ret;
     147             : 
     148           1 :     ret = check_and_open_readonly("/dev/null", &fd, uid, gid, S_IFREG|mode, 0);
     149           1 :     fail_unless(ret == EINVAL,
     150             :                 "check_and_open_readonly succeeded on non-regular file");
     151           1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     152             : }
     153           1 : END_TEST
     154             : 
     155           1 : START_TEST(test_wrong_uid)
     156             : {
     157             :     int ret;
     158             : 
     159           1 :     ret = check_and_open_readonly(filename, &fd, uid+1, gid, S_IFREG|mode, 0);
     160           1 :     fail_unless(ret == EINVAL,
     161             :                 "check_and_open_readonly succeeded with wrong uid");
     162           1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     163             : }
     164           1 : END_TEST
     165             : 
     166           1 : START_TEST(test_wrong_gid)
     167             : {
     168             :     int ret;
     169             : 
     170           1 :     ret = check_and_open_readonly(filename, &fd, uid, gid+1, S_IFREG|mode, 0);
     171           1 :     fail_unless(ret == EINVAL,
     172             :                 "check_and_open_readonly succeeded with wrong gid");
     173           1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     174             : }
     175           1 : END_TEST
     176             : 
     177           1 : START_TEST(test_wrong_permission)
     178             : {
     179             :     int ret;
     180             : 
     181           1 :     ret = check_and_open_readonly(filename, &fd,
     182             :                                   uid, gid, S_IFREG|mode|S_IWOTH, 0);
     183           1 :     fail_unless(ret == EINVAL,
     184             :                 "check_and_open_readonly succeeded with wrong mode");
     185           1 :     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
     186             : }
     187           1 : END_TEST
     188             : 
     189           1 : START_TEST(test_ok)
     190             : {
     191             :     int ret;
     192             : 
     193           1 :     ret = check_and_open_readonly(filename, &fd, uid, gid, S_IFREG|mode, 0);
     194           1 :     fail_unless(ret == EOK,
     195             :                 "check_and_open_readonly failed");
     196           1 :     fail_unless(fd >= 0,
     197             :                 "check_and_open_readonly returned illegal file descriptor");
     198             : }
     199           1 : END_TEST
     200             : 
     201           1 : START_TEST(test_write)
     202             : {
     203             :     int ret;
     204             :     ssize_t size;
     205             :     errno_t my_errno;
     206             : 
     207           1 :     ret = check_and_open_readonly(filename, &fd, uid, gid, S_IFREG|mode, 0);
     208           1 :     fail_unless(ret == EOK,
     209             :                 "check_and_open_readonly failed");
     210           1 :     fail_unless(fd >= 0,
     211             :                 "check_and_open_readonly returned illegal file descriptor");
     212             : 
     213           1 :     size = write(fd, "abc", 3);
     214           1 :     my_errno = errno;
     215           1 :     fail_unless(size == -1, "check_and_open_readonly file is not readonly");
     216           1 :     fail_unless(my_errno == EBADF,
     217             :                 "write failed for other reason than readonly");
     218             : }
     219           1 : END_TEST
     220             : 
     221           1 : Suite *check_and_open_suite (void)
     222             : {
     223           1 :     Suite *s = suite_create ("check_and_open");
     224             : 
     225           1 :     TCase *tc_check_and_open_readonly = tcase_create ("check_and_open_readonly");
     226           1 :     tcase_add_checked_fixture (tc_check_and_open_readonly,
     227             :                                setup_check_and_open,
     228             :                                teardown_check_and_open);
     229           1 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_filename);
     230           1 :     tcase_add_test (tc_check_and_open_readonly, test_not_regular_file);
     231           1 :     tcase_add_test (tc_check_and_open_readonly, test_symlink);
     232           1 :     tcase_add_test (tc_check_and_open_readonly, test_follow_symlink);
     233           1 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_uid);
     234           1 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_gid);
     235           1 :     tcase_add_test (tc_check_and_open_readonly, test_wrong_permission);
     236           1 :     tcase_add_test (tc_check_and_open_readonly, test_ok);
     237           1 :     tcase_add_test (tc_check_and_open_readonly, test_write);
     238           1 :     suite_add_tcase (s, tc_check_and_open_readonly);
     239             : 
     240           1 :     return s;
     241             : }
     242             : 
     243           1 : int main(void)
     244             : {
     245             :   int number_failed;
     246             : 
     247           1 :   tests_set_cwd();
     248             : 
     249           1 :   Suite *s = check_and_open_suite ();
     250           1 :   SRunner *sr = srunner_create (s);
     251             :   /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
     252           1 :   srunner_run_all(sr, CK_ENV);
     253           1 :   number_failed = srunner_ntests_failed (sr);
     254           1 :   srunner_free (sr);
     255           1 :   return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
     256             : }
     257             : 

Generated by: LCOV version 1.10