summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/include/rpc_srvsvc.h12
-rw-r--r--source3/rpc_parse/parse_srv.c49
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c48
4 files changed, 95 insertions, 15 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index a41c810816..e5e4b7eb2f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -3765,6 +3765,7 @@ BOOL api_srvsvc_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_srvsvc_nt.c */
BOOL share_info_db_init(void);
+void map_generic_share_sd_bits(SEC_DESC *psd);
BOOL share_access_check(int snum, uint16 vuid, uint32 desired_access);
uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u);
uint32 _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u);
diff --git a/source3/include/rpc_srvsvc.h b/source3/include/rpc_srvsvc.h
index 3fb76e82e0..2224f38766 100644
--- a/source3/include/rpc_srvsvc.h
+++ b/source3/include/rpc_srvsvc.h
@@ -339,7 +339,6 @@ typedef struct str_share_info502
} SH_INFO_502_STR;
/* SRV_SHARE_INFO_502 */
-/* SRV_SHARE_INFO_2 */
typedef struct share_info_502_info
{
SH_INFO_502 info_502;
@@ -353,6 +352,12 @@ typedef struct share_info_1005_info
uint32 dfs_root_flag;
} SRV_SHARE_INFO_1005;
+/* SRV_SHARE_INFO_1501 */
+typedef struct share_info_1501_info
+{
+ SEC_DESC_BUF *sdb;
+} SRV_SHARE_INFO_1501;
+
/* SRV_SHARE_INFO_CTR */
typedef struct srv_share_info_ctr_info
{
@@ -413,6 +418,8 @@ typedef struct q_net_share_get_info_info
} SRV_Q_NET_SHARE_GET_INFO;
+/* JRA. NB. We also need level 1004 and 1006 here. */
+
/* SRV_SHARE_INFO */
typedef struct srv_share_info {
uint32 switch_value;
@@ -423,6 +430,7 @@ typedef struct srv_share_info {
SRV_SHARE_INFO_2 info2;
SRV_SHARE_INFO_502 info502;
SRV_SHARE_INFO_1005 info1005;
+ SRV_SHARE_INFO_1501 info1501;
} share;
} SRV_SHARE_INFO;
@@ -434,8 +442,6 @@ typedef struct r_net_share_get_info_info
} SRV_R_NET_SHARE_GET_INFO;
-/* JRA. NB. We also need level 1004, 1006 and 1501 here. */
-
/* SRV_Q_NET_SHARE_SET_INFO */
typedef struct q_net_share_set_info_info
{
diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c
index b9479a7105..61d2ff7ba2 100644
--- a/source3/rpc_parse/parse_srv.c
+++ b/source3/rpc_parse/parse_srv.c
@@ -340,22 +340,45 @@ static BOOL srv_io_share_info502_str(char *desc, SH_INFO_502_STR *sh502, prs_str
/*******************************************************************
Reads or writes a structure.
********************************************************************/
+
static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005,
prs_struct* ps, int depth)
{
- if(sh1005 == NULL)
- return False;
+ if(sh1005 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "srv_io_share_info1005");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("dfs_root_flag", ps, depth, &sh1005->dfs_root_flag))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info1501(char* desc, SRV_SHARE_INFO_1501* sh1501,
+ prs_struct* ps, int depth)
+{
+ if(sh1501 == NULL)
+ return False;
- prs_debug(ps, depth, desc, "srv_io_share_info1005");
- depth++;
+ prs_debug(ps, depth, desc, "srv_io_share_info1501");
+ depth++;
- if(!prs_align(ps))
- return False;
+ if(!prs_align(ps))
+ return False;
- if(!prs_uint32("dfs_root_flag", ps, depth, &sh1005->dfs_root_flag))
- return False;
+ if (!sec_io_desc_buf(desc, &sh1501->sdb, ps, depth))
+ return False;
- return True;
+ return True;
}
/*******************************************************************
@@ -656,8 +679,12 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA
return False;
break;
case 1005:
- if(!srv_io_share_info1005("", &r_n->share.info1005, ps, depth))
- return False;
+ if(!srv_io_share_info1005("", &r_n->share.info1005, ps, depth))
+ return False;
+ break;
+ case 1501:
+ if (!srv_io_share_info1501("", &r_n->share.info1501, ps, depth))
+ return False;
default:
DEBUG(5,("%s no share info at switch_value %d\n",
tab_depth(depth), r_n->switch_value));
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index e78968a6bb..9860df6f62 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -253,8 +253,12 @@ static BOOL delete_share_security(int snum)
static BOOL read_only_share_sd(SEC_DESC *psd)
{
int i;
- SEC_ACL *ps_dacl = psd->dacl;
+ SEC_ACL *ps_dacl = NULL;
+ if (!psd)
+ return True;
+
+ ps_dacl = psd->dacl;
if (!ps_dacl)
return True;
@@ -270,6 +274,32 @@ static BOOL read_only_share_sd(SEC_DESC *psd)
}
/*******************************************************************
+ Map any generic bits to file specific bits.
+********************************************************************/
+
+void map_generic_share_sd_bits(SEC_DESC *psd)
+{
+ extern struct generic_mapping file_generic_mapping;
+ int i;
+ SEC_ACL *ps_dacl = NULL;
+
+ if (!psd)
+ return;
+
+ ps_dacl = psd->dacl;
+ if (!ps_dacl)
+ return;
+
+ for (i = 0; i < ps_dacl->num_aces; i++) {
+ SEC_ACE *psa = &ps_dacl->ace[i];
+ uint32 orig_mask = psa->info.mask;
+
+ se_map_generic(&psa->info.mask, &file_generic_mapping);
+ psa->info.mask |= orig_mask;
+ }
+}
+
+/*******************************************************************
Can this user access with share with the required permissions ?
********************************************************************/
@@ -1200,6 +1230,9 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
r_u->switch_value = 0;
+ if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$"))
+ return NT_STATUS_BAD_NETWORK_NAME;
+
snum = find_service(share_name);
/* Does this share exist ? */
@@ -1220,16 +1253,26 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
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. */
+ psd = NULL;
break;
case 502:
unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
type = q_u->info.share.info502.info_502.type;
psd = q_u->info.share.info502.info_502_str.sd;
+ map_generic_share_sd_bits(psd);
read_only = read_only_share_sd(psd);
break;
case 1005:
return ERROR_ACCESS_DENIED;
+ case 1501:
+ fstrcpy(pathname, lp_pathname(snum));
+ fstrcpy(comment, lp_comment(snum));
+ psd = q_u->info.share.info1501.sdb->sec;
+ map_generic_share_sd_bits(psd);
+ read_only = read_only_share_sd(psd);
+ type = STYPE_DISKTREE;
+ break;
default:
DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
return NT_STATUS_INVALID_INFO_CLASS;
@@ -1267,6 +1310,8 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
/* Send SIGHUP to process group. */
kill(0, SIGHUP);
+ } else {
+ DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
}
/* Replace SD if changed. */
@@ -1335,6 +1380,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
type = q_u->info.share.info502.info_502.type;
psd = q_u->info.share.info502.info_502_str.sd;
+ map_generic_share_sd_bits(psd);
read_only = read_only_share_sd(psd);
break;
case 1005: