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