Remove strlower_m() and strupper_m() from source4 and common code.
authorAndrew Bartlett <abartlet@samba.org>
Tue, 3 May 2011 02:16:16 +0000 (12:16 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 3 May 2011 05:37:07 +0000 (07:37 +0200)
This function is problematic because a string may expand in size when
changed into upper or lower case.  This will then push characters off
the end of the string in the s3 implementation, or panic in the former
s4 implementation.

Andrew Bartlett

12 files changed:
lib/util/charset/charset.h
lib/util/charset/util_unistr.c
nsswitch/wbinfo.c
source3/lib/util_str.c
source4/auth/ntlmssp/ntlmssp_server.c
source4/client/client.c
source4/dsdb/samdb/ldb_modules/rootdse.c
source4/ntvfs/cifs_posix_cli/svfs_util.c
source4/ntvfs/simple/svfs_util.c
source4/param/loadparm.c
source4/torture/masktest.c
source4/torture/winbind/struct_based.c

index d027daa052c85e6b02f15eb64a25f0c4c73ded53..e5fd596f8f50850585384da4862676b231e6553b 100644 (file)
@@ -105,11 +105,6 @@ typedef struct smb_iconv_s {
 struct loadparm_context;
 struct smb_iconv_handle;
 
-/* replace some string functions with multi-byte
-   versions */
-#define strlower(s) strlower_m(s)
-#define strupper(s) strupper_m(s)
-
 char *strchr_m(const char *s, char c);
 /**
  * Calculate the number of units (8 or 16-bit, depending on the
@@ -137,8 +132,6 @@ int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
                        const char *s1, const char *s2);
 int strcasecmp_m(const char *s1, const char *s2);
 size_t count_chars_m(const char *s, char c);
-void strupper_m(char *s);
-void strlower_m(char *s);
 char *strupper_talloc(TALLOC_CTX *ctx, const char *src);
 char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src);
 char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle,
index a585022e894e9f7ba60c8104ae98ae33172d0ddd..1915c73ad56b9a7c1c08fbf0f675e878d71c0d9c 100644 (file)
@@ -160,85 +160,6 @@ _PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src)
        return strupper_talloc(ctx, src);
 }
 
-/**
- Convert a string to lower case.
-**/
-_PUBLIC_ void strlower_m(char *s)
-{
-       char *d;
-       struct smb_iconv_handle *iconv_handle;
-
-       /* this is quite a common operation, so we want it to be
-          fast. We optimise for the ascii case, knowing that all our
-          supported multi-byte character sets are ascii-compatible
-          (ie. they match for the first 128 chars) */
-       while (*s && !(((uint8_t)*s) & 0x80)) {
-               *s = tolower((uint8_t)*s);
-               s++;
-       }
-
-       if (!*s)
-               return;
-
-       iconv_handle = get_iconv_handle();
-
-       d = s;
-
-       while (*s) {
-               size_t c_size, c_size2;
-               codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
-               c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
-               if (c_size2 > c_size) {
-                       DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
-                                c, tolower_m(c), (int)c_size, (int)c_size2));
-                       smb_panic("codepoint expansion in strlower_m\n");
-               }
-               s += c_size;
-               d += c_size2;
-       }
-       *d = 0;
-}
-
-/**
- Convert a string to UPPER case.
-**/
-_PUBLIC_ void strupper_m(char *s)
-{
-       char *d;
-       struct smb_iconv_handle *iconv_handle;
-
-       /* this is quite a common operation, so we want it to be
-          fast. We optimise for the ascii case, knowing that all our
-          supported multi-byte character sets are ascii-compatible
-          (ie. they match for the first 128 chars) */
-       while (*s && !(((uint8_t)*s) & 0x80)) {
-               *s = toupper((uint8_t)*s);
-               s++;
-       }
-
-       if (!*s)
-               return;
-
-       iconv_handle = get_iconv_handle();
-
-       d = s;
-
-       while (*s) {
-               size_t c_size, c_size2;
-               codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
-               c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
-               if (c_size2 > c_size) {
-                       DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
-                                c, toupper_m(c), (int)c_size, (int)c_size2));
-                       smb_panic("codepoint expansion in strupper_m\n");
-               }
-               s += c_size;
-               d += c_size2;
-       }
-       *d = 0;
-}
-
-
 /**
  Find the number of 'c' chars in a string
 **/
index ac071750228809feda41b40987684235444ec519..30e23b6a8fb5287dc1831a2dbba0a60c5c733052 100644 (file)
@@ -134,7 +134,6 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
        fstrcpy(user, p+1);
        fstrcpy(domain, domuser);
        domain[PTR_DIFF(p, domuser)] = 0;
-       strupper_m(domain);
 
        return true;
 }
