Fix bug #7781 (Samba transforms "ShareName" to lowercase when adding new share via...
authorJeremy Allison <jra@samba.org>
Wed, 23 May 2012 20:22:17 +0000 (22:22 +0200)
committerKarolin Seeger <kseeger@samba.org>
Fri, 14 Dec 2012 09:01:35 +0000 (10:01 +0100)
Signed-off-by: Michael Adam <obnox@samba.org>
(cherry picked from commit 3b1528dcd67d62f20313094be9b5d609a1ca4f25)

12 files changed:
source3/include/proto.h
source3/lib/dummysmbd.c
source3/lib/util_str.c
source3/modules/vfs_xattr_tdb.c
source3/param/loadparm.c
source3/printing/nt_printing.c
source3/registry/reg_backend_printing.c
source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/lanman.c
source3/smbd/msdfs.c
source3/smbd/service.c
source3/smbd/smb2_tcon.c

index 785cc30387729dd88c30d55a8abda16a3e6b6284..cee5d6af7f379d89acc4de4f3e4a3fa40b8e8350 100644 (file)
@@ -7002,7 +7002,7 @@ bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
-int find_service(fstring service);
+int find_service(const char *service_in, fstring service);
 connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
                                        int snum, user_struct *vuser,
                                        DATA_BLOB password,
index a41e6dc033a75aed60869e4f28ab77ab887c5dad..28c6f0effe4c9ecd0b7d336a2e4c085cbb11ba40 100644 (file)
@@ -28,7 +28,7 @@ int get_client_fd(void)
        return -1;
 }
 
-int find_service(fstring service)
+int find_service(const char *service_in, fstring service)
 {
        return -1;
 }
