/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "ldap_util.h"
#include "ldap_glob.h"
/*
* Log a message to the appropriate place.
*/
void
/*
* Only log LOG_INFO priority if 'verbose' is on, or if
* msgtype is MSG_ALWAYS.
*/
return;
/* Make sure we don't log the same message too often */
return;
}
if (cons == 0) {
} else {
/*
* If the last character in 'fmt' wasn't a '\n', write one
* to the console.
*/
}
}
void
if (defErr != 0) {
}
}
static void
__initTsdKey(void)
{
}
#pragma init(__initTsdKey)
void
__nis_buffer_t b = {0, 0};
return;
if (b.len > 0) {
if (doStore) {
if (ret != 0) {
"%s: pthread_setspecific() => %d",
}
}
}
}
int
if (defErr == 0) {
if (message != 0)
return (NPL_TSDERR);
}
if (message != 0)
}
void
clearError(void) {
if (defErr != 0) {
}
}
void
int msgtype;
if (defErr != 0) {
case NPL_NOERROR:
break;
case NPL_NOMEM:
break;
case NPL_TSDERR:
break;
case NPL_BERENCODE:
case NPL_BERDECODE:
break;
default:
break;
}
if (msgtype != MSG_LASTMSG) {
}
}
}
/*
* Allocate zero-initialized memory of the specified 'size'. If the
* allocation fails, log a message and return NULL. Allocation of
* zero bytes is legal, and returns a NULL pointer.
*/
void *
void *p;
if (size > 0) {
if (p == 0) {
if (msg == 0)
msg = "<unknown>";
return (0);
}
} else if (size == 0) {
p = 0;
} else {
if (msg == 0)
msg = "<unknown>";
exit(-1);
}
return (p);
}
/*
* Return the length of a string, just like strlen(), but don't croak
* on a NULL pointer.
*/
int
}
/*
* If allocate==0, return 'str'; othewise, duplicate the string just
* like strdup(), but don't die if 'str' is a NULL pointer.
*/
char *
char *s;
if (!allocate)
return (str);
if (str == 0) {
s = strdup("");
} else {
}
if (s == 0) {
}
return (s);
}
/*
* Concatenate strings like strcat(), but don't expire if passed a
* NULL pointer or two. If deallocate!=0, free() the input strings.
*/
char *
char *n;
if (s1 == 0) {
if (deallocate)
return (n);
} else if (s2 == 0) {
if (deallocate)
return (n);
}
if (n != 0) {
} else {
}
if (deallocate) {
}
return (n);
}
/* For debugging */
static void *PTR = 0;
/*
* Counters for memory errors. Note that we don't protect access,
* so the values aren't entirely reliable in an MT application.
*/
/* free() the input, but don't pass away if it's NULL */
void
/* NULL pointer OK */
if (ptr == 0)
return;
/*
* For use in the debugger, when we need to detect free of a
* certain address.
*/
abort();
/*
* All addresses returned by malloc() and friends are "suitably
* aligned for any use", so they should fall on eight-byte boundaries.
*/
if (((unsigned long)ptr % 8) != 0) {
return;
}
#ifdef NISDB_LDAP_DEBUG
/*
* Malloc:ed memory should have the length (four bytes), starting
* eight bytes before the block, and with the least-significant
* bit set.
*/
numNotActive++;
return;
}
#endif /* NISDB_LDAP_DEBUG */
/* Finally, we believe it's OK to free() the pointer */
}
/*
* If a __nis_single_value_t represents a string, the length count may or may
* not include a concluding NUL. Hence this function, which returns the last
* non-NUL character of the value.
*/
char
char *s;
return ('\0');
s = v->value;
return (s[v->length - 1]);
else
return (s[v->length - 2]);
}
void *
void *s;
int l, nl;
if (v == 0 || v->length < 0)
return (0);
/*
* If 'str' is NULL or empty, just return NULL so that the caller
* does nothing.
*/
if (l <= 0)
return (0);
if (s == 0) {
/* Caller does nothing; let's hope for the best... */
return (0);
}
if (v->value != 0)
if (newLen != 0)
return (s);
}
/*
* Do the equivalent of a strcmp() between a string and a string-valued
* __nis_single_value_t.
*/
int
if (s == 0)
return (1);
return (-1);
}
/*
* Do the equivalent of a strcasecmp() between a string and a string-valued
* __nis_single_value_t.
*/
int
if (s == 0)
return (1);
return (-1);
}
/*
* vsprintf the 'fmt' and 'ap' to a buffer, then concatenate the
* result to '*buf'.
*/
int
int size = 0;
if (newbuf == 0)
return (0);
return (0);
}
/* Find out how large the new buffer needs to be */
if (size > STDBUFSIZE) {
if (newbuf == 0)
return (0);
}
/* Don't count the NUL. This enables us to concatenate correctly */
return (buflen);
}
/* Generic print buffer */
/* sprintf to the generic __nis_buffer_t */
void
}
/* sprintf to the specified __nis_buffer_t */
void
}
/* Copy 'buf' to the specified __nis_buffer_t */
void
void *new;
/*
* Make buffer one byte larger than the lengths indicate. This
* gives us room to append a NUL, so that we can mix string and
* non-string copies into the buffer, and still end up with
* something that can be sent to printf(), strcat(), etc.
*/
if (new != 0) {
/* Put a NUL at the end, just in case we printf() */
} else {
}
}
/* Like bc2buf(), but remove any trailing NUL bytes */
void
return;
/* Snip off trailing NULs */
len--;
if (len <= 0)
return;
}
/* Copy 'buf' to the generic __nis_buffer_t */
void
}
/* Like c2buf(), but remove trailing NUL bytes */
void
}
/* How many times we try write(2) if it fails */
/* Output the generic __nis_buffer_t to stdout */
void
printbuf(void) {
int tmp;
if (tmp < 0)
break;
if (tmp > 0)
else
maxtry--;
}
}
}
void *
if (new == 0)
return (new);
}
/*
* Determine if the given string is an IP address (IPv4 or IPv6).
* If so, it converts it to the format as required by rfc2307bis
* and *newaddr will point to the new Address.
*
* Returns -2 : error
* -1 : not an IP address
* 0 : IP address not supported by rfc2307bis
* AF_INET : IPv4
* AF_INET6 : IPv6
*/
int
char *buffer;
int s, e;
/* skip leading whitespaces */
if (s >= len)
return (-1);
/* skip trailing whitespaces */
if (s == e)
return (-1);
/* adjust len */
len = e - s + 1;
return (-2);
/*
* IPv4-compatible IPv6 address and IPv4-mapped
* IPv6 addresses not allowed by rfc2307bis
*/
if (IN6_IS_ADDR_V4COMPAT(&addr_ipv6))
return (0);
if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6))
return (0);
if (newaddr == 0)
return (AF_INET6);
return (-2);
return (AF_INET6);
return (-2);
}
if (newaddr == 0)
return (AF_INET);
return (-2);
return (AF_INET);
return (-2);
}
return (-1);
}
int
return (0);
if (s1 == 0)
return (1);
if (s2 == 0)
return (-1);
}
/*
* Does the following:
* - Trims leading and trailing whitespaces
* - Collapses two or more whitespaces into one space
* - Converts all whitespaces into spaces
* - At entrance, *len contains length of str
* - At exit, *len will contain length of the return string
* - In case of mem alloc failure, *len should be ignored
*/
char *
char *ostr;
int olen = 0;
if (deallocate)
*len = 0;
return (0);
}
/* Skip leading whitespaces */
/* Collapse multiple whitespaces into one */
for (; i < *len; i++) {
if (first) {
first = 0;
}
continue;
}
first = 1;
}
/* Handle the trailing whitespace if any */
olen--;
}
if (deallocate)
return (ostr);
}
/*
* Escapes special characters in DN using the list from RFC 2253
*/
int
int i, j, k, count;
char *newval, *s;
/* Assume val is always non NULL */
/*
* Count the special characters in value to determine
* the length for the new value
*/
if (*s == '#' || *s == ',' || *s == '+' || *s == '"' ||
*s == '\\' || *s == '<' || *s == '>' || *s == ';')
count++;
}
if (count == 0)
continue;
return (-1);
/* Escape the special characters using '\\' */
if (*s == '#' || *s == ',' || *s == '+' || *s == '"' ||
*s == '\\' || *s == '<' || *s == '>' || *s == ';')
newval[k++] = '\\';
newval[k] = *s;
}
}
return (1);
}
/*
* Remove escape characters from DN returned by LDAP server
*/
void
int i;
char *s, *d, *end;
/*
* This function is called frequently and for most entries
* there will be no escapes. Process rapidly up to first escape.
*/
for (d = s; s < end; s++, d++) {
if (*s == '\\')
break;
}
/*
* Reached the end, in which case will not go into loop,
* or found an escape and now have to start moving data.
*/
for (; s < end; s++) {
if (*s == '\\') {
/*
* Next character gets coppied without being
* checked
*/
s++;
if (s >= end)
break;
}
*d = *s;
d++;
}
}
}