4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include "ns_internal.h"
31 #include "ldap_common.h"
33 /* protocols attributes filters */
35 #define _P_PROTO "ipprotocolnumber"
36 #define _F_GETPROTOBYNAME "(&(objectClass=ipProtocol)(cn=%s))"
37 #define _F_GETPROTOBYNAME_SSD "(&(%%s)(cn=%s))"
38 #define _F_GETPROTOBYNUMBER \
39 "(&(objectClass=ipProtocol)(ipProtocolNumber=%d))"
40 #define _F_GETPROTOBYNUMBER_SSD \
41 "(&(%%s)(ipProtocolNumber=%d))"
43 static const char *protocols_attrs
[] = {
49 typedef struct protocol_alias
{
54 static const protocol_alias_t ip_aliases
[10] = {
57 { "ipcomp", "IPComp" },
59 { "ipv6-route", "IPv6-Route" },
60 { "ipv6-frag", "IPv6-Frag" },
61 { "ipv6-icmp", "IPv6-ICMP" },
62 { "ipv6-nonxt", "IPv6-NoNxt" },
63 { "ipv6-opts", "IPv6-Opts" },
68 * When the data is imported by ldapaddent, it does not save the aliase in the
69 * "cn" that is same as the canonical name but only different in case.
80 * So it needs to replicate the canonical name as an alias of upper case.
81 * But some protocol does have different aliases.
90 * For many ip* protocols, the aliases are mixed cased. Maybe it's case
91 * insensitive. But this fucntion tries to restore the aliases to the original
92 * form as much as possible. If the alias can't be found in the aliases table,
93 * it assumes the alias is all upper case.
97 get_alias(char *protocol
) {
101 if (strncmp(protocol
, "ip", 2) == 0) {
102 for (i
= 0; ip_aliases
[i
].protocol
!= NULL
; i
++) {
103 if (strcmp(protocol
, ip_aliases
[i
].protocol
) == 0)
104 return (ip_aliases
[i
].alias
);
107 * No aliase in the table. Return an all upper case aliase
109 for (cp
= protocol
; *cp
; cp
++)
114 /* Return an all upper case aliase */
115 for (cp
= protocol
; *cp
; cp
++)
123 * _nss_ldap_protocols2str is the data marshaling method for the protocols
124 * getXbyY * (e.g., getbyname(), getbynumber(), getent()) backend processes.
125 * This method is called after a successful ldap search has been performed.
126 * This method will parse the ldap search values into a file format.
134 _nss_ldap_protocols2str(ldap_backend_ptr be
, nss_XbyY_args_t
*argp
)
140 char *buffer
= NULL
, **number
, *alias
;
141 ns_ldap_result_t
*result
= be
->result
;
142 ns_ldap_attr_t
*names
;
145 return (NSS_STR_PARSE_PARSE
);
147 buflen
= argp
->buf
.buflen
;
148 if (argp
->buf
.result
!= NULL
) {
149 if ((be
->buffer
= calloc(1, buflen
)) == NULL
) {
150 nss_result
= NSS_STR_PARSE_PARSE
;
155 buffer
= argp
->buf
.buffer
;
157 nss_result
= NSS_STR_PARSE_SUCCESS
;
158 (void) memset(argp
->buf
.buffer
, 0, buflen
);
160 names
= __ns_ldap_getAttrStruct(result
->entry
, _P_NAME
);
161 if (names
== NULL
|| names
->attrvalue
== NULL
) {
162 nss_result
= NSS_STR_PARSE_PARSE
;
165 /* Get the canonical name */
166 cname
= __s_api_get_canonical_name(result
->entry
, names
, 1);
167 if (cname
== NULL
|| (len
= strlen(cname
)) < 1) {
168 nss_result
= NSS_STR_PARSE_PARSE
;
171 number
= __ns_ldap_getAttr(result
->entry
, _P_PROTO
);
172 if (number
== NULL
|| number
[0] == NULL
||
173 (len
= strlen(number
[0])) < 1) {
174 nss_result
= NSS_STR_PARSE_PARSE
;
177 len
= snprintf(buffer
, buflen
, "%s %s", cname
, number
[0]);
178 TEST_AND_ADJUST(len
, buffer
, buflen
, result_pls2str
);
180 if (names
->value_count
== 1) {
181 /* create an aliase from protocol name */
182 alias
= get_alias(cname
);
183 len
= snprintf(buffer
, buflen
, " %s", alias
);
184 TEST_AND_ADJUST(len
, buffer
, buflen
, result_pls2str
);
187 for (i
= 0; i
< names
->value_count
; i
++) {
188 if (names
->attrvalue
[i
] == NULL
) {
189 nss_result
= NSS_STR_PARSE_PARSE
;
192 /* Skip the canonical name */
193 if (strcasecmp(names
->attrvalue
[i
], cname
) != 0) {
194 len
= snprintf(buffer
, buflen
, " %s",
195 names
->attrvalue
[i
]);
196 TEST_AND_ADJUST(len
, buffer
, buflen
,
202 /* The front end marshaller doesn't need to copy trailing nulls */
203 if (argp
->buf
.result
!= NULL
)
204 be
->buflen
= strlen(be
->buffer
);
208 (void) __ns_ldap_freeResult(&be
->result
);
209 return ((int)nss_result
);
214 * getbyname gets struct protoent values by protocol name. This
215 * function constructs an ldap search filter using the protocol
216 * name invocation parameter and the getprotobyname search filter
217 * defined. Once the filter is constructed, we search for a matching
218 * entry and marshal the data results into *proto = (struct *
219 * protoent *)argp->buf.result. The function _nss_ldap_protocols2ent
220 * performs the data marshaling.
224 getbyname(ldap_backend_ptr be
, void *a
)
226 nss_XbyY_args_t
*argp
= (nss_XbyY_args_t
*)a
;
227 char searchfilter
[SEARCHFILTERLEN
];
228 char userdata
[SEARCHFILTERLEN
];
229 char name
[SEARCHFILTERLEN
];
232 if (_ldap_filter_name(name
, argp
->key
.name
, sizeof (name
)) != 0)
233 return ((nss_status_t
)NSS_NOTFOUND
);
235 ret
= snprintf(searchfilter
, sizeof (searchfilter
),
236 _F_GETPROTOBYNAME
, name
);
237 if (ret
>= sizeof (searchfilter
) || ret
< 0)
238 return ((nss_status_t
)NSS_NOTFOUND
);
240 ret
= snprintf(userdata
, sizeof (userdata
),
241 _F_GETPROTOBYNAME_SSD
, name
);
242 if (ret
>= sizeof (userdata
) || ret
< 0)
243 return ((nss_status_t
)NSS_NOTFOUND
);
245 return ((nss_status_t
)_nss_ldap_lookup(be
, argp
,
246 _PROTOCOLS
, searchfilter
, NULL
,
247 _merge_SSD_filter
, userdata
));
252 * getbynumber gets struct protoent values by protocol number. This
253 * function constructs an ldap search filter using the protocol
254 * name invocation parameter and the getprotobynumber search filter
255 * defined. Once the filter is constructed, we search for a matching
256 * entry and marshal the data results into *proto = (struct *
257 * protoent *)argp->buf.result. The function _nss_ldap_protocols2ent
258 * performs the data marshaling.
262 getbynumber(ldap_backend_ptr be
, void *a
)
264 nss_XbyY_args_t
*argp
= (nss_XbyY_args_t
*)a
;
265 char searchfilter
[SEARCHFILTERLEN
];
266 char userdata
[SEARCHFILTERLEN
];
269 ret
= snprintf(searchfilter
, sizeof (searchfilter
),
270 _F_GETPROTOBYNUMBER
, argp
->key
.number
);
271 if (ret
>= sizeof (searchfilter
) || ret
< 0)
272 return ((nss_status_t
)NSS_NOTFOUND
);
274 ret
= snprintf(userdata
, sizeof (userdata
),
275 _F_GETPROTOBYNUMBER_SSD
, argp
->key
.number
);
276 if (ret
>= sizeof (userdata
) || ret
< 0)
277 return ((nss_status_t
)NSS_NOTFOUND
);
279 return ((nss_status_t
)_nss_ldap_lookup(be
, argp
,
280 _PROTOCOLS
, searchfilter
, NULL
,
281 _merge_SSD_filter
, userdata
));
284 static ldap_backend_op_t proto_ops
[] = {
295 * _nss_ldap_protocols_constr is where life begins. This function calls
296 * the generic ldap constructor function to define and build the abstract
297 * data types required to support ldap operations.
302 _nss_ldap_protocols_constr(const char *dummy1
, const char *dummy2
,
306 return ((nss_backend_t
*)_nss_ldap_constr(proto_ops
,
307 sizeof (proto_ops
)/sizeof (proto_ops
[0]), _PROTOCOLS
,
308 protocols_attrs
, _nss_ldap_protocols2str
));