xref: /onnv-gate/usr/src/lib/libsldap/common/ns_getalias.c (revision 5402:a17d5e4e8666)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*5402Sjbeck  * Common Development and Distribution License (the "License").
6*5402Sjbeck  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*5402Sjbeck 
220Sstevel@tonic-gate /*
23*5402Sjbeck  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <libintl.h>
310Sstevel@tonic-gate #include <stdio.h>
320Sstevel@tonic-gate #include <errno.h>
330Sstevel@tonic-gate #include <strings.h>
340Sstevel@tonic-gate #include "ns_sldap.h"
350Sstevel@tonic-gate #include "ns_internal.h"
360Sstevel@tonic-gate 
370Sstevel@tonic-gate /*
380Sstevel@tonic-gate  * getldaplaliasbyname() retrieves the aliases information from the LDAP server.
390Sstevel@tonic-gate  * This is requires that the LDAP naming information (ie. LDAP_CLIENT_CACHE
400Sstevel@tonic-gate  * file) is configured properly on the client machine.
410Sstevel@tonic-gate  *
420Sstevel@tonic-gate  * Return value:
430Sstevel@tonic-gate  *      0 = success;
440Sstevel@tonic-gate  *      1 = alias not found;
450Sstevel@tonic-gate  *      -1 = other failure.  Contents in answer are undefined.
460Sstevel@tonic-gate  */
470Sstevel@tonic-gate 
480Sstevel@tonic-gate #define	ALIAS_FILTER	 "(&(objectclass=mailgroup)(|(cn=%s)(mail=%s)))"
490Sstevel@tonic-gate #define	ALIAS_FILTER_SSD "(&(%%s)(|(cn=%s)(mail=%s)))"
500Sstevel@tonic-gate #define	MAIL_CN		"cn"
510Sstevel@tonic-gate #define	MAIL_ATTRIBUTE	"mail"
520Sstevel@tonic-gate #define	MAIL_MEMBER	"mgrpRFC822MailMember"
530Sstevel@tonic-gate 
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate  * This is a generic filter call back function for
560Sstevel@tonic-gate  * merging the filter from service search descriptor with
570Sstevel@tonic-gate  * an existing search filter. This routine expects userdata
580Sstevel@tonic-gate  * contain a format string with a single %s in it, and will
590Sstevel@tonic-gate  * use the format string with sprintf() to insert the SSD filter.
600Sstevel@tonic-gate  *
610Sstevel@tonic-gate  * This routine is passed to the __ns_ldap_list() API as the
620Sstevel@tonic-gate  * filter call back together with filter and userdata. For example,
630Sstevel@tonic-gate  * "(&(objectclass=mailgroup)(|(cn=abc)(mail=abc)))" as filter
640Sstevel@tonic-gate  * and "(&(%s)(|(cn=abc)(mail=abc)))" as userdata.
650Sstevel@tonic-gate  * This routine will then be called by __ns_ldap_list() to output
660Sstevel@tonic-gate  * "(&(dept=sds)(|(cn=abc)(mail=abc)))" as the real search
670Sstevel@tonic-gate  * filter, if the input SSD contains a filter "dpet=sds".
680Sstevel@tonic-gate  */
690Sstevel@tonic-gate int
__s_api_merge_SSD_filter(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata)700Sstevel@tonic-gate __s_api_merge_SSD_filter(const ns_ldap_search_desc_t *desc,
710Sstevel@tonic-gate 			char **realfilter,
720Sstevel@tonic-gate 			const void *userdata)
730Sstevel@tonic-gate {
740Sstevel@tonic-gate 	int	len;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	/* sanity check */
770Sstevel@tonic-gate 	if (realfilter == NULL)
780Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
790Sstevel@tonic-gate 	*realfilter = NULL;
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	if (desc == NULL || desc->filter == NULL ||
820Sstevel@tonic-gate 			userdata == NULL)
830Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	len = strlen(userdata) + strlen(desc->filter) + 1;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	*realfilter = (char *)malloc(len);
880Sstevel@tonic-gate 	if (*realfilter == NULL)
890Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	(void) sprintf(*realfilter, (char *)userdata,
920Sstevel@tonic-gate 			desc->filter);
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
950Sstevel@tonic-gate }
96*5402Sjbeck char *
__getldapaliasbyname(char * alias,int * retval)97*5402Sjbeck __getldapaliasbyname(char *alias, int *retval)
980Sstevel@tonic-gate {
990Sstevel@tonic-gate 	char		*service = "aliases";
1000Sstevel@tonic-gate 	char		filter[BUFSIZE];
1010Sstevel@tonic-gate 	char		userdata[BUFSIZE];
1020Sstevel@tonic-gate 	char		*attribute[2];
1030Sstevel@tonic-gate 	ns_ldap_result_t	*result = NULL;
1040Sstevel@tonic-gate 	ns_ldap_error_t	*errorp = NULL;
1050Sstevel@tonic-gate 	int		rc, i, j, len, comma;
1060Sstevel@tonic-gate 	ns_ldap_entry_t	*entry = NULL;
1070Sstevel@tonic-gate 	char		**attr_value = NULL;
108*5402Sjbeck 	char		*answer, *new_answer;
109*5402Sjbeck 	size_t		ans_size = BUFSIZE;
1100Sstevel@tonic-gate 
111*5402Sjbeck 	if (!alias || !*alias) {
1120Sstevel@tonic-gate 		errno = EINVAL;
113*5402Sjbeck 		*retval = -1;
114*5402Sjbeck 		return (NULL);
1150Sstevel@tonic-gate 	}
1160Sstevel@tonic-gate 
117*5402Sjbeck 	answer = malloc(ans_size);
118*5402Sjbeck 	if (answer == NULL) {
119*5402Sjbeck 		errno = ENOMEM;
120*5402Sjbeck 		*retval = -1;
121*5402Sjbeck 		return (NULL);
122*5402Sjbeck 	}
1230Sstevel@tonic-gate 	answer[0] = '\0';
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	/* get the aliases */
1260Sstevel@tonic-gate 	if (snprintf(filter, sizeof (filter), ALIAS_FILTER, alias, alias) < 0) {
1270Sstevel@tonic-gate 		errno = EINVAL;
128*5402Sjbeck 		*retval = -1;
129*5402Sjbeck 		return (NULL);
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	/* get the userdata for __ns_ldap_list filter call back */
1330Sstevel@tonic-gate 	if (snprintf(userdata, sizeof (userdata), ALIAS_FILTER_SSD,
1340Sstevel@tonic-gate 	    alias, alias) < 0) {
1350Sstevel@tonic-gate 		errno = EINVAL;
136*5402Sjbeck 		*retval = -1;
137*5402Sjbeck 		return (NULL);
1380Sstevel@tonic-gate 	}
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	attribute[0] = MAIL_MEMBER;
1410Sstevel@tonic-gate 	attribute[1] = NULL;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	/* should we do hardlookup */
1440Sstevel@tonic-gate 	rc = __ns_ldap_list(service, (const char *)filter,
1450Sstevel@tonic-gate 		__s_api_merge_SSD_filter,
1460Sstevel@tonic-gate 		(const char **)attribute, NULL, 0, &result,
1470Sstevel@tonic-gate 		&errorp, NULL, userdata);
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	if (rc == NS_LDAP_NOTFOUND) {
1500Sstevel@tonic-gate 		errno = ENOENT;
151*5402Sjbeck 		*retval = 1;
152*5402Sjbeck 		return (NULL);
1530Sstevel@tonic-gate 	} else if (rc != NS_LDAP_SUCCESS) {
1540Sstevel@tonic-gate #ifdef DEBUG
1550Sstevel@tonic-gate 		char *p;
1560Sstevel@tonic-gate 		(void) __ns_ldap_err2str(rc, &p);
1570Sstevel@tonic-gate 		if (errorp) {
1580Sstevel@tonic-gate 			if (errorp->message)
1590Sstevel@tonic-gate 				(void) fprintf(stderr, "%s (%s)\n", p,
1600Sstevel@tonic-gate 					errorp->message);
1610Sstevel@tonic-gate 		} else
1620Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", p);
1630Sstevel@tonic-gate #endif /* DEBUG */
1640Sstevel@tonic-gate 		(void) __ns_ldap_freeError(&errorp);
165*5402Sjbeck 		*retval = -1;
166*5402Sjbeck 		return (NULL);
1670Sstevel@tonic-gate 	}
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	/* build the return value */
1700Sstevel@tonic-gate 	answer[0] = '\0';
1710Sstevel@tonic-gate 	len = 0;
1720Sstevel@tonic-gate 	comma = 0;
1730Sstevel@tonic-gate 	entry = result->entry;
1740Sstevel@tonic-gate 	for (i = 0; i < result->entries_count; i++) {
1750Sstevel@tonic-gate 		attr_value = __ns_ldap_getAttr(entry, MAIL_MEMBER);
1760Sstevel@tonic-gate 		if (attr_value == NULL) {
1770Sstevel@tonic-gate 			errno = ENOENT;
178*5402Sjbeck 			*retval = -1;
179*5402Sjbeck 			return (NULL);
1800Sstevel@tonic-gate 		}
1810Sstevel@tonic-gate 		for (j = 0; attr_value[j]; j++) {
1820Sstevel@tonic-gate 			char	*tmp, *newhead;
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 			tmp = attr_value[j];
1850Sstevel@tonic-gate 			while (*tmp == ' ' || *tmp == '\t' && *tmp != '\0')
1860Sstevel@tonic-gate 				tmp++;
1870Sstevel@tonic-gate 			newhead = tmp;
1880Sstevel@tonic-gate 			while (*tmp != '\0') tmp++;
1890Sstevel@tonic-gate 			while (*tmp == ' ' || *tmp == '\t' || *tmp == '\0' &&
1900Sstevel@tonic-gate 			    tmp != newhead) {
1910Sstevel@tonic-gate 				*tmp-- = '\0';
1920Sstevel@tonic-gate 			}
1930Sstevel@tonic-gate 			len = len + comma + strlen(newhead);
194*5402Sjbeck 			if ((len + 1) > ans_size) {
195*5402Sjbeck 				ans_size += BUFSIZE;
196*5402Sjbeck 				new_answer = realloc(answer, ans_size);
197*5402Sjbeck 				if (new_answer == NULL) {
198*5402Sjbeck 					(void) __ns_ldap_freeResult(&result);
199*5402Sjbeck 					errno = ENOMEM;
200*5402Sjbeck 					*retval = -1;
201*5402Sjbeck 					free(answer);
202*5402Sjbeck 					return (NULL);
203*5402Sjbeck 				}
204*5402Sjbeck 				answer = new_answer;
2050Sstevel@tonic-gate 			}
2060Sstevel@tonic-gate 			if (comma)
2070Sstevel@tonic-gate 				(void) strcat(answer, ",");
2080Sstevel@tonic-gate 			else
2090Sstevel@tonic-gate 				comma = 1;
2100Sstevel@tonic-gate 			(void) strcat(answer, newhead);
2110Sstevel@tonic-gate 		}
2120Sstevel@tonic-gate 	}
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&result);
2150Sstevel@tonic-gate 	errno = 0;
216*5402Sjbeck 	*retval = 0;
217*5402Sjbeck 	return (answer);
2180Sstevel@tonic-gate }
219