summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c258
1 files changed, 198 insertions, 60 deletions
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 1bff054aa4..5c1c16c02a 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -95,10 +95,43 @@ static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
}
/*******************************************************************
- Fake up a Everyone, full access for now.
+ Create the share security tdb.
********************************************************************/
-static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
+static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
+#define SHARE_DATABASE_VERSION 1
+
+BOOL share_info_db_init(void)
+{
+ static pid_t local_pid;
+ char *vstring = "INFO/version";
+
+ if (share_tdb && local_pid == sys_getpid()) return True;
+ share_tdb = tdb_open(lock_path("share_info.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
+ if (!share_tdb) {
+ DEBUG(0,("Failed to open share info database %s (%s)\n",
+ lock_path("share_info.tdb"), strerror(errno) ));
+ return False;
+ }
+
+ local_pid = sys_getpid();
+
+ /* handle a Samba upgrade */
+ tdb_lock_bystring(share_tdb, vstring);
+ if (tdb_fetch_int(share_tdb, vstring) != SHARE_DATABASE_VERSION) {
+ tdb_traverse(share_tdb, (tdb_traverse_func)tdb_delete, NULL);
+ tdb_store_int(share_tdb, vstring, SHARE_DATABASE_VERSION);
+ }
+ tdb_unlock_bystring(share_tdb, vstring);
+
+ return True;
+}
+
+/*******************************************************************
+ Fake up a Everyone, full access as a default.
+ ********************************************************************/
+
+static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
{
extern DOM_SID global_sid_World;
SEC_ACCESS sa;
@@ -122,6 +155,94 @@ static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
}
/*******************************************************************
+ Pull a security descriptor from the share tdb.
+ ********************************************************************/
+
+SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
+{
+ prs_struct ps;
+ fstring key;
+ SEC_DESC *psd;
+
+ /* Fetch security descriptor from tdb */
+
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+
+ if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
+ !sec_io_desc("get_share_security", &psd, &ps, 1)) {
+
+ DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
+
+ return get_share_security_default(ctx, snum, psize);
+ }
+
+ prs_mem_free(&ps);
+ return psd;
+}
+
+/*******************************************************************
+ Store a security descriptor in the share db.
+ ********************************************************************/
+
+static BOOL set_share_security(TALLOC_CTX *ctx, int snum, SEC_DESC *psd)
+{
+ prs_struct ps;
+ TALLOC_CTX *mem_ctx = NULL;
+ fstring key;
+ BOOL ret = False;
+
+ mem_ctx = talloc_init();
+ if (mem_ctx == NULL)
+ return False;
+
+ prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
+
+ if (!sec_io_desc("nt_printing_setsec", &psd, &ps, 1)) {
+ goto out;
+ }
+
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+
+ if (tdb_prs_store(share_tdb, key, &ps)==0) {
+ ret = True;
+ DEBUG(5,("set_share_security: stored secdesc for %s\n", lp_servicename(snum) ));
+ } else {
+ DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", lp_servicename(snum) ));
+ }
+
+ /* Free malloc'ed memory */
+
+ out:
+
+ prs_mem_free(&ps);
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return ret;
+}
+
+/*******************************************************************
+ Delete a security descriptor.
+********************************************************************/
+
+static BOOL delete_share_security(int snum)
+{
+ TDB_DATA kbuf;
+ fstring key;
+
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+ kbuf.dptr = key;
+ kbuf.dsize = strlen(key)+1;
+
+ if (tdb_delete(share_tdb, kbuf) != 0) {
+ DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
+ lp_servicename(snum) ));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
Fill in a share info level 502 structure.
********************************************************************/
@@ -942,62 +1063,6 @@ uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
}
/*******************************************************************
- Net share set info.
-********************************************************************/
-
-uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
-{
- fstring share_name;
- uint32 status = NT_STATUS_NOPROBLEMO;
- int snum;
-#if 0
- fstring servicename;
- fstring comment;
- pstring pathname;
-#endif
-
- DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
-
- unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
-
- r_u->switch_value = 0;
-
- snum = find_service(share_name);
-
- /* For now we only handle setting the security descriptor. JRA. */
-
- if (snum >= 0) {
- switch (q_u->info_level) {
- case 1:
- status = ERROR_ACCESS_DENIED;
- break;
- case 2:
- status = ERROR_ACCESS_DENIED;
- break;
- case 502:
- /* we set sd's here. FIXME. JRA */
- status = ERROR_ACCESS_DENIED;
- break;
- case 1005:
- status = ERROR_ACCESS_DENIED;
- break;
- default:
- DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
- status = NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
- } else {
- status = NT_STATUS_BAD_NETWORK_NAME;
- }
-
- r_u->status = status;
-
- DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
-
- return r_u->status;
-}
-
-/*******************************************************************
Check a given DOS pathname is valid for a share.
********************************************************************/
@@ -1041,6 +1106,68 @@ static char *valid_share_pathname(char *dos_pathname)
}
/*******************************************************************
+ Net share set info. Modify share details.
+********************************************************************/
+
+uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
+{
+ struct current_user user;
+ pstring command;
+ fstring share_name;
+ fstring comment;
+ pstring pathname;
+ int type;
+ int snum;
+ int ret;
+ char *ptr;
+ BOOL read_only;
+
+ DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
+
+ unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
+
+ r_u->switch_value = 0;
+
+ snum = find_service(share_name);
+
+ /* Does this share exist ? */
+ if (snum < 0)
+ return NT_STATUS_BAD_NETWORK_NAME;
+
+ get_current_user(&user,p);
+
+ if (user.uid != 0)
+ return ERROR_ACCESS_DENIED;
+
+ if (!lp_change_share_cmd())
+ return ERROR_ACCESS_DENIED;
+
+ switch (q_u->info_level) {
+ case 1:
+ return ERROR_ACCESS_DENIED;
+ break;
+ case 2:
+ return ERROR_ACCESS_DENIED;
+ break;
+ case 502:
+ /* we set sd's here. FIXME. JRA */
+ return ERROR_ACCESS_DENIED;
+ break;
+ case 1005:
+ return ERROR_ACCESS_DENIED;
+ break;
+ default:
+ DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+
+ DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
Net share add. Call 'add_share_command "sharename" "pathname" "comment"'
********************************************************************/
@@ -1055,6 +1182,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
int snum;
int ret;
char *ptr;
+ BOOL read_only = False;
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
@@ -1077,6 +1205,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
type = q_u->info.share.info2.info_2.type;
+ read_only = False; /* No SD means "Everyone full access. */
break;
case 502:
/* we set sd's here. FIXME. JRA */
@@ -1107,8 +1236,14 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
if (!(ptr = valid_share_pathname( pathname )))
return ERRbadpath;
- slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), share_name, ptr, comment );
+ /* Ensure share name, pathname and comment don't contain '"' characters. */
+ string_replace(share_name, '"', ' ');
+ string_replace(ptr, '"', ' ');
+ string_replace(comment, '"', ' ');
+
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
+ lp_add_share_cmd(), share_name, ptr, comment,
+ read_only ? "read only = yes" : "read only = no" );
dos_to_unix(command, True); /* Convert to unix-codepage */
DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
@@ -1170,6 +1305,9 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
return ERROR_ACCESS_DENIED;
}
+ /* Delete the SD in the database. */
+ delete_share_security(snum);
+
/* Send SIGHUP to process group. */
kill(0, SIGHUP);