summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2001-04-16 15:16:31 +0000
committerAndrew Tridgell <tridge@samba.org>2001-04-16 15:16:31 +0000
commit4355098a757885462dd44b94b616014c30eea2bf (patch)
tree64b5bf0f4e47c35a1d97112e90b38ac13fc9adf3
parent8c0a1c61cc3f0dbfe811ff0fadaf1f6c376b59fe (diff)
downloadsamba-4355098a757885462dd44b94b616014c30eea2bf.tar.gz
samba-4355098a757885462dd44b94b616014c30eea2bf.tar.bz2
samba-4355098a757885462dd44b94b616014c30eea2bf.zip
hide unreadable patch from idra
(This used to be commit 7b6cfe243002a92f5dfb52413e9b3550c61cecfb)
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/smbd/dir.c49
3 files changed, 54 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 5d7398b23f..c9c508be6c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1791,6 +1791,7 @@ BOOL lp_shortpreservecase(int );
BOOL lp_casemangle(int );
BOOL lp_status(int );
BOOL lp_hide_dot_files(int );
+BOOL lp_hideunreadable(int );
BOOL lp_browseable(int );
BOOL lp_readonly(int );
BOOL lp_no_set_dir(int );
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 022154f1d8..11697b5044 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -359,6 +359,7 @@ typedef struct
BOOL bCaseMangle;
BOOL status;
BOOL bHideDotFiles;
+ BOOL bHideUnReadable;
BOOL bBrowseable;
BOOL bAvailable;
BOOL bRead_only;
@@ -474,6 +475,7 @@ static service sDefault = {
False, /* case mangle */
True, /* status */
True, /* bHideDotFiles */
+ False, /* bHideUnReadable */
True, /* bBrowseable */
True, /* bAvailable */
True, /* bRead_only */
@@ -871,6 +873,7 @@ static struct parm_struct parm_table[] = {
{"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
{"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_DOS_STRING},
@@ -1649,6 +1652,7 @@ FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
FN_LOCAL_BOOL(lp_status, status)
FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
+FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
FN_LOCAL_BOOL(lp_browseable, bBrowseable)
FN_LOCAL_BOOL(lp_readonly, bRead_only)
FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 5bf0dec944..46078b8d06 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -663,6 +663,36 @@ typedef struct
} Dir;
+
+/*******************************************************************
+check to see if a user can read a file. This is only approximate,
+it is used as part of the "hide unreadable" option. Don't
+use it for anything security sensitive
+********************************************************************/
+static BOOL user_can_read_file(connection_struct *conn, const char *name)
+{
+ struct stat ste;
+
+ /* if we can't stat it does not show it */
+ if (stat(name, &ste) != 0) return False;
+
+ if (ste.st_uid == conn->uid) {
+ return (ste.st_mode & S_IRUSR) == S_IRUSR;
+ } else {
+ int i;
+ if (ste.st_gid == conn->gid) {
+ return (ste.st_mode & S_IRGRP) == S_IRGRP;
+ }
+ for (i=0; i<conn->ngroups; i++) {
+ if (conn->groups[i] == ste.st_gid) {
+ return (ste.st_mode & S_IRGRP) == S_IRGRP;
+ }
+ }
+ }
+
+ return (ste.st_mode & S_IROTH) == S_IROTH;
+}
+
/*******************************************************************
Open a directory.
********************************************************************/
@@ -677,6 +707,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
if (!p) return(NULL);
dirp = (Dir *)malloc(sizeof(Dir));
if (!dirp) {
+ DEBUG(0,("Out of memory in OpenDir\n"));
conn->vfs_ops.closedir(conn,p);
return(NULL);
}
@@ -695,6 +726,24 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
/* If it's a vetoed file, pretend it doesn't even exist */
if (use_veto && conn && IS_VETO_PATH(conn, n)) continue;
+ /* Honour _hide unreadable_ option */
+ if (conn && lp_hideunreadable(SNUM(conn)))
+ {
+ char *entry;
+ int ret;
+
+ entry = (char *)malloc(PATH_MAX);
+ if (!entry) {
+ DEBUG(0,("Out of memory in OpenDir\n"));
+ conn->vfs_ops.closedir(conn,p);
+ return(NULL);
+ }
+ slprintf(entry, PATH_MAX, "%s/%s/%s", conn->origpath, name, n);
+ ret = user_can_read_file(conn, entry);
+ free(entry);
+ if (!ret) continue;
+ }
+
if (used + l > dirp->mallocsize) {
int s = MAX(used+l,used+2000);
char *r;