From fc8e308ea06aff671dc1d21e99e8b42bf5c2fda1 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Wed, 7 Nov 2012 16:56:55 +0000 Subject: [PATCH] Parameterized directory listing permission check --- src/chat/chat.c | 2 +- src/fs/fs_api.c | 8 +++--- src/fs/gnunet-auto-share.c | 2 +- src/include/gnunet_disk_lib.h | 15 ++++++----- src/mesh/gnunet-regex-profiler.c | 2 +- src/regex/gnunet-regex-simulation-profiler.c | 2 +- src/util/disk.c | 28 ++++++++++++-------- src/util/test_disk.c | 2 +- 8 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/chat/chat.c b/src/chat/chat.c index 26f8f2e38..b2078e563 100644 --- a/src/chat/chat.c +++ b/src/chat/chat.c @@ -473,7 +473,7 @@ init_private_key (const struct GNUNET_CONFIGURATION_Handle *cfg, return NULL; } GNUNET_DISK_directory_create (home); - if (GNUNET_OK != GNUNET_DISK_directory_test (home)) + if (GNUNET_OK != GNUNET_DISK_directory_test (home, GNUNET_YES)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to access chat home directory `%s'\n"), home); diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c index 059c70ba6..f03cdb8e4 100644 --- a/src/fs/fs_api.c +++ b/src/fs/fs_api.c @@ -738,7 +738,7 @@ GNUNET_FS_remove_sync_dir_ (struct GNUNET_FS_Handle *h, const char *ext, dn = get_serialization_file_name_in_dir (h, ext, uni, ""); if (NULL == dn) return; - if ((GNUNET_OK == GNUNET_DISK_directory_test (dn)) && + if ((GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) && (GNUNET_OK != GNUNET_DISK_directory_remove (dn))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rmdir", dn); GNUNET_free (dn); @@ -2700,7 +2700,7 @@ deserialize_download (struct GNUNET_FS_Handle *h, dn = get_download_sync_filename (dc, dc->serialization, ".dir"); if (NULL != dn) { - if (GNUNET_YES == GNUNET_DISK_directory_test (dn)) + if (GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) GNUNET_DISK_directory_scan (dn, &deserialize_subdownload, dc); GNUNET_free (dn); } @@ -2813,7 +2813,7 @@ deserialize_search (struct GNUNET_FS_Handle *h, sc->serialization, ""); if (NULL != dn) { - if (GNUNET_YES == GNUNET_DISK_directory_test (dn)) + if (GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) GNUNET_DISK_directory_scan (dn, &deserialize_search_result, sc); GNUNET_free (dn); } @@ -2940,7 +2940,7 @@ deserialization_master (const char *master_path, GNUNET_FileNameCallback proc, dn = get_serialization_file_name (h, master_path, ""); if (NULL == dn) return; - if (GNUNET_YES == GNUNET_DISK_directory_test (dn)) + if (GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) GNUNET_DISK_directory_scan (dn, proc, h); GNUNET_free (dn); } diff --git a/src/fs/gnunet-auto-share.c b/src/fs/gnunet-auto-share.c index e0514bc8f..86cab5593 100644 --- a/src/fs/gnunet-auto-share.c +++ b/src/fs/gnunet-auto-share.c @@ -681,7 +681,7 @@ run (void *cls, char *const *args, const char *cfgfile, { /* check arguments */ if ((args[0] == NULL) || (args[1] != NULL) || - (GNUNET_YES != GNUNET_DISK_directory_test (args[0]))) + (GNUNET_YES != GNUNET_DISK_directory_test (args[0], GNUNET_YES))) { printf (_("You must specify one and only one directory name for automatic publication.\n")); ret = -1; diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index 91cc1587a..73736be31 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -663,17 +663,18 @@ GNUNET_DISK_directory_create_for_file (const char *filename); /** - * Test if "fil" is a directory that can be accessed. - * Will not print an error message if the directory - * does not exist. Will log errors if GNUNET_SYSERR is - * returned. + * Test if "fil" is a directory and readable. Also check if the directory is + * listable. Will not print an error message if the directory does not exist. + * Will log errors if GNUNET_SYSERR is returned (i.e., a file exists with the + * same name). * * @param fil filename to test - * @return GNUNET_YES if yes, GNUNET_NO if does not exist, GNUNET_SYSERR - * on any error and if exists but not directory + * @param is_listable GNUNET_YES to additionally check if "fil" is listable + * @return GNUNET_YES if yes, GNUNET_NO if not, GNUNET_SYSERR if it + * does not exist */ int -GNUNET_DISK_directory_test (const char *fil); +GNUNET_DISK_directory_test (const char *fil, int is_listable); /** diff --git a/src/mesh/gnunet-regex-profiler.c b/src/mesh/gnunet-regex-profiler.c index 6b3566823..9e4f1b2f8 100644 --- a/src/mesh/gnunet-regex-profiler.c +++ b/src/mesh/gnunet-regex-profiler.c @@ -1711,7 +1711,7 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", data_filename); - if (GNUNET_YES != GNUNET_DISK_directory_test (args[1])) + if (GNUNET_YES != GNUNET_DISK_directory_test (args[1], GNUNET_YES)) { fprintf (stderr, _("Specified policies directory does not exist. Exiting.\n")); shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); diff --git a/src/regex/gnunet-regex-simulation-profiler.c b/src/regex/gnunet-regex-simulation-profiler.c index 74e88ea9f..4bb033ea6 100644 --- a/src/regex/gnunet-regex-simulation-profiler.c +++ b/src/regex/gnunet-regex-simulation-profiler.c @@ -499,7 +499,7 @@ run (void *cls, char *const *args, const char *cfgfile, result = GNUNET_SYSERR; return; } - if (GNUNET_YES != GNUNET_DISK_directory_test (args[0])) + if (GNUNET_YES != GNUNET_DISK_directory_test (args[0], GNUNET_YES)) { fprintf (stderr, _("Specified policies directory does not exist. Exiting.\n")); result = GNUNET_SYSERR; diff --git a/src/util/disk.c b/src/util/disk.c index 82cc9ddab..ae9135b0c 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -584,17 +584,19 @@ GNUNET_DISK_get_blocks_available (const char *part) /** - * Test if "fil" is a directory. - * Will not print an error message if the directory - * does not exist. Will log errors if GNUNET_SYSERR is - * returned (i.e., a file exists with the same name). + * Test if "fil" is a directory and readable. Also check if the directory is + * listable. Will not print an error message if the directory does not exist. + * Will log errors if GNUNET_SYSERR is returned (i.e., a file exists with the + * same name). * * @param fil filename to test - * @return GNUNET_YES if yes, GNUNET_NO if not, GNUNET_SYSERR if it - * does not exist + * @param is_listable GNUNET_YES to additionally check if "fil" is listable; + * GNUNET_NO to disable this check + * @return GNUNET_YES if yes, GNUNET_NO if not; GNUNET_SYSERR if it + * does not exist */ int -GNUNET_DISK_directory_test (const char *fil) +GNUNET_DISK_directory_test (const char *fil, int is_listable) { struct stat filestat; int ret; @@ -611,7 +613,11 @@ GNUNET_DISK_directory_test (const char *fil) } if (!S_ISDIR (filestat.st_mode)) return GNUNET_NO; - if (ACCESS (fil, R_OK | X_OK) < 0) + if (GNUNET_YES == is_listable) + ret = ACCESS (fil, R_OK | X_OK); + else + ret = ACCESS (fil, R_OK); + if (ret < 0) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", fil); return GNUNET_SYSERR; @@ -716,7 +722,7 @@ GNUNET_DISK_directory_create (const char *dir) if (DIR_SEPARATOR == rdir[pos2]) { rdir[pos2] = '\0'; - ret = GNUNET_DISK_directory_test (rdir); + ret = GNUNET_DISK_directory_test (rdir, GNUNET_YES); if (GNUNET_SYSERR == ret) { GNUNET_free (rdir); @@ -740,7 +746,7 @@ GNUNET_DISK_directory_create (const char *dir) if ((rdir[pos] == DIR_SEPARATOR) || (pos == len)) { rdir[pos] = '\0'; - ret = GNUNET_DISK_directory_test (rdir); + ret = GNUNET_DISK_directory_test (rdir, GNUNET_YES); if (ret == GNUNET_SYSERR) { GNUNET_free (rdir); @@ -1393,7 +1399,7 @@ GNUNET_DISK_directory_remove (const char *filename) /* EISDIR is not sufficient in all cases, e.g. * sticky /tmp directory may result in EPERM on BSD. * So we also explicitly check "isDirectory" */ - (GNUNET_YES != GNUNET_DISK_directory_test (filename))) + (GNUNET_YES != GNUNET_DISK_directory_test (filename, GNUNET_YES))) { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "rmdir", filename); return GNUNET_SYSERR; diff --git a/src/util/test_disk.c b/src/util/test_disk.c index 149cec0b2..804a870e5 100644 --- a/src/util/test_disk.c +++ b/src/util/test_disk.c @@ -250,7 +250,7 @@ testDirMani () return 1; if (GNUNET_OK != GNUNET_DISK_directory_create ("test")) return 1; - if (GNUNET_YES != GNUNET_DISK_directory_test ("test")) + if (GNUNET_YES != GNUNET_DISK_directory_test ("test", GNUNET_YES)) return 1; if (GNUNET_OK != GNUNET_DISK_directory_remove ("test")) return 1; -- 2.25.1