From f0dcc90f726e1232a4e0b74a03784281ea9a7cdc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Nov 2010 15:07:49 -0800 Subject: Fix bug 7781 - Samba transforms ShareName to lowercase (sharename) when adding new share via MMC Change the find_service() interface to not depend on fstring, and create a useable talloc-based interface. Jeremy. --- source3/rpc_server/srv_srvsvc_nt.c | 103 +++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 34 deletions(-) (limited to 'source3/rpc_server/srv_srvsvc_nt.c') diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index f59b972861..82b89390db 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -1412,15 +1412,20 @@ WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p, struct srvsvc_NetShareGetInfo *r) { WERROR status = WERR_OK; - fstring share_name; + char *share_name = NULL; int snum; union srvsvc_NetShareInfo *info = r->out.info; DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__)); - fstrcpy(share_name, r->in.share_name); + if (!r->in.share_name) { + return WERR_INVALID_NAME; + } - snum = find_service(share_name); + snum = find_service(talloc_tos(), r->in.share_name, &share_name); + if (!share_name) { + return WERR_NOMEM; + } if (snum < 0) { return WERR_INVALID_NAME; } @@ -1543,26 +1548,28 @@ WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p, DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__)); - share_name = talloc_strdup(p->mem_ctx, r->in.share_name); - if (!share_name) { - return WERR_NOMEM; + if (!r->in.share_name) { + return WERR_INVALID_NAME; } if (r->out.parm_error) { *r->out.parm_error = 0; } - if ( strequal(share_name,"IPC$") - || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) - || strequal(share_name,"global") ) + if ( strequal(r->in.share_name,"IPC$") + || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") ) + || strequal(r->in.share_name,"global") ) { DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be " "modified by a remote user.\n", - share_name )); + r->in.share_name )); return WERR_ACCESS_DENIED; } - snum = find_service(share_name); + snum = find_service(talloc_tos(), r->in.share_name, &share_name); + if (!share_name) { + return WERR_NOMEM; + } /* Does this share exist ? */ if (snum < 0) @@ -1756,6 +1763,7 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, struct srvsvc_NetShareAdd *r) { char *command = NULL; + char *share_name_in = NULL; char *share_name = NULL; char *comment = NULL; char *pathname = NULL; @@ -1792,7 +1800,7 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, /* Not enough info in a level 1 to do anything. */ return WERR_ACCESS_DENIED; case 2: - share_name = talloc_strdup(ctx, r->in.info->info2->name); + share_name_in = talloc_strdup(ctx, r->in.info->info2->name); comment = talloc_strdup(ctx, r->in.info->info2->comment); pathname = talloc_strdup(ctx, r->in.info->info2->path); max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ? @@ -1803,7 +1811,7 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, /* No path. Not enough info in a level 501 to do anything. */ return WERR_ACCESS_DENIED; case 502: - share_name = talloc_strdup(ctx, r->in.info->info502->name); + share_name_in = talloc_strdup(ctx, r->in.info->info502->name); comment = talloc_strdup(ctx, r->in.info->info502->comment); pathname = talloc_strdup(ctx, r->in.info->info502->path); max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ? @@ -1831,21 +1839,24 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, /* check for invalid share names */ - if (!share_name || !validate_net_name(share_name, + if (!share_name_in || !validate_net_name(share_name_in, INVALID_SHARENAME_CHARS, - strlen(share_name))) { + strlen(share_name_in))) { DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n", - share_name ? share_name : "")); + share_name_in ? share_name_in : "")); return WERR_INVALID_NAME; } - if (strequal(share_name,"IPC$") || strequal(share_name,"global") + if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global") || (lp_enable_asu_support() && - strequal(share_name,"ADMIN$"))) { + strequal(share_name_in,"ADMIN$"))) { return WERR_ACCESS_DENIED; } - snum = find_service(share_name); + snum = find_service(ctx, share_name_in, &share_name); + if (!share_name) { + return WERR_NOMEM; + } /* Share already exists. */ if (snum >= 0) { @@ -1863,6 +1874,7 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, } /* Ensure share name, pathname and comment don't contain '"' characters. */ + string_replace(share_name_in, '"', ' '); string_replace(share_name, '"', ' '); string_replace(path, '"', ' '); if (comment) { @@ -1873,7 +1885,7 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", lp_add_share_cmd(), get_dyn_CONFIGFILE(), - share_name, + share_name_in, path, comment ? comment : "", max_connections); @@ -1910,6 +1922,8 @@ WERROR _srvsvc_NetShareAdd(struct pipes_struct *p, return WERR_ACCESS_DENIED; if (psd) { + /* Note we use share_name here, not share_name_in as + we need a canonicalized name for setting security. */ if (!set_share_security(share_name, psd)) { DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n", share_name )); @@ -1946,22 +1960,29 @@ WERROR _srvsvc_NetShareDel(struct pipes_struct *p, DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__)); - share_name = talloc_strdup(p->mem_ctx, r->in.share_name); - if (!share_name) { + if (!r->in.share_name) { return WERR_NET_NAME_NOT_FOUND; } - if ( strequal(share_name,"IPC$") - || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) - || strequal(share_name,"global") ) + + if ( strequal(r->in.share_name,"IPC$") + || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") ) + || strequal(r->in.share_name,"global") ) { return WERR_ACCESS_DENIED; } - if (!(params = get_share_params(p->mem_ctx, share_name))) { + snum = find_service(talloc_tos(), r->in.share_name, &share_name); + if (!share_name) { + return WERR_NOMEM; + } + + if (snum < 0) { return WERR_NO_SUCH_SHARE; } - snum = find_service(share_name); + 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)) @@ -2092,7 +2113,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, struct smb_filename *smb_fname = NULL; struct security_descriptor *psd = NULL; size_t sd_size; - fstring servicename; + char *servicename = NULL; SMB_STRUCT_STAT st; NTSTATUS nt_status; WERROR werr; @@ -2104,9 +2125,15 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, ZERO_STRUCT(st); - fstrcpy(servicename, r->in.share); - - snum = find_service(servicename); + if (!r->in.share) { + werr = WERR_NET_NAME_NOT_FOUND; + goto error_exit; + } + snum = find_service(talloc_tos(), r->in.share, &servicename); + if (!servicename) { + werr = WERR_NOMEM; + goto error_exit; + } if (snum == -1) { DEBUG(10, ("Could not find service %s\n", servicename)); werr = WERR_NET_NAME_NOT_FOUND; @@ -2222,7 +2249,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) { struct smb_filename *smb_fname = NULL; - fstring servicename; + char *servicename = NULL; files_struct *fsp = NULL; SMB_STRUCT_STAT st; NTSTATUS nt_status; @@ -2235,9 +2262,17 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, ZERO_STRUCT(st); - fstrcpy(servicename, r->in.share); + if (!r->in.share) { + werr = WERR_NET_NAME_NOT_FOUND; + goto error_exit; + } + + snum = find_service(talloc_tos(), r->in.share, &servicename); + if (!servicename) { + werr = WERR_NOMEM; + goto error_exit; + } - snum = find_service(servicename); if (snum == -1) { DEBUG(10, ("Could not find service %s\n", servicename)); werr = WERR_NET_NAME_NOT_FOUND; -- cgit