index d86963702e03ebc73365d327f08f5f090e098e16..17a4a8f2c4e9727f56a0c559d70de14ac4c14c57 100644 (file)
@@ -2301,6 +2301,10 @@ bool validate_net_name( const char *name,
 {
        int i;
 
+       if (!name) {
+               return false;
+       }
+
        for ( i=0; i<max_len && name[i]; i++ ) {
                /* fail if strchr_m() finds one of the invalid characters */
                if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
index f7fbfce4cb979f2232d9c301a78faab41996e5b1..fa8db047f8cf6b03f7fd6e98384519f9c2612185 100644 (file)
@@ -733,8 +733,7 @@ static int xattr_tdb_connect(vfs_handle_struct *handle, const char *service,
                return res;
        }
 
-       fstrcpy(sname, service);
-       snum = find_service(sname);
+       snum = find_service(service, sname);
        if (snum == -1) {
                /*
                 * Should not happen, but we should not fail just *here*.
index 8c1cf0973b0729ac54c6d14aa1f2e8a0c96b1b85..eaff9e6ec4c51b1429fbf4f12e8b82f117fe319f 100644 (file)
@@ -9471,15 +9471,10 @@ struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
                                      const char *sharename)
 {
        struct share_params *result;
-       char *sname;
+       fstring sname;
        int snum;
 
-       if (!(sname = SMB_STRDUP(sharename))) {
-               return NULL;
-       }
-
-       snum = find_service(sname);
-       SAFE_FREE(sname);
+       snum = find_service(sharename, sname);
 
        if (snum < 0) {
                return NULL;
index beaa9e5790a3c053e0dffd43c04c96f5dcdf7cd3..85ce703bd80e198dac4fea167721877943389f77 100644 (file)
@@ -1472,9 +1472,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
                return 3;
        }
 
-       fstrcpy(printdollar, "print$");
-
-       printdollar_snum = find_service(printdollar);
+       printdollar_snum = find_service("print$", printdollar);
        if (printdollar_snum == -1) {
                *perr = WERR_NO_SUCH_SHARE;
                return -1;
@@ -1864,9 +1862,7 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
 
-       fstrcpy(printdollar, "print$");
-
-       printdollar_snum = find_service(printdollar);
+       printdollar_snum = find_service("print$", printdollar);
        if (printdollar_snum == -1) {
                *perr = WERR_NO_SUCH_SHARE;
                return WERR_NO_SUCH_SHARE;
@@ -5134,9 +5130,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
        DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
                r->driver_name, r->version));
 
-       fstrcpy(printdollar, "print$");
-
-       printdollar_snum = find_service(printdollar);
+       printdollar_snum = find_service("print$", printdollar);
        if (printdollar_snum == -1) {
                return false;
        }
index 90ccc33c4c9b54f735114f650941db3bfe1cfcbc..cba4f798d3802fb12dec10b0178cf512ab13296d 100644 (file)
@@ -278,7 +278,7 @@ done:
 static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
 {
        int i, num_keys, snum;
-       char *printername;
+       char *printername_in;
        NT_PRINTER_INFO_LEVEL_2 info2;
        NT_PRINTER_INFO_LEVEL printer;
        
@@ -289,8 +289,9 @@ static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
        
        become_root();
        for ( i=0; i<num_keys; i++ ) {
-               printername = regsubkey_ctr_specific_key( subkeys, i );
-               snum = find_service( printername );
+               fstring printername;
+               printername_in = regsubkey_ctr_specific_key( subkeys, i );
+               snum = find_service(printername_in, printername);
                
                /* just verify a valied snum for now */
                if ( snum == -1 ) {
index a2d1d0716d2fc6804ec7743dcb193381b1eb9eb3..b51c7e2f2f9be771ba11448195c21760f065213e 100644 (file)
@@ -1397,9 +1397,11 @@ WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
 
        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(r->in.share_name, share_name);
        if (snum < 0) {
                return WERR_INVALID_NAME;
        }
@@ -1507,7 +1509,7 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
                               struct srvsvc_NetShareSetInfo *r)
 {
        char *command = NULL;
-       char *share_name = NULL;
+       fstring share_name;
        char *comment = NULL;
        const char *pathname = NULL;
        int type;
@@ -1523,26 +1525,25 @@ WERROR _srvsvc_NetShareSetInfo(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(r->in.share_name, share_name);
 
        /* Does this share exist ? */
        if (snum < 0)
@@ -1737,7 +1738,8 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p,
                           struct srvsvc_NetShareAdd *r)
 {
        char *command = NULL;
-       char *share_name = NULL;
+       char *share_name_in = NULL;
+       fstring share_name;
        char *comment = NULL;
        char *pathname = NULL;
        int type;
@@ -1774,7 +1776,7 @@ WERROR _srvsvc_NetShareAdd(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) ?
@@ -1785,7 +1787,7 @@ WERROR _srvsvc_NetShareAdd(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) ?
@@ -1813,21 +1815,21 @@ WERROR _srvsvc_NetShareAdd(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(share_name_in, share_name);
 
        /* Share already exists. */
        if (snum >= 0) {
@@ -1845,7 +1847,7 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p,
        }
 
        /* Ensure share name, pathname and comment don't contain '"' characters. */
-       string_replace(share_name, '"', ' ');
+       string_replace(share_name_in, '"', ' ');
        string_replace(path, '"', ' ');
        if (comment) {
                string_replace(comment, '"', ' ');
@@ -1855,7 +1857,7 @@ WERROR _srvsvc_NetShareAdd(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);
@@ -1892,6 +1894,8 @@ WERROR _srvsvc_NetShareAdd(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 ));
@@ -1919,7 +1923,7 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p,
                           struct srvsvc_NetShareDel *r)
 {
        char *command = NULL;
-       char *share_name = NULL;
+       fstring share_name;
        int ret;
        int snum;
        SE_PRIV se_diskop = SE_DISK_OPERATOR;
@@ -1929,22 +1933,21 @@ WERROR _srvsvc_NetShareDel(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))) {
+       if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
                return WERR_NO_SUCH_SHARE;
        }
 
-       snum = find_service(share_name);
+       snum = find_service(r->in.share_name, share_name);
 
        /* No change to printer shares. */
        if (lp_print_ok(snum))
@@ -2087,9 +2090,11 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
 
        ZERO_STRUCT(st);
 
-       fstrcpy(servicename, r->in.share);
+       if (!r->in.share) {
+               return WERR_INVALID_NAME;
+       }
 
-       snum = find_service(servicename);
+       snum = find_service(r->in.share, servicename);
        if (snum == -1) {
                DEBUG(10, ("Could not find service %s\n", servicename));
                werr = WERR_NET_NAME_NOT_FOUND;
@@ -2217,9 +2222,11 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
 
        ZERO_STRUCT(st);
 
-       fstrcpy(servicename, r->in.share);
+       if (!r->in.share) {
+               return WERR_INVALID_NAME;
+       }
 
-       snum = find_service(servicename);
+       snum = find_service(r->in.share, servicename);
        if (snum == -1) {
                DEBUG(10, ("Could not find service %s\n", servicename));
                werr = WERR_NET_NAME_NOT_FOUND;
index 7b01968a1f04146b874af76e4b06cfc54611f300..9b173d4d7f4fce825e62c02e9362a4663c44a99e 100644 (file)
@@ -849,6 +849,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
        char *str2 = skip_string(param,tpscnt,str1);
        char *p = skip_string(param,tpscnt,str2);
        char *QueueName = p;
+       fstring share_name;
        unsigned int uLevel;
        int count=0;
        int snum;
@@ -899,7 +900,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
                return(True);
        }
 
-       snum = find_service(QueueName);
+       snum = find_service(QueueName, share_name);
        if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
                return False;
 
@@ -1929,12 +1930,13 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
        char *p = skip_string(param,tpscnt,netname);
        int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
        int snum;
+       fstring share_name;
 
        if (!str1 || !str2 || !netname || !p) {
                return False;
        }
 
-       snum = find_service(netname);
+       snum = find_service(netname, share_name);
        if (snum < 0) {
                return False;
        }
@@ -2126,7 +2128,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
                return False;
        }
        pull_ascii_fstring(sharename,data);
-       snum = find_service(sharename);
+       snum = find_service(sharename, sharename);
        if (snum >= 0) { /* already exists */
                res = ERRfilexists;
                goto error_exit;
@@ -4182,6 +4184,7 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
        struct pack_desc desc;
        print_queue_struct *queue=NULL;
        print_status_struct status;
+       fstring share_name;
 
        if (!str1 || !str2 || !p) {
                return False;
@@ -4211,7 +4214,7 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
                return False;
        }
 
-       snum = find_service(name);
+       snum = find_service(name, share_name);
        if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
                return False;
        }
@@ -4332,6 +4335,7 @@ static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
        char *str2 = skip_string(param,tpscnt,str1);
        char *p = skip_string(param,tpscnt,str2);
        char* PrinterName = p;
+       fstring share_name;
        int uLevel;
        struct pack_desc desc;
        int snum;
@@ -4359,7 +4363,7 @@ static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
                return False;
        }
 
-       snum = find_service(PrinterName);
+       snum = find_service(PrinterName, share_name);
        if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
                *rdata_len = 0;
                desc.errcode = NERR_DestNotFound;
index 0480b585503a5458b2f8a9bb54af5d737bc29b7b..718d0def7214514c4660ef825f409745deb9bb0f 100644 (file)
@@ -822,8 +822,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
        snum = lp_servicenumber(jucn->service_name);
        if(snum < 0) {
                fstring service_name;
-               fstrcpy(service_name, jucn->service_name);
-               if ((snum = find_service(service_name)) < 0) {
+               if ((snum = find_service(jucn->service_name, service_name)) < 0) {
                        return NT_STATUS_NOT_FOUND;
                }
                TALLOC_FREE(jucn->service_name);
index 2de9384893568d8cec52c5fcf3da8d82c062debe..5281ef32c93d80f6b4ebdf38ced5fc02cf837799 100644 (file)
@@ -300,14 +300,20 @@ int add_home_service(const char *service, const char *username, const char *home
 /**
  * Find a service entry.
  *
- * @param service is modified (to canonical form??)
+ * @param service_in is modified (to canonical form??)
+ * and returned in return parameter service.
  **/
 
-int find_service(fstring service)
+int find_service(const char *service_in, fstring service)
 {
        int iService;
        struct smbd_server_connection *sconn = smbd_server_conn;
 
+       if (!service_in) {
+               return -1;
+       }
+
+       fstrcpy(service, service_in);
        all_string_sub(service,"\\","/",0);
 
        iService = lp_servicenumber(service);
@@ -394,7 +400,7 @@ int find_service(fstring service)
                                goto fail;
                        }
 
-                       iService = find_service(defservice);
+                       iService = find_service(defservice, service);
                        if (iService >= 0) {
                                all_string_sub(service, "_","/",0);
                                iService = lp_add_service(service, iService);
@@ -1177,7 +1183,7 @@ connection_struct *make_connection(struct smbd_server_connection *sconn,
                                fstrcpy(unix_username,
                                        current_user_info.smb_name);
                                map_username(sconn, unix_username);
-                               snum = find_service(unix_username);
+                               snum = find_service(unix_username, unix_username);
                        } 
                        if (snum != -1) {
                                DEBUG(5, ("making a connection to 'homes' "
@@ -1205,7 +1211,7 @@ connection_struct *make_connection(struct smbd_server_connection *sconn,
 
        strlower_m(service);
 
-       snum = find_service(service);
+       snum = find_service(service, service);
 
        if (snum < 0) {
                if (strequal(service,"IPC$") ||
index 70c5e8845e5d6c4e9710991b23f095b1c8baa1bb..f7b9bdb5929df3c36b9903ce41ae7dd9fe23654a 100644 (file)
@@ -167,7 +167,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 
        strlower_m(service);
 
-       snum = find_service(service);
+       snum = find_service(service, service);
        if (snum < 0) {
                DEBUG(3,("smbd_smb2_tree_connect: couldn't find service %s\n",
                         service));