1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <sys/systeminfo.h>
30*0Sstevel@tonic-gate #include "ldap_common.h"
31*0Sstevel@tonic-gate
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate #ifdef DEBUG
34*0Sstevel@tonic-gate /*
35*0Sstevel@tonic-gate * Debugging routine for printing the value of a result
36*0Sstevel@tonic-gate * structure
37*0Sstevel@tonic-gate */
38*0Sstevel@tonic-gate int
printresult(ns_ldap_result_t * result)39*0Sstevel@tonic-gate printresult(ns_ldap_result_t *result)
40*0Sstevel@tonic-gate {
41*0Sstevel@tonic-gate int i, j, k;
42*0Sstevel@tonic-gate ns_ldap_entry_t *curEntry;
43*0Sstevel@tonic-gate
44*0Sstevel@tonic-gate printf("--------------------------------------\n");
45*0Sstevel@tonic-gate printf("entries_count %d\n", result->entries_count);
46*0Sstevel@tonic-gate curEntry = result->entry;
47*0Sstevel@tonic-gate for (i = 0; i < result->entries_count; i++) {
48*0Sstevel@tonic-gate printf("entry %d has attr_count = %d \n",
49*0Sstevel@tonic-gate i, curEntry->attr_count);
50*0Sstevel@tonic-gate for (j = 0; j < curEntry->attr_count; j++) {
51*0Sstevel@tonic-gate printf("entry %d has attr_pair[%d] = %s \n",
52*0Sstevel@tonic-gate i, j, curEntry->attr_pair[j]->attrname);
53*0Sstevel@tonic-gate for (k = 0;
54*0Sstevel@tonic-gate (k < curEntry->attr_pair[j]->value_count) &&
55*0Sstevel@tonic-gate (curEntry->attr_pair[j]->attrvalue[k]);
56*0Sstevel@tonic-gate k++)
57*0Sstevel@tonic-gate printf("entry %d has "
58*0Sstevel@tonic-gate "attr_pair[%d]->attrvalue[%d] = %s \n",
59*0Sstevel@tonic-gate i, j, k,
60*0Sstevel@tonic-gate curEntry->attr_pair[j]->attrvalue[k]);
61*0Sstevel@tonic-gate }
62*0Sstevel@tonic-gate printf("\n--------------------------------------\n");
63*0Sstevel@tonic-gate curEntry = curEntry->next;
64*0Sstevel@tonic-gate }
65*0Sstevel@tonic-gate return (1);
66*0Sstevel@tonic-gate }
67*0Sstevel@tonic-gate #endif
68*0Sstevel@tonic-gate
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gate /*
71*0Sstevel@tonic-gate *
72*0Sstevel@tonic-gate */
73*0Sstevel@tonic-gate
74*0Sstevel@tonic-gate ns_ldap_attr_t *
getattr(ns_ldap_result_t * result,int i)75*0Sstevel@tonic-gate getattr(ns_ldap_result_t *result, int i)
76*0Sstevel@tonic-gate {
77*0Sstevel@tonic-gate ns_ldap_entry_t *entry;
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate #ifdef DEBUG
80*0Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_utils.c: getattr]\n");
81*0Sstevel@tonic-gate #endif /* DEBUG */
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate if (result != NULL) {
84*0Sstevel@tonic-gate entry = result->entry;
85*0Sstevel@tonic-gate } else {
86*0Sstevel@tonic-gate return (NULL);
87*0Sstevel@tonic-gate }
88*0Sstevel@tonic-gate if (result->entries_count == 0) {
89*0Sstevel@tonic-gate return (NULL);
90*0Sstevel@tonic-gate } else {
91*0Sstevel@tonic-gate return (entry->attr_pair[i]);
92*0Sstevel@tonic-gate }
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate /*
96*0Sstevel@tonic-gate * _get_domain_name() passes the dn one level up from cdn, e.g.,
97*0Sstevel@tonic-gate * a pointer pointing to "ou= ..." for the cdn's listed below:
98*0Sstevel@tonic-gate * dn: cn=hostname+ipHostNumber="109.34.54.76", ou= ...
99*0Sstevel@tonic-gate * dn: echo+IpServiceProtocol=udp, ou= ...
100*0Sstevel@tonic-gate * to __ns_ldap_dn2domain() to retrieve the domain name associated
101*0Sstevel@tonic-gate * with cdn.
102*0Sstevel@tonic-gate */
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gate char *
_get_domain_name(char * cdn)105*0Sstevel@tonic-gate _get_domain_name(char *cdn)
106*0Sstevel@tonic-gate {
107*0Sstevel@tonic-gate char **rdns;
108*0Sstevel@tonic-gate char *pdn, *domain = NULL;
109*0Sstevel@tonic-gate int nrdns;
110*0Sstevel@tonic-gate int len = 0;
111*0Sstevel@tonic-gate const ns_cred_t *cred = NULL;
112*0Sstevel@tonic-gate ns_ldap_error_t *error;
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate /* break the cdn into its components */
115*0Sstevel@tonic-gate rdns = ldap_explode_dn(cdn, 0);
116*0Sstevel@tonic-gate if (rdns == NULL || *rdns == NULL)
117*0Sstevel@tonic-gate return (NULL);
118*0Sstevel@tonic-gate
119*0Sstevel@tonic-gate /* construct parent dn */
120*0Sstevel@tonic-gate for (nrdns = 1; rdns[nrdns]; nrdns++)
121*0Sstevel@tonic-gate len += strlen(rdns[nrdns]) + 1;
122*0Sstevel@tonic-gate if (len == 0)
123*0Sstevel@tonic-gate len = strlen(rdns[0]);
124*0Sstevel@tonic-gate pdn = (char *)malloc(len + 1);
125*0Sstevel@tonic-gate if (pdn == NULL) {
126*0Sstevel@tonic-gate ldap_value_free(rdns);
127*0Sstevel@tonic-gate return (NULL);
128*0Sstevel@tonic-gate }
129*0Sstevel@tonic-gate
130*0Sstevel@tonic-gate *pdn = '\0';
131*0Sstevel@tonic-gate if (nrdns == 1)
132*0Sstevel@tonic-gate (void) strcat(pdn, rdns[0]);
133*0Sstevel@tonic-gate else {
134*0Sstevel@tonic-gate for (nrdns = 1; rdns[nrdns]; nrdns++) {
135*0Sstevel@tonic-gate (void) strcat(pdn, rdns[nrdns]);
136*0Sstevel@tonic-gate (void) strcat(pdn, ",");
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate /* remove the last ',' */
139*0Sstevel@tonic-gate pdn[strlen(pdn) - 1] = '\0';
140*0Sstevel@tonic-gate }
141*0Sstevel@tonic-gate /* get domain name */
142*0Sstevel@tonic-gate (void) __ns_ldap_dn2domain(pdn, &domain, cred, &error);
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gate ldap_value_free(rdns);
145*0Sstevel@tonic-gate free(pdn);
146*0Sstevel@tonic-gate return (domain);
147*0Sstevel@tonic-gate }
148*0Sstevel@tonic-gate
149*0Sstevel@tonic-gate
150*0Sstevel@tonic-gate /*
151*0Sstevel@tonic-gate * "109.34.54.76" -> 109.34.54.76
152*0Sstevel@tonic-gate */
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate const char *
_strip_quotes(char * ipaddress)155*0Sstevel@tonic-gate _strip_quotes(char *ipaddress)
156*0Sstevel@tonic-gate {
157*0Sstevel@tonic-gate char *cp = (char *)NULL;
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate /* look for first " */
160*0Sstevel@tonic-gate if ((cp = strchr(ipaddress, '"')) == NULL)
161*0Sstevel@tonic-gate return ((char *)ipaddress);
162*0Sstevel@tonic-gate ipaddress++;
163*0Sstevel@tonic-gate /* look for last " */
164*0Sstevel@tonic-gate if ((cp = strchr(ipaddress, '"')) == NULL)
165*0Sstevel@tonic-gate return ((char *)ipaddress);
166*0Sstevel@tonic-gate *cp++ = '\0';
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate return (ipaddress);
169*0Sstevel@tonic-gate }
170*0Sstevel@tonic-gate
171*0Sstevel@tonic-gate
172*0Sstevel@tonic-gate /*
173*0Sstevel@tonic-gate * This is a copy of a routine in libnsl/nss/netdir_inet.c. It is
174*0Sstevel@tonic-gate * here because /etc/lib/nss_ldap.so.1 cannot call routines in
175*0Sstevel@tonic-gate * libnsl. Care should be taken to keep the two copies in sync.
176*0Sstevel@tonic-gate */
177*0Sstevel@tonic-gate
178*0Sstevel@tonic-gate int
__nss2herrno(nss_status_t nsstat)179*0Sstevel@tonic-gate __nss2herrno(nss_status_t nsstat)
180*0Sstevel@tonic-gate {
181*0Sstevel@tonic-gate switch (nsstat) {
182*0Sstevel@tonic-gate case NSS_SUCCESS:
183*0Sstevel@tonic-gate return (0);
184*0Sstevel@tonic-gate case NSS_NOTFOUND:
185*0Sstevel@tonic-gate return (HOST_NOT_FOUND);
186*0Sstevel@tonic-gate case NSS_TRYAGAIN:
187*0Sstevel@tonic-gate return (TRY_AGAIN);
188*0Sstevel@tonic-gate case NSS_UNAVAIL:
189*0Sstevel@tonic-gate default: /* keep gcc happy */
190*0Sstevel@tonic-gate return (NO_RECOVERY);
191*0Sstevel@tonic-gate }
192*0Sstevel@tonic-gate /* NOTREACHED */
193*0Sstevel@tonic-gate }
194*0Sstevel@tonic-gate
195*0Sstevel@tonic-gate /*
196*0Sstevel@tonic-gate * This is a generic filter call back function for
197*0Sstevel@tonic-gate * merging the filter from service search descriptor with
198*0Sstevel@tonic-gate * an existing search filter. This routine expects userdata
199*0Sstevel@tonic-gate * contain a format string with a single %s in it, and will
200*0Sstevel@tonic-gate * use the format string with sprintf() to insert the SSD filter.
201*0Sstevel@tonic-gate *
202*0Sstevel@tonic-gate * This routine is passed to the __ns_ldap_list() or
203*0Sstevel@tonic-gate * __ns_ldap_firstEntry() APIs as the filter call back
204*0Sstevel@tonic-gate * together with the userdata. For example,
205*0Sstevel@tonic-gate * the gethostbyname processing may call __ns_ldap_list() with
206*0Sstevel@tonic-gate * "(&(objectClass=ipHost)(cn=sys1))" as filter, this function
207*0Sstevel@tonic-gate * as the filter call back, and "(&(%s)(cn=sys1))" as the
208*0Sstevel@tonic-gate * userdata, this routine will in turn gets call to produce
209*0Sstevel@tonic-gate * "(&(department=sds)(cn=sys1))" as the real search
210*0Sstevel@tonic-gate * filter, if the input SSD contains a filter "department=sds".
211*0Sstevel@tonic-gate */
212*0Sstevel@tonic-gate int
_merge_SSD_filter(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata)213*0Sstevel@tonic-gate _merge_SSD_filter(const ns_ldap_search_desc_t *desc,
214*0Sstevel@tonic-gate char **realfilter,
215*0Sstevel@tonic-gate const void *userdata)
216*0Sstevel@tonic-gate {
217*0Sstevel@tonic-gate int len;
218*0Sstevel@tonic-gate
219*0Sstevel@tonic-gate #ifdef DEBUG
220*0Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_utils.c: _merge_SSD_filter]\n");
221*0Sstevel@tonic-gate #endif /* DEBUG */
222*0Sstevel@tonic-gate
223*0Sstevel@tonic-gate /* sanity check */
224*0Sstevel@tonic-gate if (realfilter == NULL)
225*0Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM);
226*0Sstevel@tonic-gate *realfilter = NULL;
227*0Sstevel@tonic-gate
228*0Sstevel@tonic-gate if (desc == NULL || desc->filter == NULL ||
229*0Sstevel@tonic-gate userdata == NULL)
230*0Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM);
231*0Sstevel@tonic-gate
232*0Sstevel@tonic-gate #ifdef DEBUG
233*0Sstevel@tonic-gate (void) fprintf(stdout, "\n[userdata: %s]\n", (char *)userdata);
234*0Sstevel@tonic-gate (void) fprintf(stdout, "\n[SSD filter: %s]\n", desc->filter);
235*0Sstevel@tonic-gate #endif /* DEBUG */
236*0Sstevel@tonic-gate
237*0Sstevel@tonic-gate len = strlen(userdata) + strlen(desc->filter) + 1;
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate *realfilter = (char *)malloc(len);
240*0Sstevel@tonic-gate if (*realfilter == NULL)
241*0Sstevel@tonic-gate return (NS_LDAP_MEMORY);
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gate (void) sprintf(*realfilter, (char *)userdata,
244*0Sstevel@tonic-gate desc->filter);
245*0Sstevel@tonic-gate
246*0Sstevel@tonic-gate #ifdef DEBUG
247*0Sstevel@tonic-gate (void) fprintf(stdout, "\n[new filter: %s]\n", *realfilter);
248*0Sstevel@tonic-gate #endif /* DEBUG */
249*0Sstevel@tonic-gate
250*0Sstevel@tonic-gate return (NS_LDAP_SUCCESS);
251*0Sstevel@tonic-gate }
252*0Sstevel@tonic-gate
253*0Sstevel@tonic-gate static char
hex_char(int n)254*0Sstevel@tonic-gate hex_char(int n)
255*0Sstevel@tonic-gate {
256*0Sstevel@tonic-gate return ("0123456789abcdef"[n & 0xf]);
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate
259*0Sstevel@tonic-gate int
_ldap_filter_name(char * filter_name,const char * name,int filter_name_size)260*0Sstevel@tonic-gate _ldap_filter_name(char *filter_name, const char *name, int filter_name_size)
261*0Sstevel@tonic-gate {
262*0Sstevel@tonic-gate char *end = filter_name + filter_name_size;
263*0Sstevel@tonic-gate char c;
264*0Sstevel@tonic-gate
265*0Sstevel@tonic-gate for (; *name; name++) {
266*0Sstevel@tonic-gate c = *name;
267*0Sstevel@tonic-gate switch (c) {
268*0Sstevel@tonic-gate case '*':
269*0Sstevel@tonic-gate case '(':
270*0Sstevel@tonic-gate case ')':
271*0Sstevel@tonic-gate case '\\':
272*0Sstevel@tonic-gate if (end <= filter_name + 3)
273*0Sstevel@tonic-gate return (-1);
274*0Sstevel@tonic-gate *filter_name++ = '\\';
275*0Sstevel@tonic-gate *filter_name++ = hex_char(c >> 4);
276*0Sstevel@tonic-gate *filter_name++ = hex_char(c & 0xf);
277*0Sstevel@tonic-gate break;
278*0Sstevel@tonic-gate default:
279*0Sstevel@tonic-gate if (end <= filter_name + 1)
280*0Sstevel@tonic-gate return (-1);
281*0Sstevel@tonic-gate *filter_name++ = c;
282*0Sstevel@tonic-gate break;
283*0Sstevel@tonic-gate }
284*0Sstevel@tonic-gate }
285*0Sstevel@tonic-gate if (end <= filter_name)
286*0Sstevel@tonic-gate return (-1);
287*0Sstevel@tonic-gate *filter_name = '\0';
288*0Sstevel@tonic-gate return (0);
289*0Sstevel@tonic-gate }
290