index b15dd7907ba38221bb08b97d79362279d43c7bd5..4d76cc0a9f5e1d36426295390c3d9c8ad89fa568 100644 (file)
@@ -796,6 +796,36 @@ static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t des
        return ret;
 }
 
+#if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
+
+/**
+ Convert a string to lower case.
+**/
+_PUBLIC_ void strlower_m(char *s)
+{
+       char *d;
+       struct smb_iconv_handle *iconv_handle;
+
+       iconv_handle = get_iconv_handle();
+
+       d = s;
+
+       while (*s) {
+               size_t c_size, c_size2;
+               codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
+               c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
+               if (c_size2 > c_size) {
+                       DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
+                                c, tolower_m(c), (int)c_size, (int)c_size2));
+                       smb_panic("codepoint expansion in strlower_m\n");
+               }
+               s += c_size;
+               d += c_size2;
+       }
+       *d = 0;
+}
+
+#endif
 
 /**
  Convert a string to lower case.
@@ -851,6 +881,37 @@ static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t des
        return ret;
 }
 
+#if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
+
+/**
+ Convert a string to UPPER case.
+**/
+_PUBLIC_ void strupper_m(char *s)
+{
+       char *d;
+       struct smb_iconv_handle *iconv_handle;
+
+       iconv_handle = get_iconv_handle();
+
+       d = s;
+
+       while (*s) {
+               size_t c_size, c_size2;
+               codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
+               c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
+               if (c_size2 > c_size) {
+                       DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
+                                c, toupper_m(c), (int)c_size, (int)c_size2));
+                       smb_panic("codepoint expansion in strupper_m\n");
+               }
+               s += c_size;
+               d += c_size2;
+       }
+       *d = 0;
+}
+
+#endif
+
 /**
  Convert a string to upper case.
 **/
index 9db3b560c1067162e78035cf796be86a137bc1f6..cdae37262e54741e86c30cf9c8e197c03e37d3f9 100644 (file)
@@ -308,26 +308,26 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
        ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
 
        {
-               char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN];
-
-               /* Find out the DNS domain name */
-               dnsdomname[0] = '\0';
-               safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
+               char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
+               char *dnsname, *lower_netbiosname;
+               lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name);
 
                /* Find out the DNS host name */
-               safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1);
-               if (dnsdomname[0] != '\0') {
-                       safe_strcat(dnsname, ".", sizeof(dnsname) - 1);
-                       safe_strcat(dnsname, dnsdomname, sizeof(dnsname) - 1);
+               if (dnsdomain && dnsdomain[0] != '\0') {
+                       dnsname = talloc_asprintf(ntlmssp_state, "%s.%s",
+                                                 lower_netbiosname,
+                                                 dnsdomain);
+                       talloc_free(lower_netbiosname);
+                       ntlmssp_state->server.dns_name = dnsname;
+               } else {
+                       ntlmssp_state->server.dns_name = lower_netbiosname;
                }
-               strlower_m(dnsname);
 
-               ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state,
-                                                                     dnsname);
                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);
 
-               ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state,
-                                                                       dnsdomname);
+               ntlmssp_state->server.dns_domain
+                       = talloc_strdup(ntlmssp_state,
+                                       lpcfg_dnsdomain(gensec_security->settings->lp_ctx));
                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
        }
 
