diff options
-rw-r--r-- | source3/lib/sharesec.c | 9 | ||||
-rw-r--r-- | source3/lib/util_tdb.c | 29 | ||||
-rw-r--r-- | source3/param/loadparm.c | 24 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 28 |
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; } |