mirror of
https://github.com/samba-team/samba.git
synced 2025-08-03 04:22:09 +03:00
Remove strlower_m() and strupper_m() from source4 and common code.
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
This commit is contained in:
@ -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,
|
||||
|
@ -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
|
||||
**/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
**/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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') {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user