[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