diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/include/rpc_srvsvc.h | 12 | ||||
-rw-r--r-- | source3/rpc_parse/parse_srv.c | 49 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 48 |
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: |