[PATCH] s3: Dynamic share permssion detection, part 3; make normal share work.

Bo Yang boyang at samba.org
Mon Nov 30 18:35:48 MST 2009


Signed-off-by: Bo Yang <boyang at samba.org>
---
 source3/lib/dummysmbd.c            |    5 +++
 source3/param/loadparm.c           |   62 ++++++++++++++++++++++++++++++++++--
 source3/rpc_server/srv_srvsvc_nt.c |   12 +++++++
 source3/smbd/process.c             |    3 ++
 4 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c
index 314ec54..c0c90c2 100644
--- a/source3/lib/dummysmbd.c
+++ b/source3/lib/dummysmbd.c
@@ -38,6 +38,11 @@ bool conn_snum_used(int snum)
 	return False;
 }
 
+bool reload_services(bool test)
+{
+	return False;
+}
+
 void conn_disconnect_snum(int snum)
 {
 	return;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index db83c5d..a81aeb7 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -369,6 +369,7 @@ struct service {
 	bool valid;
 	bool autoloaded;
 	int usershare;
+	int pending_delete;
 	struct timespec usershare_last_mod;
 	char *szService;
 	char *szPath;
@@ -512,6 +513,7 @@ static struct service sDefault = {
 	True,			/* valid */
 	False,			/* not autoloaded */
 	0,			/* not a usershare */
+	0,			/* not pending delete */
 	{0, },                  /* No last mod time */
 	NULL,			/* szService */
 	NULL,			/* szPath */
@@ -6201,6 +6203,7 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
 	ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
 
 	ServicePtrs[i]->autoloaded = True;
+	ServicePtrs[i]->pending_delete = 0;
 
 	DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
 	       user, ServicePtrs[i]->szPath ));
@@ -6250,6 +6253,7 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
 	ServicePtrs[i]->bGuest_ok = guest_ok;
 	ServicePtrs[i]->bPrint_ok = False;
 	ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
+	ServicePtrs[i]->pending_delete = 0;
 
 	DEBUG(3, ("adding IPC service\n"));
 
@@ -6289,6 +6293,7 @@ bool lp_add_printer(const char *pszPrintername, int iDefaultService)
 	ServicePtrs[i]->bOpLocks = False;
 	/* Printer services must be printable. */
 	ServicePtrs[i]->bPrint_ok = True;
+	ServicePtrs[i]->pending_delete = 0;
 
 	DEBUG(3, ("adding printer service %s\n", pszPrintername));
 
@@ -7808,6 +7813,9 @@ static bool do_section(const char *pszSectionName, void *userdata)
 		}
 	}
 
+	/* clear the pending delete flags here. */
+	ServicePtrs[iServiceIndex]->pending_delete = 0;
+
 	return (bRetval);
 }
 
@@ -8762,6 +8770,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
 
 	/* Set the service as a valid usershare. */
 	ServicePtrs[iService]->usershare = USERSHARE_VALID;
+	ServicePtrs[iService]->pending_delete = 0;
 
 	/* Set guest access. */
 	if (lp_usershare_allow_guests()) {
@@ -9860,6 +9869,30 @@ static int find_service_by_name(const char *pszServiceName)
 	return GLOBAL_SECTION_SNUM;
 }
 
+static bool usershare_file_exists(const char *serviceName)
+{
+	SMB_STRUCT_STAT lsbuf;
+	const char *usersharepath = Globals.szUsersharePath;
+	char *fname;
+
+	if (asprintf(&fname, "%s/%s", usersharepath, serviceName) < 0) {
+		return false;
+	}
+
+	if (sys_lstat(fname, &lsbuf) != 0) {
+		SAFE_FREE(fname);
+		return false;
+	}
+
+	if (!S_ISREG(lsbuf.st_ex_mode)) {
+		SAFE_FREE(fname);
+		return false;
+	}
+
+	SAFE_FREE(fname);
+	return true;
+}
+
 void msg_reevaluate_share(struct messaging_context *ctx,
 				void *private_data,
 				uint32_t msg_type,
@@ -9868,16 +9901,25 @@ void msg_reevaluate_share(struct messaging_context *ctx,
 {
 	const char *serviceName = (char *)data->data;
 	int iService = -1, retval;
+	struct timespec last_mod;
+	change_to_root_user();
 	iService = getservicebyname(serviceName, NULL);
 	if (iService < 0) {
-		/* The share is not even loaded, return. */
+		/* 
+		 * The share is not even loaded, it may be newly added usershare
+		 * or normal share.
+		 */
+		if (usershare_file_exists(serviceName)) {
+			/* No need to load new usershare. */
+			return;
+		}
+		/* This may be a newly added normal share, reload. */
+		reload_services(False);
 		return;
 	}
 	
 	/* found usershare service. */
 	if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_VALID)) {
-		struct timespec last_mod;
-
 		if (!usershare_exists(iService, &last_mod)) {
 			/* Remove the share security tdb entry for it. */
 			delete_share_security(lp_servicename(iService));
@@ -9905,6 +9947,20 @@ void msg_reevaluate_share(struct messaging_context *ctx,
 		return;
 	}
 
+	/* Normal share. */
+	if (VALID(iService) && !ServicePtrs[iService]->usershare
+	    && !ServicePtrs[iService]->autoloaded) {
+		ServicePtrs[iService]->pending_delete = 1;
+		reload_services(False);
+		if (ServicePtrs[iService]->pending_delete) {
+			/* delete this service. */
+			delete_share_security(lp_servicename(iService));
+			conn_disconnect_snum(iService);
+			free_service_byindex(iService);
+		}
+		return;
+	}
+
 	/* Other type of services can be handled here. */
 
 	return;
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index d35557e..bad341e 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -1668,6 +1668,9 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
 			message_send_all(smbd_messaging_context(),
 					 MSG_SMB_CONF_UPDATED, NULL, 0,
 					 NULL);
+			message_send_all(smbd_messaging_context(),
+					 MSG_SMB_REEVALUATE_SHARE, share_name,
+					 strlen(share_name) + 1, NULL);
 		}
 
 		if ( is_disk_op )
@@ -1855,6 +1858,9 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p,
 		/* Tell everyone we updated smb.conf. */
 		message_send_all(smbd_messaging_context(),
 				 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
+		message_send_all(smbd_messaging_context(),
+				 MSG_SMB_REEVALUATE_SHARE, share_name,
+				 strlen(share_name) + 1, NULL);
 	}
 
 	if ( is_disk_op )
@@ -1959,6 +1965,9 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p,
 		/* Tell everyone we updated smb.conf. */
 		message_send_all(smbd_messaging_context(),
 				 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
+		message_send_all(smbd_messaging_context(),
+				 MSG_SMB_REEVALUATE_SHARE, share_name,
+				 strlen(share_name) + 1, NULL);
 	}
 
 	if ( is_disk_op )
@@ -1971,10 +1980,13 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p,
 	if ( ret != 0 )
 		return WERR_ACCESS_DENIED;
 
+#if 0
+	/* Let this be done in the message handler. */
 	/* Delete the SD in the database. */
 	delete_share_security(lp_servicename(params->service));
 
 	lp_killservice(params->service);
+#endif
 
 	return WERR_OK;
 }
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 965928e..022ee71 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1347,11 +1347,14 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
 		 * without cache to update connection struct
 		 */
 		if (flags & NEED_WRITE) {
+			become_root();
 			if (!check_share_perm_without_cache(conn, session_tag)) {
 				DEBUG(4, ("Error: cannot access share!\n"));
 				reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+				unbecome_root();
 				return conn;
 			}
+			unbecome_root();
 			if (!CAN_WRITE(conn)) {
 				reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
 				return conn;
-- 
1.5.3


--------------020706050703070905050801
Content-Type: text/x-patch;
 name="dynamic-share-permission-master-part-4-bug-fix-mbox.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="dynamic-share-permission-master-part-4-bug-fix-mbox.diff"



More information about the samba-technical mailing list