summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2002-07-27 02:33:49 +0000
committerSimo Sorce <idra@samba.org>2002-07-27 02:33:49 +0000
commit31b4cfd8208a0efd63891eb24827babb88d04ba0 (patch)
tree7a09b5cd6c4502986fecb4cac55043bdb69ffaa8 /source3
parent2ff0939301d738a3f8177ddb6e01781b638ce811 (diff)
downloadsamba-31b4cfd8208a0efd63891eb24827babb88d04ba0.tar.gz
samba-31b4cfd8208a0efd63891eb24827babb88d04ba0.tar.bz2
samba-31b4cfd8208a0efd63891eb24827babb88d04ba0.zip
nice day today
add also hide unwriteable as per user request (This used to be commit e6b38a881b67af5365f84e52f9cd6dcfec82bf2f)
Diffstat (limited to 'source3')
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/smbd/dir.c69
2 files changed, 73 insertions, 0 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index a5f01c6abf..6f976cda64 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -339,6 +339,7 @@ typedef struct
BOOL bCaseMangle;
BOOL bHideDotFiles;
BOOL bHideUnReadable;
+ BOOL bHideUnWriteable;
BOOL bBrowseable;
BOOL bAvailable;
BOOL bRead_only;
@@ -457,6 +458,7 @@ static service sDefault = {
False, /* case mangle */
True, /* bHideDotFiles */
False, /* bHideUnReadable */
+ False, /* bHideUnable */
True, /* bBrowseable */
True, /* bAvailable */
True, /* bRead_only */
@@ -875,6 +877,7 @@ static struct parm_struct parm_table[] = {
{"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},
+ {"hide unwriteable", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteable, 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 },
{"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
@@ -1661,6 +1664,7 @@ FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
+FN_LOCAL_BOOL(lp_hideunwriteable, bHideUnWriteable)
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 7dd425ef8a..01e3063b67 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -722,6 +722,62 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
}
/*******************************************************************
+check to see if a user can write a file. This is only approximate,
+it is used as part of the "hide unwriteable" option. Don't
+use it for anything security sensitive
+********************************************************************/
+
+static BOOL user_can_write_file(connection_struct *conn, char *name)
+{
+ extern struct current_user current_user;
+ SMB_STRUCT_STAT ste;
+ SEC_DESC *psd = NULL;
+ size_t sd_size;
+ files_struct *fsp;
+ int smb_action;
+ int access_mode;
+ NTSTATUS status;
+ uint32 access_granted;
+
+ ZERO_STRUCT(ste);
+
+ /*
+ * If user is a member of the Admin group
+ * we never hide files from them.
+ */
+
+ if (conn->admin_user)
+ return True;
+
+ /* If we can't stat it does not show it */
+ if (vfs_stat(conn, name, &ste) != 0)
+ return False;
+
+ /* Pseudo-open the file (note - no fd's created). */
+
+ if(S_ISDIR(ste.st_mode))
+ fsp = open_directory(conn, name, &ste, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ unix_mode(conn, aDIR, name), &smb_action);
+ else
+ fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+
+ if (!fsp)
+ return False;
+
+ /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
+ sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ close_file(fsp, False);
+
+ /* No access if SD get failed. */
+ if (!sd_size)
+ return False;
+
+ return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
+ &access_granted, &status);
+}
+
+/*******************************************************************
Open a directory.
********************************************************************/
@@ -781,6 +837,19 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
continue;
}
+ /* Honour _hide unwriteable_ option */
+ if (normal_entry && conn && lp_hideunwriteable(SNUM(conn))) {
+ char *entry;
+ int ret=0;
+
+ if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
+ ret = user_can_write_file(conn, entry);
+ SAFE_FREE(entry);
+ }
+ if (!ret)
+ continue;
+ }
+
if (used + l > dirp->mallocsize) {
int s = MAX(used+l,used+2000);
char *r;