summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/sharesec.c9
-rw-r--r--source3/lib/util_tdb.c29
-rw-r--r--source3/param/loadparm.c24
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c28
4 files changed, 69 insertions, 21 deletions
diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c
index 0c8035e3dc..81b383d167 100644
--- a/source3/lib/sharesec.c
+++ b/source3/lib/sharesec.c
@@ -188,18 +188,19 @@ out:
Delete a security descriptor.
********************************************************************/
-BOOL delete_share_security(int snum)
+BOOL delete_share_security(const struct share_params *params)
{
TDB_DATA kbuf;
fstring key;
- slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+ slprintf(key, sizeof(key)-1, "SECDESC/%s",
+ lp_servicename(params->service));
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
- if (tdb_delete(share_tdb, kbuf) != 0) {
+ if (tdb_trans_delete(share_tdb, kbuf) != 0) {
DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
- lp_servicename(snum) ));
+ lp_servicename(params->service) ));
return False;
}
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 3e18c09fbf..e847c79369 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -809,3 +809,32 @@ int tdb_trans_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
return res;
}
+
+/****************************************************************************
+ tdb_delete, wrapped in a transaction. This way we make sure that a process
+ that dies within deleting does not leave a corrupt tdb behind.
+****************************************************************************/
+
+int tdb_trans_delete(struct tdb_context *tdb, TDB_DATA key)
+{
+ int res;
+
+ if ((res = tdb_transaction_start(tdb)) != 0) {
+ DEBUG(5, ("tdb_transaction_start failed\n"));
+ return res;
+ }
+
+ if ((res = tdb_delete(tdb, key)) != 0) {
+ DEBUG(10, ("tdb_delete failed\n"));
+ if (tdb_transaction_cancel(tdb) != 0) {
+ smb_panic("Cancelling transaction failed\n");
+ }
+ return res;
+ }
+
+ if ((res = tdb_transaction_commit(tdb)) != 0) {
+ DEBUG(5, ("tdb_transaction_commit failed\n"));
+ }
+
+ return res;
+}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 0dff2e36c7..fe1dc8ec50 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -4879,7 +4879,7 @@ int load_usershare_shares(void)
/* Remove from the share ACL db. */
DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
lp_servicename(iService) ));
- delete_share_security(iService);
+ delete_share_security(snum2params_static(iService));
free_service_byindex(iService);
}
}
@@ -5113,7 +5113,7 @@ int lp_servicenumber(const char *pszServiceName)
if (!usershare_exists(iService, &last_mod)) {
/* Remove the share security tdb entry for it. */
- delete_share_security(iService);
+ delete_share_security(snum2params_static(iService));
/* Remove it from the array. */
free_service_byindex(iService);
/* Doesn't exist anymore. */
@@ -5146,12 +5146,16 @@ struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
const char *sharename)
{
struct share_params *result;
- fstring sname;
+ char *sname;
int snum;
- fstrcpy(sname, sharename);
+ if (!(sname = SMB_STRDUP(sharename))) {
+ return NULL;
+ }
snum = find_service(sname);
+ SAFE_FREE(sname);
+
if (snum < 0) {
return NULL;
}
@@ -5213,6 +5217,18 @@ struct share_params *next_printer(struct share_iterator *list)
return result;
}
+/*
+ * This is a hack for a transition period until we transformed all code from
+ * service numbers to struct share_params.
+ */
+
+struct share_params *snum2params_static(int snum)
+{
+ static struct share_params result;
+ result.service = snum;
+ return &result;
+}
+
/*******************************************************************
A useful volume label function.
********************************************************************/
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index ec39c2a482..0e7f749a4e 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -1680,12 +1680,11 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t lev
WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
{
- pstring command;
+ char *command;
int ret;
- int snum;
+ struct share_params *params;
SE_PRIV se_diskop = SE_DISK_OPERATOR;
BOOL is_disk_op;
- fstring tmp_share_name;
DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
@@ -1696,14 +1695,12 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *
return WERR_ACCESS_DENIED;
}
- fstrcpy(tmp_share_name, share_name);
- snum = find_service(tmp_share_name);
-
- if (snum < 0)
+ if (!(params = get_share_params(p->mem_ctx, share_name))) {
return WERR_NO_SUCH_SHARE;
+ }
/* No change to printer shares. */
- if (lp_print_ok(snum))
+ if (lp_print_ok(params->service))
return WERR_ACCESS_DENIED;
is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
@@ -1715,9 +1712,12 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *
DEBUG(10,("_srv_net_share_del: No delete share command\n"));
return WERR_ACCESS_DENIED;
}
-
- slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
- lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
+
+ if (asprintf(&command, "%s \"%s\" \"%s\"",
+ lp_delete_share_cmd(), dyn_CONFIGFILE,
+ lp_servicename(params->service)) == -1) {
+ return WERR_NOMEM;
+ }
DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
@@ -1733,6 +1733,8 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *
if ( is_disk_op )
unbecome_root();
+
+ SAFE_FREE(command);
/********* END SeDiskOperatorPrivilege BLOCK *********/
@@ -1742,9 +1744,9 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *
return WERR_ACCESS_DENIED;
/* Delete the SD in the database. */
- delete_share_security(snum);
+ delete_share_security(params);
- lp_killservice(snum);
+ lp_killservice(params->service);
return WERR_OK;
}