1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * Copyright (c) 2001 by Sun Microsystems, Inc.
3*0Sstevel@tonic-gate * All rights reserved.
4*0Sstevel@tonic-gate */
5*0Sstevel@tonic-gate
6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
7*0Sstevel@tonic-gate
8*0Sstevel@tonic-gate /*
9*0Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public
10*0Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file
11*0Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of
12*0Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS
15*0Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16*0Sstevel@tonic-gate * implied. See the License for the specific language governing
17*0Sstevel@tonic-gate * rights and limitations under the License.
18*0Sstevel@tonic-gate *
19*0Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released
20*0Sstevel@tonic-gate * March 31, 1998.
21*0Sstevel@tonic-gate *
22*0Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape
23*0Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are
24*0Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All
25*0Sstevel@tonic-gate * Rights Reserved.
26*0Sstevel@tonic-gate *
27*0Sstevel@tonic-gate * Contributor(s):
28*0Sstevel@tonic-gate */
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate * Copyright (c) 1994 Regents of the University of Michigan.
31*0Sstevel@tonic-gate * All rights reserved.
32*0Sstevel@tonic-gate */
33*0Sstevel@tonic-gate /*
34*0Sstevel@tonic-gate * getdn.c
35*0Sstevel@tonic-gate */
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate #if 0
38*0Sstevel@tonic-gate #ifndef lint
39*0Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
40*0Sstevel@tonic-gate #endif
41*0Sstevel@tonic-gate #endif
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate #include "ldap-int.h"
44*0Sstevel@tonic-gate
45*0Sstevel@tonic-gate char *
46*0Sstevel@tonic-gate LDAP_CALL
ldap_get_dn(LDAP * ld,LDAPMessage * entry)47*0Sstevel@tonic-gate ldap_get_dn( LDAP *ld, LDAPMessage *entry )
48*0Sstevel@tonic-gate {
49*0Sstevel@tonic-gate char *dn;
50*0Sstevel@tonic-gate struct berelement tmp;
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 );
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
55*0Sstevel@tonic-gate return( NULL ); /* punt */
56*0Sstevel@tonic-gate }
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
59*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
60*0Sstevel@tonic-gate return( NULL );
61*0Sstevel@tonic-gate }
62*0Sstevel@tonic-gate
63*0Sstevel@tonic-gate tmp = *entry->lm_ber; /* struct copy */
64*0Sstevel@tonic-gate if ( ber_scanf( &tmp, "{a", &dn ) == LBER_ERROR ) {
65*0Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
66*0Sstevel@tonic-gate return( NULL );
67*0Sstevel@tonic-gate }
68*0Sstevel@tonic-gate
69*0Sstevel@tonic-gate return( dn );
70*0Sstevel@tonic-gate }
71*0Sstevel@tonic-gate
72*0Sstevel@tonic-gate char *
73*0Sstevel@tonic-gate LDAP_CALL
ldap_dn2ufn(const char * dn)74*0Sstevel@tonic-gate ldap_dn2ufn( const char *dn )
75*0Sstevel@tonic-gate {
76*0Sstevel@tonic-gate char *p, *ufn, *r;
77*0Sstevel@tonic-gate size_t plen;
78*0Sstevel@tonic-gate int state;
79*0Sstevel@tonic-gate
80*0Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gate if ( dn == NULL ) {
83*0Sstevel@tonic-gate dn = "";
84*0Sstevel@tonic-gate }
85*0Sstevel@tonic-gate
86*0Sstevel@tonic-gate if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL )
87*0Sstevel@tonic-gate return( nsldapi_strdup( (char *)dn ));
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate ufn = nsldapi_strdup( ++p );
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate #define INQUOTE 1
92*0Sstevel@tonic-gate #define OUTQUOTE 2
93*0Sstevel@tonic-gate state = OUTQUOTE;
94*0Sstevel@tonic-gate for ( p = ufn, r = ufn; *p; p += plen ) {
95*0Sstevel@tonic-gate plen = 1;
96*0Sstevel@tonic-gate switch ( *p ) {
97*0Sstevel@tonic-gate case '\\':
98*0Sstevel@tonic-gate if ( *++p == '\0' )
99*0Sstevel@tonic-gate plen=0;
100*0Sstevel@tonic-gate else {
101*0Sstevel@tonic-gate *r++ = '\\';
102*0Sstevel@tonic-gate r += (plen = LDAP_UTF8COPY(r,p));
103*0Sstevel@tonic-gate }
104*0Sstevel@tonic-gate break;
105*0Sstevel@tonic-gate case '"':
106*0Sstevel@tonic-gate if ( state == INQUOTE )
107*0Sstevel@tonic-gate state = OUTQUOTE;
108*0Sstevel@tonic-gate else
109*0Sstevel@tonic-gate state = INQUOTE;
110*0Sstevel@tonic-gate *r++ = *p;
111*0Sstevel@tonic-gate break;
112*0Sstevel@tonic-gate case ';':
113*0Sstevel@tonic-gate case ',':
114*0Sstevel@tonic-gate if ( state == OUTQUOTE )
115*0Sstevel@tonic-gate *r++ = ',';
116*0Sstevel@tonic-gate else
117*0Sstevel@tonic-gate *r++ = *p;
118*0Sstevel@tonic-gate break;
119*0Sstevel@tonic-gate case '=':
120*0Sstevel@tonic-gate if ( state == INQUOTE )
121*0Sstevel@tonic-gate *r++ = *p;
122*0Sstevel@tonic-gate else {
123*0Sstevel@tonic-gate char *rsave = r;
124*0Sstevel@tonic-gate LDAP_UTF8DEC(r);
125*0Sstevel@tonic-gate *rsave = '\0';
126*0Sstevel@tonic-gate while ( !ldap_utf8isspace( r ) && *r != ';'
127*0Sstevel@tonic-gate && *r != ',' && r > ufn )
128*0Sstevel@tonic-gate LDAP_UTF8DEC(r);
129*0Sstevel@tonic-gate LDAP_UTF8INC(r);
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate if ( strcasecmp( r, "c" )
132*0Sstevel@tonic-gate && strcasecmp( r, "o" )
133*0Sstevel@tonic-gate && strcasecmp( r, "ou" )
134*0Sstevel@tonic-gate && strcasecmp( r, "st" )
135*0Sstevel@tonic-gate && strcasecmp( r, "l" )
136*0Sstevel@tonic-gate && strcasecmp( r, "dc" )
137*0Sstevel@tonic-gate && strcasecmp( r, "uid" )
138*0Sstevel@tonic-gate && strcasecmp( r, "cn" ) ) {
139*0Sstevel@tonic-gate r = rsave;
140*0Sstevel@tonic-gate *r++ = '=';
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate }
143*0Sstevel@tonic-gate break;
144*0Sstevel@tonic-gate default:
145*0Sstevel@tonic-gate r += (plen = LDAP_UTF8COPY(r,p));
146*0Sstevel@tonic-gate break;
147*0Sstevel@tonic-gate }
148*0Sstevel@tonic-gate }
149*0Sstevel@tonic-gate *r = '\0';
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate return( ufn );
152*0Sstevel@tonic-gate }
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate char **
155*0Sstevel@tonic-gate LDAP_CALL
ldap_explode_dns(const char * dn)156*0Sstevel@tonic-gate ldap_explode_dns( const char *dn )
157*0Sstevel@tonic-gate {
158*0Sstevel@tonic-gate int ncomps, maxcomps;
159*0Sstevel@tonic-gate char *s, *cpydn;
160*0Sstevel@tonic-gate char **rdns;
161*0Sstevel@tonic-gate #ifdef HAVE_STRTOK_R /* defined in portable.h */
162*0Sstevel@tonic-gate char *lasts;
163*0Sstevel@tonic-gate #endif
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate if ( dn == NULL ) {
166*0Sstevel@tonic-gate dn = "";
167*0Sstevel@tonic-gate }
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gate if ( (rdns = (char **)NSLDAPI_MALLOC( 8 * sizeof(char *) )) == NULL ) {
170*0Sstevel@tonic-gate return( NULL );
171*0Sstevel@tonic-gate }
172*0Sstevel@tonic-gate
173*0Sstevel@tonic-gate maxcomps = 8;
174*0Sstevel@tonic-gate ncomps = 0;
175*0Sstevel@tonic-gate cpydn = nsldapi_strdup( (char *)dn );
176*0Sstevel@tonic-gate for ( s = STRTOK( cpydn, "@.", &lasts ); s != NULL;
177*0Sstevel@tonic-gate s = STRTOK( NULL, "@.", &lasts ) ) {
178*0Sstevel@tonic-gate if ( ncomps == maxcomps ) {
179*0Sstevel@tonic-gate maxcomps *= 2;
180*0Sstevel@tonic-gate if ( (rdns = (char **)NSLDAPI_REALLOC( rdns, maxcomps *
181*0Sstevel@tonic-gate sizeof(char *) )) == NULL ) {
182*0Sstevel@tonic-gate NSLDAPI_FREE( cpydn );
183*0Sstevel@tonic-gate return( NULL );
184*0Sstevel@tonic-gate }
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate rdns[ncomps++] = nsldapi_strdup( s );
187*0Sstevel@tonic-gate }
188*0Sstevel@tonic-gate rdns[ncomps] = NULL;
189*0Sstevel@tonic-gate NSLDAPI_FREE( cpydn );
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate return( rdns );
192*0Sstevel@tonic-gate }
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate #define LDAP_DN 1
195*0Sstevel@tonic-gate #define LDAP_RDN 2
196*0Sstevel@tonic-gate
197*0Sstevel@tonic-gate static char **
ldap_explode(const char * dn,const int notypes,const int nametype)198*0Sstevel@tonic-gate ldap_explode( const char *dn, const int notypes, const int nametype )
199*0Sstevel@tonic-gate {
200*0Sstevel@tonic-gate char *p, *q, *rdnstart, **rdns = NULL;
201*0Sstevel@tonic-gate size_t plen = 0;
202*0Sstevel@tonic-gate int state, count = 0, endquote, len, goteq;
203*0Sstevel@tonic-gate
204*0Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_explode\n", 0, 0, 0 );
205*0Sstevel@tonic-gate
206*0Sstevel@tonic-gate if ( dn == NULL ) {
207*0Sstevel@tonic-gate dn = "";
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate
210*0Sstevel@tonic-gate #if 0
211*0Sstevel@tonic-gate if ( ldap_is_dns_dn( dn ) ) {
212*0Sstevel@tonic-gate return( ldap_explode_dns( dn ) );
213*0Sstevel@tonic-gate }
214*0Sstevel@tonic-gate #endif
215*0Sstevel@tonic-gate
216*0Sstevel@tonic-gate while ( ldap_utf8isspace( (char *)dn )) { /* ignore leading spaces */
217*0Sstevel@tonic-gate ++dn;
218*0Sstevel@tonic-gate }
219*0Sstevel@tonic-gate
220*0Sstevel@tonic-gate p = rdnstart = (char *) dn;
221*0Sstevel@tonic-gate state = OUTQUOTE;
222*0Sstevel@tonic-gate goteq = 0;
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate do {
225*0Sstevel@tonic-gate p += plen;
226*0Sstevel@tonic-gate plen = 1;
227*0Sstevel@tonic-gate switch ( *p ) {
228*0Sstevel@tonic-gate case '\\':
229*0Sstevel@tonic-gate if ( *++p == '\0' )
230*0Sstevel@tonic-gate p--;
231*0Sstevel@tonic-gate else
232*0Sstevel@tonic-gate plen = LDAP_UTF8LEN(p);
233*0Sstevel@tonic-gate break;
234*0Sstevel@tonic-gate case '"':
235*0Sstevel@tonic-gate if ( state == INQUOTE )
236*0Sstevel@tonic-gate state = OUTQUOTE;
237*0Sstevel@tonic-gate else
238*0Sstevel@tonic-gate state = INQUOTE;
239*0Sstevel@tonic-gate break;
240*0Sstevel@tonic-gate case '+': if ( nametype != LDAP_RDN ) break;
241*0Sstevel@tonic-gate case ';':
242*0Sstevel@tonic-gate case ',':
243*0Sstevel@tonic-gate case '\0':
244*0Sstevel@tonic-gate if ( state == OUTQUOTE ) {
245*0Sstevel@tonic-gate /*
246*0Sstevel@tonic-gate * semicolon and comma are not valid RDN
247*0Sstevel@tonic-gate * separators.
248*0Sstevel@tonic-gate */
249*0Sstevel@tonic-gate if ( nametype == LDAP_RDN &&
250*0Sstevel@tonic-gate ( *p == ';' || *p == ',' || !goteq)) {
251*0Sstevel@tonic-gate ldap_charray_free( rdns );
252*0Sstevel@tonic-gate return NULL;
253*0Sstevel@tonic-gate }
254*0Sstevel@tonic-gate if ( (*p == ',' || *p == ';') && !goteq ) {
255*0Sstevel@tonic-gate /* If we get here, we have a case similar
256*0Sstevel@tonic-gate * to <attr>=<value>,<string>,<attr>=<value>
257*0Sstevel@tonic-gate * This is not a valid dn */
258*0Sstevel@tonic-gate ldap_charray_free( rdns );
259*0Sstevel@tonic-gate return NULL;
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate goteq = 0;
262*0Sstevel@tonic-gate ++count;
263*0Sstevel@tonic-gate if ( rdns == NULL ) {
264*0Sstevel@tonic-gate if (( rdns = (char **)NSLDAPI_MALLOC( 8
265*0Sstevel@tonic-gate * sizeof( char *))) == NULL )
266*0Sstevel@tonic-gate return( NULL );
267*0Sstevel@tonic-gate } else if ( count >= 8 ) {
268*0Sstevel@tonic-gate if (( rdns = (char **)NSLDAPI_REALLOC(
269*0Sstevel@tonic-gate rdns, (count+1) *
270*0Sstevel@tonic-gate sizeof( char *))) == NULL )
271*0Sstevel@tonic-gate return( NULL );
272*0Sstevel@tonic-gate }
273*0Sstevel@tonic-gate rdns[ count ] = NULL;
274*0Sstevel@tonic-gate endquote = 0;
275*0Sstevel@tonic-gate if ( notypes ) {
276*0Sstevel@tonic-gate for ( q = rdnstart;
277*0Sstevel@tonic-gate q < p && *q != '='; ++q ) {
278*0Sstevel@tonic-gate ;
279*0Sstevel@tonic-gate }
280*0Sstevel@tonic-gate if ( q < p ) { /* *q == '=' */
281*0Sstevel@tonic-gate rdnstart = ++q;
282*0Sstevel@tonic-gate }
283*0Sstevel@tonic-gate if ( *rdnstart == '"' ) {
284*0Sstevel@tonic-gate ++rdnstart;
285*0Sstevel@tonic-gate }
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gate if ( *(p-1) == '"' ) {
288*0Sstevel@tonic-gate endquote = 1;
289*0Sstevel@tonic-gate --p;
290*0Sstevel@tonic-gate }
291*0Sstevel@tonic-gate }
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gate len = p - rdnstart;
294*0Sstevel@tonic-gate if (( rdns[ count-1 ] = (char *)NSLDAPI_CALLOC(
295*0Sstevel@tonic-gate 1, len + 1 )) != NULL ) {
296*0Sstevel@tonic-gate SAFEMEMCPY( rdns[ count-1 ], rdnstart,
297*0Sstevel@tonic-gate len );
298*0Sstevel@tonic-gate if ( !endquote ) {
299*0Sstevel@tonic-gate /* trim trailing spaces */
300*0Sstevel@tonic-gate while ( len > 0 &&
301*0Sstevel@tonic-gate ldap_utf8isspace(
302*0Sstevel@tonic-gate &rdns[count-1][len-1] )) {
303*0Sstevel@tonic-gate --len;
304*0Sstevel@tonic-gate }
305*0Sstevel@tonic-gate }
306*0Sstevel@tonic-gate rdns[ count-1 ][ len ] = '\0';
307*0Sstevel@tonic-gate }
308*0Sstevel@tonic-gate
309*0Sstevel@tonic-gate /*
310*0Sstevel@tonic-gate * Don't forget to increment 'p' back to where
311*0Sstevel@tonic-gate * it should be. If we don't, then we will
312*0Sstevel@tonic-gate * never get past an "end quote."
313*0Sstevel@tonic-gate */
314*0Sstevel@tonic-gate if ( endquote == 1 )
315*0Sstevel@tonic-gate p++;
316*0Sstevel@tonic-gate
317*0Sstevel@tonic-gate rdnstart = *p ? p + 1 : p;
318*0Sstevel@tonic-gate while ( ldap_utf8isspace( rdnstart ))
319*0Sstevel@tonic-gate ++rdnstart;
320*0Sstevel@tonic-gate }
321*0Sstevel@tonic-gate break;
322*0Sstevel@tonic-gate case '=':
323*0Sstevel@tonic-gate if ( state == OUTQUOTE ) {
324*0Sstevel@tonic-gate goteq = 1;
325*0Sstevel@tonic-gate }
326*0Sstevel@tonic-gate /* FALL */
327*0Sstevel@tonic-gate default:
328*0Sstevel@tonic-gate plen = LDAP_UTF8LEN(p);
329*0Sstevel@tonic-gate break;
330*0Sstevel@tonic-gate }
331*0Sstevel@tonic-gate } while ( *p );
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gate return( rdns );
334*0Sstevel@tonic-gate }
335*0Sstevel@tonic-gate
336*0Sstevel@tonic-gate char **
337*0Sstevel@tonic-gate LDAP_CALL
ldap_explode_dn(const char * dn,const int notypes)338*0Sstevel@tonic-gate ldap_explode_dn( const char *dn, const int notypes )
339*0Sstevel@tonic-gate {
340*0Sstevel@tonic-gate return( ldap_explode( dn, notypes, LDAP_DN ) );
341*0Sstevel@tonic-gate }
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate char **
344*0Sstevel@tonic-gate LDAP_CALL
ldap_explode_rdn(const char * rdn,const int notypes)345*0Sstevel@tonic-gate ldap_explode_rdn( const char *rdn, const int notypes )
346*0Sstevel@tonic-gate {
347*0Sstevel@tonic-gate return( ldap_explode( rdn, notypes, LDAP_RDN ) );
348*0Sstevel@tonic-gate }
349*0Sstevel@tonic-gate
350*0Sstevel@tonic-gate int
351*0Sstevel@tonic-gate LDAP_CALL
ldap_is_dns_dn(const char * dn)352*0Sstevel@tonic-gate ldap_is_dns_dn( const char *dn )
353*0Sstevel@tonic-gate {
354*0Sstevel@tonic-gate return( dn != NULL && dn[ 0 ] != '\0' && strchr( dn, '=' ) == NULL &&
355*0Sstevel@tonic-gate strchr( dn, ',' ) == NULL );
356*0Sstevel@tonic-gate }
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
359*0Sstevel@tonic-gate
360*0Sstevel@tonic-gate /*
361*0Sstevel@tonic-gate * Convert a DNS domain name into an X.500 distinguished name.
362*0Sstevel@tonic-gate * For example, "sales.wiz.com" -> "dc=sales,dc=wiz,dc=com"
363*0Sstevel@tonic-gate *
364*0Sstevel@tonic-gate * If an error is encountered zero is returned, otherwise a string
365*0Sstevel@tonic-gate * distinguished name and the number of nameparts is returned.
366*0Sstevel@tonic-gate * The caller should free the returned string if it is non-zero.
367*0Sstevel@tonic-gate */
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gate char *
ldap_dns_to_dn(char * dns_name,int * nameparts)370*0Sstevel@tonic-gate ldap_dns_to_dn(
371*0Sstevel@tonic-gate char *dns_name,
372*0Sstevel@tonic-gate int *nameparts
373*0Sstevel@tonic-gate )
374*0Sstevel@tonic-gate {
375*0Sstevel@tonic-gate size_t dns_len;
376*0Sstevel@tonic-gate char *dn = 0;
377*0Sstevel@tonic-gate char *cp;
378*0Sstevel@tonic-gate
379*0Sstevel@tonic-gate /* check for NULL string, empty name and name ending in '.' */
380*0Sstevel@tonic-gate if (dns_name && (dns_len = strlen(dns_name)) &&
381*0Sstevel@tonic-gate (dns_name[dns_len - 1] != '.')) {
382*0Sstevel@tonic-gate if (dn = (char *)malloc(dns_len * 3 + 1)) {
383*0Sstevel@tonic-gate *nameparts = 0;
384*0Sstevel@tonic-gate cp = dn;
385*0Sstevel@tonic-gate while (*dns_name) {
386*0Sstevel@tonic-gate *cp++ = 'd';
387*0Sstevel@tonic-gate *cp++ = 'c';
388*0Sstevel@tonic-gate *cp++ = '=';
389*0Sstevel@tonic-gate
390*0Sstevel@tonic-gate while (*dns_name && (*dns_name != '.')) {
391*0Sstevel@tonic-gate *cp++ = *dns_name++;
392*0Sstevel@tonic-gate }
393*0Sstevel@tonic-gate if (*dns_name == '.') {
394*0Sstevel@tonic-gate dns_name++;
395*0Sstevel@tonic-gate *cp++ = ',';
396*0Sstevel@tonic-gate }
397*0Sstevel@tonic-gate (*nameparts)++;
398*0Sstevel@tonic-gate }
399*0Sstevel@tonic-gate *cp = '\0';
400*0Sstevel@tonic-gate }
401*0Sstevel@tonic-gate }
402*0Sstevel@tonic-gate return (dn);
403*0Sstevel@tonic-gate }
404*0Sstevel@tonic-gate
405*0Sstevel@tonic-gate #endif
406*0Sstevel@tonic-gate
407