Move some functions from ldap.c to ldap_util.c.

These will be used by the LDAP innetgr() implementation.
This commit is contained in:
Todd C. Miller
2023-03-10 10:02:36 -07:00
parent 0aad96bba1
commit 554df8d934
4 changed files with 151 additions and 148 deletions

View File

@@ -632,3 +632,119 @@ sudo_ldap_new_member_all(void)
m->type = ALL;
debug_return_ptr(m);
}
/*
* Determine length of query value after escaping characters
* as per RFC 4515.
*/
size_t
sudo_ldap_value_len(const char *value)
{
const char *s;
size_t len = 0;
for (s = value; *s != '\0'; s++) {
switch (*s) {
case '\\':
case '(':
case ')':
case '*':
len += 2;
break;
}
}
len += (size_t)(s - value);
return len;
}
/*
* Like strlcat() but escapes characters as per RFC 4515.
*/
size_t
sudo_ldap_value_cat(char *dst, const char *src, size_t size)
{
char *d = dst;
const char *s = src;
size_t n = size;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = size - dlen;
if (n == 0)
return dlen + strlen(s);
while (*s != '\0') {
switch (*s) {
case '\\':
if (n < 3)
goto done;
*d++ = '\\';
*d++ = '5';
*d++ = 'c';
n -= 3;
break;
case '(':
if (n < 3)
goto done;
*d++ = '\\';
*d++ = '2';
*d++ = '8';
n -= 3;
break;
case ')':
if (n < 3)
goto done;
*d++ = '\\';
*d++ = '2';
*d++ = '9';
n -= 3;
break;
case '*':
if (n < 3)
goto done;
*d++ = '\\';
*d++ = '2';
*d++ = 'a';
n -= 3;
break;
default:
if (n < 1)
goto done;
*d++ = *s;
n--;
break;
}
s++;
}
done:
*d = '\0';
while (*s != '\0')
s++;
return dlen + (s - src); /* count does not include NUL */
}
/*
* Like strdup() but escapes characters as per RFC 4515.
*/
char *
sudo_ldap_value_dup(const char *src)
{
char *dst;
size_t size;
size = sudo_ldap_value_len(src) + 1;
dst = malloc(size);
if (dst == NULL)
return NULL;
*dst = '\0';
if (sudo_ldap_value_cat(dst, src, size) >= size) {
/* Should not be possible... */
free(dst);
dst = NULL;
}
return dst;
}