index c6c0088b3c32f6c161bcd623433471df7ed786fe..923a6f3a2381afe27b28ba100e783cefd2d8abc0 100644 (file)
@@ -696,11 +696,12 @@ static int do_get(struct smbclient_context *ctx, char *rname, const char *p_lnam
        char *lname;
 
 
-       lname = talloc_strdup(ctx, p_lname);
        GetTimeOfDay(&tp_start);
 
        if (ctx->lowercase) {
-               strlower(lname);
+               lname = strlower_talloc(ctx, p_lname);
+       } else {
+               lname = talloc_strdup(ctx, p_lname);
        }
 
        fnum = smbcli_open(ctx->cli->tree, rname, O_RDONLY, DENY_NONE);
@@ -884,13 +885,14 @@ static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *fin
 
        ctx->remote_cur_dir = talloc_asprintf_append_buffer(NULL, "%s\\", finfo->name);
 
-       l_fname = talloc_strdup(ctx, finfo->name);
-
-       string_replace(l_fname, '\\', '/');
        if (ctx->lowercase) {
-               strlower(l_fname);
+               l_fname = strlower_talloc(ctx, finfo->name);
+       } else {
+               l_fname = talloc_strdup(ctx, finfo->name);
        }
        
+       string_replace(l_fname, '\\', '/');
+
        if (!directory_exist(l_fname) &&
            mkdir(l_fname, 0777) != 0) {
                d_printf("failed to create directory %s\n", l_fname);
index b7189003455d96236895e2a909128570492e3c3b..7bc27b46b46a98f16ca98cbcdbbc12474bb822c6 100644 (file)
@@ -222,11 +222,10 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
                                          struct loadparm_context);
                char *ldap_service_name, *hostname;
 
-               hostname = talloc_strdup(msg, lpcfg_netbios_name(lp_ctx));
+               hostname = strlower_talloc(msg, lpcfg_netbios_name(lp_ctx));
                if (hostname == NULL) {
                        goto failed;
                }
-               strlower_m(hostname);
 
                ldap_service_name = talloc_asprintf(msg, "%s:%s$@%s",
                                                    samdb_forest_name(ldb, msg),
index d8a7909390c71142cb4a0c5c7581adfec6b0ce36..128440c1ea8c7b04f697f135cfc1a6afe1e14490 100644 (file)
@@ -41,16 +41,15 @@ char *cifspsx_unix_path(struct ntvfs_module_context *ntvfs,
 {
        struct cifspsx_private *p = ntvfs->private_data;
        char *ret;
+       char *name_lower = strlower_talloc(p, name);
 
        if (*name != '\\') {
-               ret = talloc_asprintf(req, "%s/%s", p->connectpath, name);
+               ret = talloc_asprintf(req, "%s/%s", p->connectpath, name_lower);
        } else {
-               ret = talloc_asprintf(req, "%s%s", p->connectpath, name);
+               ret = talloc_asprintf(req, "%s%s", p->connectpath, name_lower);
        }
        all_string_sub(ret, "\\", "/", 0);
-
-       strlower(ret + strlen(p->connectpath));
-
+       talloc_free(name_lower);
        return ret;
 }
 
@@ -85,9 +84,8 @@ struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request
        /* the wildcard pattern is the last part */
        mask = p+1;
 
-       low_mask = talloc_strdup(mem_ctx, mask);
+       low_mask = strlower_talloc(mem_ctx, mask);
        if (!low_mask) { return NULL; }
-       strlower(low_mask);
 
        odir = opendir(dir->unix_dir);
        if (!odir) { return NULL; }
@@ -102,9 +100,8 @@ struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request
                        continue;
                }
 
-               low_name = talloc_strdup(mem_ctx, dent->d_name);
+               low_name = strlower_talloc(mem_ctx, dent->d_name);
                if (!low_name) { continue; }
-               strlower(low_name);
 
                /* check it matches the wildcard pattern */
                if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) {
index 2a01c2d5deccb2bf677699516e40d597b063410c..75261f727707e2219a68f02b4f770d3398bfceb2 100644 (file)
@@ -38,16 +38,15 @@ char *svfs_unix_path(struct ntvfs_module_context *ntvfs,
 {
        struct svfs_private *p = ntvfs->private_data;
        char *ret;
+       char *name_lower = strlower_talloc(p, name);
 
        if (*name != '\\') {
-               ret = talloc_asprintf(req, "%s/%s", p->connectpath, name);
+               ret = talloc_asprintf(req, "%s/%s", p->connectpath, name_lower);
        } else {
-               ret = talloc_asprintf(req, "%s%s", p->connectpath, name);
+               ret = talloc_asprintf(req, "%s%s", p->connectpath, name_lower);
        }
        all_string_sub(ret, "\\", "/", 0);
-
-       strlower(ret + strlen(p->connectpath));
-
+       talloc_free(name_lower);
        return ret;
 }
 
@@ -82,9 +81,8 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req,
        /* the wildcard pattern is the last part */
        mask = p+1;
 
-       low_mask = talloc_strdup(mem_ctx, mask);
+       low_mask = strlower_talloc(mem_ctx, mask);
        if (!low_mask) { return NULL; }
-       strlower(low_mask);
 
        odir = opendir(dir->unix_dir);
        if (!odir) { return NULL; }
@@ -99,9 +97,8 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req,
                        continue;
                }
 
-               low_name = talloc_strdup(mem_ctx, dent->d_name);
+               low_name = strlower_talloc(mem_ctx, dent->d_name);
                if (!low_name) { continue; }
-               strlower(low_name);
 
                /* check it matches the wildcard pattern */
                if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) {
index 0f60e4364b0bade35993e99f8a6be17c5f75d3db..fa00beee967fbc5ad22dde4bcad713ca5582cece 100644 (file)
@@ -779,6 +779,7 @@ const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
                              struct loadparm_service *service,
                              const char *type, const char *option)
 {
+       char *vfskey_tmp = NULL;
        char *vfskey = NULL;
        struct parmlist_entry *data;
 
@@ -787,13 +788,14 @@ const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
 
        data = (service == NULL ? lp_ctx->globals->param_opt : service->param_opt);
 
-       asprintf(&vfskey, "%s:%s", type, option);
-       if (vfskey == NULL) return NULL;
-       strlower(vfskey);
+       vfskey_tmp = talloc_asprintf(NULL, "%s:%s", type, option);
+       if (vfskey_tmp == NULL) return NULL;
+       vfskey = strlower_talloc(NULL, vfskey_tmp);
+       talloc_free(vfskey_tmp);
 
        while (data) {
                if (strcmp(data->key, vfskey) == 0) {
-                       free(vfskey);
+                       talloc_free(vfskey);
                        return data->value;
                }
                data = data->next;
@@ -805,13 +807,13 @@ const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
                for (data = lp_ctx->globals->param_opt; data;
                     data = data->next) {
                        if (strcmp(data->key, vfskey) == 0) {
-                               free(vfskey);
+                               talloc_free(vfskey);
                                return data->value;
                        }
                }
        }
 
-       free(vfskey);
+       talloc_free(vfskey);
 
        return NULL;
 }
@@ -1031,7 +1033,27 @@ static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
 
        *dest = talloc_strdup(mem_ctx, src);
        if ((*dest) == NULL) {
-               DEBUG(0,("Out of memory in string_init\n"));
+               DEBUG(0,("Out of memory in string_set\n"));
+               return false;
+       }
+
+       return true;
+}
+
+/**
+ * Set a string value, deallocating any existing space, and allocing the space
+ * for the string
+ */
+static bool string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
+{
+       talloc_free(*dest);
+
+       if (src == NULL)
+               src = "";
+
+       *dest = strupper_talloc(mem_ctx, src);
+       if ((*dest) == NULL) {
+               DEBUG(0,("Out of memory in string_set_upper\n"));
                return false;
        }
 
@@ -1292,10 +1314,9 @@ static void copy_service(struct loadparm_service *pserviceDest,
                                        break;
 
                                case P_USTRING:
-                                       string_set(pserviceDest,
-                                                  (char **)dest_ptr,
-                                                  *(char **)src_ptr);
-                                       strupper(*(char **)dest_ptr);
+                                       string_set_upper(pserviceDest,
+                                                        (char **)dest_ptr,
+                                                        *(char **)src_ptr);
                                        break;
                                case P_LIST:
                                        *(const char ***)dest_ptr = (const char **)str_list_copy(pserviceDest, 
@@ -1574,11 +1595,9 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
                pszParmName++;
        }
 
-       name = strdup(pszParmName);
+       name = strlower_talloc(lp_ctx, pszParmName);
        if (!name) return false;
 
-       strlower(name);
-
        if (service == NULL) {
                data = lp_ctx->globals->param_opt;
                mem_ctx = lp_ctx->globals;
@@ -1594,13 +1613,14 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
                if (strcmp(paramo->key, name) == 0) {
                        if ((paramo->priority & FLAG_CMDLINE) &&
                            !(flags & FLAG_CMDLINE)) {
+                               talloc_free(name);
                                return true;
                        }
 
                        talloc_free(paramo->value);
                        paramo->value = talloc_strdup(paramo, pszParmValue);
                        paramo->priority = flags;
-                       free(name);
+                       talloc_free(name);
                        return true;
                }
        }
@@ -1617,7 +1637,7 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
                DLIST_ADD(service->param_opt, paramo);
        }
 
-       free(name);
+       talloc_free(name);
 
        return true;
 }
