filter-sharelist-by-access [plain text]
Index: samba/source/smbd/darwin_check_share_access.c
===================================================================
--- /dev/null
+++ samba/source/smbd/darwin_check_share_access.c
@@ -0,0 +1,63 @@
+/*
+ * Darwin check share access
+ *
+ * Copyright (c) 2007 Apple Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This header has to be here due to preprocessor conflicts with Samba
+ * headers.
+ */
+#include "includes.h"
+#include <sys/attr.h>
+
+/*
+ * Given a path to a share check the users access. The
+ * user needs to be able to read or write to the share point.
+ *
+ * Note: This routine doesn't handle the "force user" option.
+ */
+BOOL check_share_access(const char *path)
+{
+ struct attrlist attrlist;
+ u_int32_t attrbuf[2]; /* Length field and access modes */
+
+ ZERO_STRUCT(attrlist);
+ ZERO_STRUCT(attrbuf);
+ attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
+ attrlist.commonattr = ATTR_CMN_USERACCESS;
+ /* Call getattrlist to get the real volume name */
+ if (getattrlist(path, &attrlist, attrbuf, sizeof(attrbuf), 0) != 0) {
+ if (errno == EACCES) {
+ DEBUG(5, ("getattrlist for %s failed: %s disallowing access!\n", path, strerror(errno)));
+ return False;
+ }
+ DEBUG(10, ("getattrlist for %s failed: %s allowing access!\n", path, strerror(errno)));
+ return True;
+ }
+ /* Check the length just to be safe */
+ if (attrbuf[0] < sizeof(attrbuf)) {
+ DEBUG(10, ("getattrlist for %s returned a bad length (%d) allowing access!\n", path, attrbuf[0]));
+ return True;
+ }
+ /* Make sure they have read or write access */
+ if ((attrbuf[1] & X_OK) && ((attrbuf[1] & R_OK) || (attrbuf[1] & W_OK)) ) {
+ DEBUG(10, ("%s allowing access 0x%x\n", path, attrbuf[1]));
+ return True;
+ }
+ DEBUG(5, ("%s disallowing access 0x%x\n", path, attrbuf[1]));
+ return False;
+}
Index: samba/source/rpc_server/srv_srvsvc_nt.c
===================================================================
--- samba/source/rpc_server/srv_srvsvc_nt.c.orig
+++ samba/source/rpc_server/srv_srvsvc_nt.c
@@ -469,8 +469,15 @@ static BOOL init_srv_share_info_ctr(pipe
/* Count the number of entries. */
for (snum = 0; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
+ if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
+ if ((lp_parm_bool(snum, "com.apple", "filter shares by access", False) == False) ||
+ (check_share_access(lp_pathname(snum)) == True))
num_entries++;
+ else {
+ DEBUG(10,("Marking service %s unbrowseable - path = %s\n", lp_servicename(snum), lp_pathname(snum)));
+ lp_set_browseable(snum, False);
+ }
+ }
}
*total_entries = num_entries;
Index: samba/source/smbd/lanman.c
===================================================================
--- samba/source/smbd/lanman.c.orig
+++ samba/source/smbd/lanman.c
@@ -1735,6 +1735,13 @@ static BOOL api_RNetShareEnum( connectio
if (!(lp_browseable(i) && lp_snum_ok(i))) {
continue;
}
+ if ((lp_parm_bool(i, "com.apple", "filter shares by access", False) == True) &&
+ (check_share_access(lp_pathname(i)) == False)) {
+ DEBUG(10,("Marking service %s unbrowseable - path = %s\n", lp_servicename(i), lp_pathname(i)));
+ lp_set_browseable(i, False);
+ continue;
+ }
+
push_ascii_fstring(servicename_dos, lp_servicename(i));
/* Maximum name length = 13. */
if( lp_browseable( i ) && lp_snum_ok( i ) && (strlen(servicename_dos) < 13)) {
Index: samba/source/Makefile.in
===================================================================
--- samba/source/Makefile.in.orig
+++ samba/source/Makefile.in
@@ -481,6 +481,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpass
smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
$(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
smbd/darwin_clone_local_volumes.o \
+ smbd/darwin_check_share_access.o \
smbd/dmapi.o lib/opendirectory.o \
lib/launchd.o smbd/sockinit.o \
$(MANGLE_OBJ) @VFS_STATIC@
Index: samba/source/param/loadparm.c
===================================================================
--- samba/source/param/loadparm.c.orig
+++ samba/source/param/loadparm.c
@@ -5967,3 +5967,14 @@ void lp_set_posix_default_cifsx_readwrit
posix_default_lock_was_set = True;
posix_cifsx_locktype = val;
}
+
+/***************************************************************************
+ Make the service browseable or not.
+***************************************************************************/
+
+void lp_set_browseable(int snum, BOOL val)
+{
+ if (LP_SNUM_OK(snum)) {
+ ServicePtrs[snum]->bBrowseable = val;
+ }
+}