mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
Always escape ldap filter strings. Escaping code was from pam_ldap, but I'm to
blame for the realloc() stuff. Plus a couple of minor updates to libads. Andrew Bartlett
This commit is contained in:
parent
9494c1e153
commit
34b2e558a4
90
source/lib/ldap_escape.c
Normal file
90
source/lib/ldap_escape.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
ldap filter argument escaping
|
||||
|
||||
Copyright (C) 1998, 1999, 2000 Luke Howard <lukeh@padl.com>,
|
||||
Copyright (C) 2003 Andrew Bartlett <abartlet@samba.org>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
/**
|
||||
* Escape a parameter to an LDAP filter string, so they cannot contain
|
||||
* embeded ( ) * or \ chars which may cause it not to parse correctly.
|
||||
*
|
||||
* @param s The input string
|
||||
*
|
||||
* @return A string allocated with malloc(), containing the escaped string,
|
||||
* and to be free()ed by the caller.
|
||||
**/
|
||||
|
||||
char *escape_ldap_string_alloc(const char *s)
|
||||
{
|
||||
size_t len = strlen(s)+1;
|
||||
char *output = malloc(len);
|
||||
char *output_tmp;
|
||||
const char *sub;
|
||||
int i = 0;
|
||||
char *p = output;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
switch (*s)
|
||||
{
|
||||
case '*':
|
||||
sub = "\\2a";
|
||||
break;
|
||||
case '(':
|
||||
sub = "\\28";
|
||||
break;
|
||||
case ')':
|
||||
sub = "\\29";
|
||||
break;
|
||||
case '\\':
|
||||
sub = "\\5c";
|
||||
break;
|
||||
default:
|
||||
sub = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sub) {
|
||||
len = len + 3;
|
||||
output_tmp = realloc(output, len);
|
||||
if (!output_tmp) {
|
||||
SAFE_FREE(output);
|
||||
return NULL;
|
||||
}
|
||||
output = output_tmp;
|
||||
|
||||
p = &output[i];
|
||||
strncpy (p, sub, 3);
|
||||
p += 3;
|
||||
i += 3;
|
||||
|
||||
} else {
|
||||
*p = *s;
|
||||
p++;
|
||||
i++;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
return output;
|
||||
}
|
@ -37,9 +37,16 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
|
||||
char *exp;
|
||||
uint32 t;
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
char *escaped_name = escape_ldap_string_alloc(name);
|
||||
char *escaped_realm = escape_ldap_string_alloc(ads->config.realm);
|
||||
|
||||
if (!escaped_name || !escaped_realm) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
|
||||
name, name, ads->config.realm) == -1) {
|
||||
escaped_name, escaped_name, escaped_realm) == -1) {
|
||||
DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
@ -77,6 +84,9 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
|
||||
done:
|
||||
if (res) ads_msgfree(ads, res);
|
||||
|
||||
SAFE_FREE(escaped_name);
|
||||
SAFE_FREE(escaped_realm);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -974,7 +974,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
|
||||
/* make sure the end of the list is NULL */
|
||||
mods[i] = NULL;
|
||||
|
||||
ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods);
|
||||
ret = ldap_add_s(ads->ld, utf8_dn, mods);
|
||||
SAFE_FREE(utf8_dn);
|
||||
return ADS_ERROR(ret);
|
||||
}
|
||||
@ -994,7 +994,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn)
|
||||
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn);
|
||||
ret = ldap_delete(ads->ld, utf8_dn);
|
||||
return ADS_ERROR(ret);
|
||||
}
|
||||
|
||||
@ -1029,8 +1029,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
|
||||
ADS_MODLIST mods;
|
||||
const char *objectClass[] = {"top", "person", "organizationalPerson",
|
||||
"user", "computer", NULL};
|
||||
const char *servicePrincipalName[3] = {NULL, NULL, NULL};
|
||||
char *psp;
|
||||
const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL};
|
||||
char *psp, *psp2;
|
||||
unsigned acct_control;
|
||||
|
||||
if (!(ctx = talloc_init("machine_account")))
|
||||
@ -1051,10 +1051,16 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
|
||||
ads->config.bind_path);
|
||||
servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname);
|
||||
psp = talloc_asprintf(ctx, "HOST/%s.%s",
|
||||
hostname,
|
||||
ads->config.realm);
|
||||
hostname,
|
||||
ads->config.realm);
|
||||
strlower(&psp[5]);
|
||||
servicePrincipalName[1] = psp;
|
||||
servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname);
|
||||
psp2 = talloc_asprintf(ctx, "CIFS/%s.%s",
|
||||
hostname,
|
||||
ads->config.realm);
|
||||
strlower(&psp2[5]);
|
||||
servicePrincipalName[3] = psp2;
|
||||
|
||||
free(ou_str);
|
||||
if (!new_dn)
|
||||
@ -1405,6 +1411,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
|
||||
size_t sd_size = 0;
|
||||
struct berval bval = {0, NULL};
|
||||
prs_struct ps_wire;
|
||||
char *escaped_hostname = escape_ldap_string_alloc(hostname);
|
||||
|
||||
LDAPMessage *res = 0;
|
||||
LDAPMessage *msg = 0;
|
||||
@ -1420,11 +1427,18 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
|
||||
|
||||
ret = ADS_ERROR(LDAP_SUCCESS);
|
||||
|
||||
if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) {
|
||||
DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n"));
|
||||
if (!escaped_hostname) {
|
||||
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) {
|
||||
DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n"));
|
||||
SAFE_FREE(escaped_hostname);
|
||||
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
SAFE_FREE(escaped_hostname);
|
||||
|
||||
ret = ads_search(ads, (void *) &res, exp, attrs);
|
||||
|
||||
if (!ADS_ERR_OK(ret)) return ret;
|
||||
|
@ -30,10 +30,15 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user)
|
||||
ADS_STATUS status;
|
||||
char *exp;
|
||||
const char *attrs[] = {"*", NULL};
|
||||
char *escaped_user = escape_ldap_string_alloc(user);
|
||||
if (!escaped_user) {
|
||||
return ADS_ERROR(LDAP_NO_MEMORY);
|
||||
}
|
||||
|
||||
asprintf(&exp, "(samAccountName=%s)", user);
|
||||
asprintf(&exp, "(samAccountName=%s)", escaped_user);
|
||||
status = ads_search(ads, res, exp, attrs);
|
||||
free(exp);
|
||||
SAFE_FREE(exp);
|
||||
SAFE_FREE(escaped_user);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -346,10 +346,17 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
|
||||
ADS_STATUS rc;
|
||||
uint32 atype;
|
||||
DOM_SID sid;
|
||||
char *escaped_dn = escape_ldap_string_alloc(dn);
|
||||
|
||||
if (!escaped_dn) {
|
||||
return False;
|
||||
}
|
||||
|
||||
asprintf(&exp, "(distinguishedName=%s)", dn);
|
||||
rc = ads_search_retry(ads, &res, exp, attrs);
|
||||
free(exp);
|
||||
SAFE_FREE(exp);
|
||||
SAFE_FREE(escaped_dn);
|
||||
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
goto failed;
|
||||
}
|
||||
|
@ -666,7 +666,12 @@ static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state,
|
||||
LDAPMessage ** result)
|
||||
{
|
||||
pstring filter;
|
||||
|
||||
char *escape_user = escape_ldap_string_alloc(user);
|
||||
|
||||
if (!escape_user) {
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* in the filter expression, replace %u with the real name
|
||||
* so in ldap filter, %u MUST exist :-)
|
||||
@ -677,7 +682,10 @@ static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state,
|
||||
* have to use this here because $ is filtered out
|
||||
* in pstring_sub
|
||||
*/
|
||||
all_string_sub(filter, "%u", user, sizeof(pstring));
|
||||
|
||||
|
||||
all_string_sub(filter, "%u", escape_user, sizeof(pstring));
|
||||
SAFE_FREE(escape_user);
|
||||
|
||||
return ldapsam_search_one_user(ldap_state, filter, result);
|
||||
}
|
||||
@ -691,6 +699,7 @@ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
|
||||
{
|
||||
struct passwd *user;
|
||||
pstring filter;
|
||||
char *escape_user;
|
||||
|
||||
/* Get the username from the system and look that up in the LDAP */
|
||||
|
||||
@ -701,9 +710,16 @@ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
|
||||
|
||||
pstrcpy(filter, lp_ldap_filter());
|
||||
|
||||
all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
|
||||
escape_user = escape_ldap_string_alloc(user->pw_name);
|
||||
if (!escape_user) {
|
||||
passwd_free(&user);
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
all_string_sub(filter, "%u", escape_user, sizeof(pstring));
|
||||
|
||||
passwd_free(&user);
|
||||
SAFE_FREE(escape_user);
|
||||
|
||||
return ldapsam_search_one_user(ldap_state, filter, result);
|
||||
}
|
||||
|
@ -308,12 +308,18 @@ static int ads_user_info(int argc, const char **argv)
|
||||
const char *attrs[] = {"memberOf", NULL};
|
||||
char *searchstring=NULL;
|
||||
char **grouplist;
|
||||
char *escaped_user = escape_ldap_string_alloc(argv[0]);
|
||||
|
||||
if (argc < 1) return net_ads_user_usage(argc, argv);
|
||||
|
||||
if (!(ads = ads_startup())) return -1;
|
||||
|
||||
asprintf(&searchstring, "(sAMAccountName=%s)", argv[0]);
|
||||
if (!escaped_user) {
|
||||
d_printf("ads_user_info: failed to escape user %s\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user);
|
||||
rc = ads_search(ads, &res, searchstring, attrs);
|
||||
safe_free(searchstring);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user