@@ -1713,8 +1733,7 @@ static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
                        break;
 
                case P_USTRING:
-                       string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
-                       strupper(*(char **)parm_ptr);
+                       string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue);
                        break;
 
                case P_ENUM:
index 9c66291087fb6d3f1f7e7366eb5bdcb6a719c4dc..42665ab897aac180be246cccbb57afe2fa3074d5 100644 (file)
@@ -153,10 +153,8 @@ static void get_real_name(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
                        listfn, &state);
 
        if (f_info_hit) {
-               *short_name = talloc_strdup(mem_ctx, last_hit.short_name);
-               strlower(*short_name);
-               *long_name = talloc_strdup(mem_ctx, last_hit.long_name);
-               strlower(*long_name);
+               *short_name = strlower_talloc(mem_ctx, last_hit.short_name);
+               *long_name = strlower_talloc(mem_ctx, last_hit.long_name);
        }
 
        if (*short_name == '\0') {
index aeb81c972ced932e05fa24d0a91801f4f21c1d88..2bab94088a3ed4135c44d099dbc3c6acd33745a5 100644 (file)
@@ -914,7 +914,6 @@ static bool parse_domain_user(struct torture_context *torture,
        fstrcpy(user, p+1);
        fstrcpy(domain, domuser);
        domain[PTR_DIFF(p, domuser)] = 0;
-       strupper_m(domain);
 
        return true;
 }