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
51914Scasper * Common Development and Distribution License (the "License").
61914Scasper * 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 */
210Sstevel@tonic-gate /*
228821SMichen.Chang@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /* libsldap - cachemgr side configuration components */
270Sstevel@tonic-gate
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <libintl.h>
320Sstevel@tonic-gate #include <string.h>
330Sstevel@tonic-gate #include <ctype.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate #include <sys/stat.h>
360Sstevel@tonic-gate #include <fcntl.h>
370Sstevel@tonic-gate #include <unistd.h>
380Sstevel@tonic-gate #include <syslog.h>
390Sstevel@tonic-gate #include <locale.h>
400Sstevel@tonic-gate #include <errno.h>
410Sstevel@tonic-gate #include <sys/time.h>
420Sstevel@tonic-gate
430Sstevel@tonic-gate #include "ns_sldap.h"
440Sstevel@tonic-gate #include "ns_internal.h"
450Sstevel@tonic-gate #include "ns_cache_door.h"
460Sstevel@tonic-gate
470Sstevel@tonic-gate #define ALWAYS 1
480Sstevel@tonic-gate
490Sstevel@tonic-gate
500Sstevel@tonic-gate /*
510Sstevel@tonic-gate * **************************************************************
520Sstevel@tonic-gate * Configuration File Routines
530Sstevel@tonic-gate * **************************************************************
540Sstevel@tonic-gate */
550Sstevel@tonic-gate
560Sstevel@tonic-gate
570Sstevel@tonic-gate /* Size of the errstr buffer needs to be MAXERROR */
580Sstevel@tonic-gate static int
read_line(FILE * fp,char * buffer,int buflen,char * errstr)590Sstevel@tonic-gate read_line(FILE *fp, char *buffer, int buflen, char *errstr)
600Sstevel@tonic-gate {
610Sstevel@tonic-gate int linelen;
620Sstevel@tonic-gate char c;
630Sstevel@tonic-gate
640Sstevel@tonic-gate *errstr = '\0';
650Sstevel@tonic-gate
660Sstevel@tonic-gate for (linelen = 0; linelen < buflen; ) {
670Sstevel@tonic-gate c = getc(fp);
680Sstevel@tonic-gate if (c == EOF)
690Sstevel@tonic-gate break;
700Sstevel@tonic-gate switch (c) {
710Sstevel@tonic-gate case '\n':
726063Smj162486 if (linelen > 0 && buffer[linelen - 1] == '\\') {
736063Smj162486 /* Continuation line found */
746063Smj162486 --linelen;
756063Smj162486 } else {
766063Smj162486 /* end of line found */
776063Smj162486 buffer[linelen] = '\0';
786063Smj162486 return (linelen);
796063Smj162486 }
806063Smj162486 break;
810Sstevel@tonic-gate default:
826063Smj162486 buffer[linelen++] = c;
830Sstevel@tonic-gate }
840Sstevel@tonic-gate }
850Sstevel@tonic-gate
860Sstevel@tonic-gate if (linelen >= buflen) {
870Sstevel@tonic-gate (void) snprintf(errstr, MAXERROR,
886063Smj162486 gettext("Buffer overflow, line too long."));
890Sstevel@tonic-gate return (-2);
900Sstevel@tonic-gate } else if (linelen > 0 && buffer[linelen - 1] == '\\') {
910Sstevel@tonic-gate (void) snprintf(errstr, MAXERROR,
926063Smj162486 gettext("Unterminated continuation line."));
930Sstevel@tonic-gate return (-2);
940Sstevel@tonic-gate } else {
950Sstevel@tonic-gate /* end of file */
960Sstevel@tonic-gate buffer[linelen] = '\0';
970Sstevel@tonic-gate }
980Sstevel@tonic-gate return (linelen > 0 ? linelen : -1);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate static ns_parse_status
read_file(ns_config_t * ptr,int cred_file,ns_ldap_error_t ** error)1030Sstevel@tonic-gate read_file(ns_config_t *ptr, int cred_file, ns_ldap_error_t **error)
1040Sstevel@tonic-gate {
1050Sstevel@tonic-gate ParamIndexType i = 0;
1060Sstevel@tonic-gate char errstr[MAXERROR];
1070Sstevel@tonic-gate char buffer[BUFSIZE], *name, *value;
1080Sstevel@tonic-gate int emptyfile, lineno;
1090Sstevel@tonic-gate FILE *fp;
1100Sstevel@tonic-gate int ret;
1110Sstevel@tonic-gate int linelen;
1120Sstevel@tonic-gate char *file;
1130Sstevel@tonic-gate int first = 1;
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate if (cred_file) {
1170Sstevel@tonic-gate file = NSCREDFILE;
1180Sstevel@tonic-gate } else {
1190Sstevel@tonic-gate file = NSCONFIGFILE;
1200Sstevel@tonic-gate }
1211914Scasper fp = fopen(file, "rF");
1220Sstevel@tonic-gate if (fp == NULL) {
1230Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
1246063Smj162486 gettext("Unable to open filename '%s' "
1256063Smj162486 "for reading (errno=%d)."), file, errno);
1260Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_FILE, strdup(errstr), NULL);
1270Sstevel@tonic-gate return (NS_NOTFOUND);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate emptyfile = 1;
1310Sstevel@tonic-gate lineno = 0;
1320Sstevel@tonic-gate for (; ; ) {
1330Sstevel@tonic-gate if ((linelen = read_line(fp, buffer, sizeof (buffer),
1346063Smj162486 errstr)) < 0)
1350Sstevel@tonic-gate /* End of file */
1360Sstevel@tonic-gate break;
1370Sstevel@tonic-gate lineno++;
1380Sstevel@tonic-gate if (linelen == 0)
1390Sstevel@tonic-gate continue;
1400Sstevel@tonic-gate /* get rid of comment lines */
1410Sstevel@tonic-gate if (buffer[0] == '#')
1420Sstevel@tonic-gate continue;
1430Sstevel@tonic-gate emptyfile = 0;
1440Sstevel@tonic-gate name = NULL;
1450Sstevel@tonic-gate value = NULL;
1460Sstevel@tonic-gate __s_api_split_key_value(buffer, &name, &value);
1470Sstevel@tonic-gate if (name == NULL || value == NULL) {
1480Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
1490Sstevel@tonic-gate gettext("Missing Name or Value on line %d."),
1506063Smj162486 lineno);
1510Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1526063Smj162486 strdup(errstr), NULL);
1530Sstevel@tonic-gate (void) fclose(fp);
1540Sstevel@tonic-gate return (NS_PARSE_ERR);
1550Sstevel@tonic-gate }
1560Sstevel@tonic-gate if (__s_api_get_versiontype(ptr, name, &i) != 0) {
1570Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
1580Sstevel@tonic-gate gettext("Illegal profile type on line %d."),
1596063Smj162486 lineno);
1600Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1616063Smj162486 strdup(errstr), NULL);
1620Sstevel@tonic-gate (void) fclose(fp);
1630Sstevel@tonic-gate return (NS_PARSE_ERR);
1640Sstevel@tonic-gate }
1650Sstevel@tonic-gate if (!first && i == NS_LDAP_FILE_VERSION_P) {
1660Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
1676063Smj162486 gettext("Illegal NS_LDAP_FILE_VERSION "
1686063Smj162486 "on line %d."), lineno);
1690Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1706063Smj162486 strdup(errstr), NULL);
1710Sstevel@tonic-gate (void) fclose(fp);
1720Sstevel@tonic-gate return (NS_PARSE_ERR);
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate first = 0;
1750Sstevel@tonic-gate switch (__s_api_get_configtype(i)) {
1760Sstevel@tonic-gate case SERVERCONFIG:
1770Sstevel@tonic-gate case CLIENTCONFIG:
1780Sstevel@tonic-gate if (cred_file == 0) {
1790Sstevel@tonic-gate ret = __ns_ldap_setParamValue(ptr, i, value,
1806063Smj162486 error);
1810Sstevel@tonic-gate if (ret != NS_SUCCESS) {
1820Sstevel@tonic-gate (void) fclose(fp);
1830Sstevel@tonic-gate return (ret);
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate } else if (i != NS_LDAP_FILE_VERSION_P) {
1860Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
1876063Smj162486 gettext("Illegal entry in '%s' on "
1886063Smj162486 "line %d"), file, lineno);
1890Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1906063Smj162486 strdup(errstr), NULL);
1910Sstevel@tonic-gate (void) fclose(fp);
1920Sstevel@tonic-gate return (NS_PARSE_ERR);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate break;
1950Sstevel@tonic-gate case CREDCONFIG:
1960Sstevel@tonic-gate if (i == NS_LDAP_FILE_VERSION_P)
1970Sstevel@tonic-gate break;
1980Sstevel@tonic-gate if (cred_file) {
1990Sstevel@tonic-gate ret = __ns_ldap_setParamValue(ptr, i, value,
2006063Smj162486 error);
2010Sstevel@tonic-gate if (ret != NS_SUCCESS) {
2020Sstevel@tonic-gate (void) fclose(fp);
2030Sstevel@tonic-gate return (ret);
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate } else {
2060Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
2076063Smj162486 gettext("Illegal entry in '%s' on "
2086063Smj162486 "line %d"), file, lineno);
2090Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2106063Smj162486 strdup(errstr), NULL);
2110Sstevel@tonic-gate (void) fclose(fp);
2120Sstevel@tonic-gate return (NS_PARSE_ERR);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate (void) fclose(fp);
2170Sstevel@tonic-gate if (!cred_file && emptyfile) {
2180Sstevel@tonic-gate /* Error in read_line */
2190Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
2206063Smj162486 gettext("Empty config file: '%s'"), file);
2210Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
2226063Smj162486 NULL);
2230Sstevel@tonic-gate return (NS_PARSE_ERR);
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate if (linelen == -2) {
2260Sstevel@tonic-gate /* Error in read_line */
2270Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
2286063Smj162486 gettext("Line too long in '%s'"), file);
2290Sstevel@tonic-gate MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
2306063Smj162486 NULL);
2310Sstevel@tonic-gate return (NS_PARSE_ERR);
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate return (NS_SUCCESS);
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate
2376842Sth160488 static
2386842Sth160488 ns_ldap_return_code
set_attr(ns_config_t * config_struct,char * attr_name,char * attr_val,ns_ldap_error_t ** errorp)2396842Sth160488 set_attr(ns_config_t *config_struct,
2406842Sth160488 char *attr_name,
2416842Sth160488 char *attr_val,
2426842Sth160488 ns_ldap_error_t **errorp)
2436842Sth160488 {
2446842Sth160488 ParamIndexType idx;
2456842Sth160488 char errmsg[MAXERROR];
2466842Sth160488
2476842Sth160488 if (errorp == NULL) {
2486842Sth160488 return (NS_LDAP_INVALID_PARAM);
2496842Sth160488 }
2506842Sth160488
2516842Sth160488 *errorp = NULL;
2526842Sth160488
2536842Sth160488 /*
2546842Sth160488 * This double call is made due to the presence of
2556842Sth160488 * two sets of LDAP config. attribute names.
2566842Sth160488 * An LDAP configuration can be obtained either from a server
2576842Sth160488 * or from SMF. The former sends a DUA with attributes' names
2586842Sth160488 * styled like "preferredServerList". But local configurations
2596842Sth160488 * will have names inherited from the /var/ldap/ldap* files such as
2606842Sth160488 * "NS_LDAP_SERVER_PREF".
2616842Sth160488 * So, the standalone bits are able to process both sets of
2626842Sth160488 * attributes' names.
2636842Sth160488 */
2646842Sth160488 if (__s_api_get_profiletype(attr_name, &idx) < 0 &&
2656842Sth160488 __s_api_get_versiontype(config_struct, attr_name, &idx) < 0) {
2666842Sth160488 (void) snprintf(errmsg, sizeof (errmsg),
2676842Sth160488 gettext("Illegal DUAProfile property: <%s>."), attr_name);
2686842Sth160488 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
2696842Sth160488 return (NS_LDAP_CONFIG);
2706842Sth160488 }
2716842Sth160488
2726842Sth160488 return (__ns_ldap_setParamValue(config_struct, idx, attr_val, errorp));
2736842Sth160488 }
2746842Sth160488
2756842Sth160488
2766842Sth160488 /*
2776842Sth160488 * This function creates a configuration which will be used
2786842Sth160488 * for all LDAP requests in the Standalone mode.
2796842Sth160488 *
2806842Sth160488 * INPUT:
2816842Sth160488 * config - a buffer returned by __ns_ldap_getConnectionInfo()'s
2826842Sth160488 * dua_profile parameter.
2836842Sth160488 *
2846842Sth160488 */
2856842Sth160488 ns_config_t *
__s_api_create_config_door_str(char * config,ns_ldap_error_t ** errorp)2866842Sth160488 __s_api_create_config_door_str(char *config, ns_ldap_error_t **errorp)
2876842Sth160488 {
2886842Sth160488 char *attr, *attrName, *attrVal, *rest;
2896842Sth160488 ns_config_t *configStruct = NULL;
2906842Sth160488 char errmsg[MAXERROR];
2916842Sth160488
2926842Sth160488 if (config == NULL || errorp == NULL)
2936842Sth160488 return (NULL);
2946842Sth160488
2956842Sth160488 if ((configStruct = __s_api_create_config()) == NULL) {
2966842Sth160488 return (NULL);
2976842Sth160488 }
2986842Sth160488
2996842Sth160488 *errorp = NULL;
3006842Sth160488
3016842Sth160488 attr = strtok_r(config, DOORLINESEP, &rest);
3026842Sth160488 if (!attr) {
3036842Sth160488 __s_api_destroy_config(configStruct);
3046842Sth160488 (void) snprintf(errmsg, sizeof (errmsg),
3056842Sth160488 gettext("DUAProfile received from the server"
3066842Sth160488 " has bad format"));
3076842Sth160488 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
3086842Sth160488 return (NULL);
3096842Sth160488 }
3106842Sth160488
3116842Sth160488 do {
3126842Sth160488 __s_api_split_key_value(attr, &attrName, &attrVal);
3136842Sth160488
3146842Sth160488 if (attrName == NULL || attrVal == NULL) {
3156842Sth160488 __s_api_destroy_config(configStruct);
3166842Sth160488 (void) snprintf(errmsg, sizeof (errmsg),
3176842Sth160488 gettext("Attribute %s is not valid"), attr);
3186842Sth160488 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG,
3196842Sth160488 strdup(errmsg), NULL);
3206842Sth160488 return (NULL);
3216842Sth160488 }
3226842Sth160488
3236842Sth160488 /* Get the version of the profile. */
3246842Sth160488 if (strcasecmp(attrName, "objectclass") == 0) {
3256842Sth160488 if (strcasecmp(attrVal, _PROFILE2_OBJECTCLASS) == 0) {
3266842Sth160488 if (__ns_ldap_setParamValue(configStruct,
3276842Sth160488 NS_LDAP_FILE_VERSION_P,
3286842Sth160488 NS_LDAP_VERSION_2,
3296842Sth160488 errorp) != NS_LDAP_SUCCESS) {
3306842Sth160488 __s_api_destroy_config(configStruct);
3316842Sth160488 return (NULL);
3326842Sth160488 }
3338821SMichen.Chang@Sun.COM } else if (strcasecmp(attrVal,
3348821SMichen.Chang@Sun.COM _PROFILE1_OBJECTCLASS) == 0) {
3358821SMichen.Chang@Sun.COM if (__ns_ldap_setParamValue(configStruct,
3368821SMichen.Chang@Sun.COM NS_LDAP_FILE_VERSION_P,
3378821SMichen.Chang@Sun.COM NS_LDAP_VERSION_1,
3388821SMichen.Chang@Sun.COM errorp) != NS_LDAP_SUCCESS) {
3398821SMichen.Chang@Sun.COM __s_api_destroy_config(configStruct);
3408821SMichen.Chang@Sun.COM return (NULL);
3418821SMichen.Chang@Sun.COM }
3426842Sth160488 }
3436842Sth160488 continue;
3446842Sth160488 }
3456842Sth160488
3466842Sth160488 if (set_attr(configStruct, attrName, attrVal, errorp) !=
3476842Sth160488 NS_LDAP_SUCCESS) {
3486842Sth160488 __s_api_destroy_config(configStruct);
3496842Sth160488 return (NULL);
3506842Sth160488 }
3516842Sth160488 } while (attr = strtok_r(NULL, DOORLINESEP, &rest));
3526842Sth160488
3536842Sth160488 if (__s_api_crosscheck(configStruct, errmsg, B_FALSE) != NS_SUCCESS) {
3546842Sth160488 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
3556842Sth160488 __s_api_destroy_config(configStruct);
3566842Sth160488 return (NULL);
3576842Sth160488 }
3586842Sth160488
3596842Sth160488 return (configStruct);
3606842Sth160488 }
3616842Sth160488
3626842Sth160488
3630Sstevel@tonic-gate /*
3640Sstevel@tonic-gate * Cache Manager side of configuration file loading
3650Sstevel@tonic-gate */
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_LoadConfiguration()3680Sstevel@tonic-gate __ns_ldap_LoadConfiguration()
3690Sstevel@tonic-gate {
3700Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
3710Sstevel@tonic-gate ns_config_t *ptr = NULL;
3720Sstevel@tonic-gate char errstr[MAXERROR];
3730Sstevel@tonic-gate ns_parse_status ret;
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate ptr = __s_api_create_config();
3770Sstevel@tonic-gate if (ptr == NULL) {
3780Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
3796063Smj162486 gettext("__ns_ldap_LoadConfiguration: Out of memory."));
3800Sstevel@tonic-gate MKERROR(LOG_ERR, error, NS_CONFIG_NOTLOADED,
3816063Smj162486 strdup(errstr), NULL);
3820Sstevel@tonic-gate return (error);
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate /* Load in Configuration file */
3860Sstevel@tonic-gate ret = read_file(ptr, 0, &error);
3870Sstevel@tonic-gate if (ret != NS_SUCCESS) {
3880Sstevel@tonic-gate __s_api_destroy_config(ptr);
3890Sstevel@tonic-gate return (error);
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate /* Load in Credential file */
3930Sstevel@tonic-gate ret = read_file(ptr, 1, &error);
3940Sstevel@tonic-gate if (ret != NS_SUCCESS) {
3950Sstevel@tonic-gate __s_api_destroy_config(ptr);
3960Sstevel@tonic-gate return (error);
3970Sstevel@tonic-gate }
3980Sstevel@tonic-gate
3990Sstevel@tonic-gate if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
4000Sstevel@tonic-gate __s_api_destroy_config(ptr);
4010Sstevel@tonic-gate MKERROR(LOG_ERR, error, NS_CONFIG_SYNTAX, strdup(errstr), NULL);
4020Sstevel@tonic-gate return (error);
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate __s_api_init_config(ptr);
4060Sstevel@tonic-gate return (NULL);
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate
410*10132SMilan.Jurik@Sun.COM int
__print2buf(LineBuf * line,const char * toprint,char * sep)411*10132SMilan.Jurik@Sun.COM __print2buf(LineBuf *line, const char *toprint, char *sep)
4120Sstevel@tonic-gate {
4130Sstevel@tonic-gate int newsz = 0;
4140Sstevel@tonic-gate int newmax = 0;
4150Sstevel@tonic-gate char *str;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate if (line == NULL)
4180Sstevel@tonic-gate return (-1);
4190Sstevel@tonic-gate
4200Sstevel@tonic-gate newsz = strlen(toprint) + line->len + 1;
421*10132SMilan.Jurik@Sun.COM if (sep != NULL) {
422*10132SMilan.Jurik@Sun.COM newsz += strlen(sep);
4230Sstevel@tonic-gate }
4240Sstevel@tonic-gate if (line->alloc == 0 || newsz > line->alloc) {
4250Sstevel@tonic-gate /* Round up to next buffer and add 1 */
4260Sstevel@tonic-gate newmax = (((newsz+(BUFSIZ-1))/BUFSIZ)+1) * BUFSIZ;
4270Sstevel@tonic-gate if (line->alloc == 0)
4280Sstevel@tonic-gate line->str = (char *)calloc(newmax, 1);
4290Sstevel@tonic-gate else {
4300Sstevel@tonic-gate /*
4310Sstevel@tonic-gate * if realloc() returns NULL,
4320Sstevel@tonic-gate * the original buffer is untouched.
4330Sstevel@tonic-gate * It needs to be freed.
4340Sstevel@tonic-gate */
4350Sstevel@tonic-gate str = (char *)realloc(line->str, newmax);
4360Sstevel@tonic-gate if (str == NULL) {
4370Sstevel@tonic-gate free(line->str);
4380Sstevel@tonic-gate line->str = NULL;
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate else
4410Sstevel@tonic-gate line->str = str;
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate line->alloc = newmax;
4440Sstevel@tonic-gate if (line->str == NULL) {
4450Sstevel@tonic-gate line->alloc = 0;
4460Sstevel@tonic-gate line->len = 0;
4470Sstevel@tonic-gate return (-1);
4480Sstevel@tonic-gate }
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate /* now add new 'toprint' data to buffer */
4510Sstevel@tonic-gate (void) strlcat(line->str, toprint, line->alloc);
452*10132SMilan.Jurik@Sun.COM if (sep != NULL) {
453*10132SMilan.Jurik@Sun.COM (void) strlcat(line->str, sep, line->alloc);
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate line->len = newsz;
4560Sstevel@tonic-gate return (0);
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate
4600Sstevel@tonic-gate /*
4610Sstevel@tonic-gate * __ns_ldap_LoadDoorInfo is a routine used by the ldapcachemgr
4620Sstevel@tonic-gate * to create a configuration buffer to transmit back to a client
4630Sstevel@tonic-gate * domainname is transmitted to ldapcachemgr and ldapcachemgr uses
4640Sstevel@tonic-gate * it to select a configuration to transmit back. Otherwise it
4650Sstevel@tonic-gate * is essentially unused in sldap.
4669576SJulian.Pullen@Sun.COM * If cred_only is not 0, then only the credentials for shadow
4679576SJulian.Pullen@Sun.COM * update are taken care of.
4680Sstevel@tonic-gate */
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_LoadDoorInfo(LineBuf * configinfo,char * domainname,ns_config_t * new,int cred_only)4719576SJulian.Pullen@Sun.COM __ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname,
4729576SJulian.Pullen@Sun.COM ns_config_t *new, int cred_only)
4730Sstevel@tonic-gate {
4740Sstevel@tonic-gate ns_config_t *ptr;
4750Sstevel@tonic-gate char errstr[MAXERROR];
4760Sstevel@tonic-gate ns_ldap_error_t *errorp;
4770Sstevel@tonic-gate char *str;
4780Sstevel@tonic-gate ParamIndexType i = 0;
4796842Sth160488 int len;
4806842Sth160488 ldap_config_out_t *cout;
4810Sstevel@tonic-gate
4826842Sth160488 /*
4836842Sth160488 * If new is NULL, it outputs the flatten data of current default
4846842Sth160488 * config, if it's non-NULL, it outputs the flatten data of a temporary
4856842Sth160488 * config. It's used to compare the new config data with the current
4866842Sth160488 * default config data.
4876842Sth160488 */
4886842Sth160488 if (new == NULL)
4896842Sth160488 ptr = __s_api_get_default_config();
4906842Sth160488 else
4916842Sth160488 ptr = new;
4920Sstevel@tonic-gate if (ptr == NULL) {
4930Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
4940Sstevel@tonic-gate gettext("No configuration information available for %s."),
4950Sstevel@tonic-gate domainname == NULL ? "<no domain specified>" : domainname);
4960Sstevel@tonic-gate MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
4976063Smj162486 strdup(errstr), NULL);
4980Sstevel@tonic-gate return (errorp);
4990Sstevel@tonic-gate }
5000Sstevel@tonic-gate (void) memset((char *)configinfo, 0, sizeof (LineBuf));
5010Sstevel@tonic-gate for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
5029576SJulian.Pullen@Sun.COM if (cred_only) {
5039576SJulian.Pullen@Sun.COM /* only exposed credential for shadow update */
5049576SJulian.Pullen@Sun.COM if (i != NS_LDAP_ADMIN_BINDDN_P &&
5059576SJulian.Pullen@Sun.COM i != NS_LDAP_ADMIN_BINDPASSWD_P)
5069576SJulian.Pullen@Sun.COM continue;
5079576SJulian.Pullen@Sun.COM } else {
5089576SJulian.Pullen@Sun.COM /* credential for shadow update is not to be exposed */
5099576SJulian.Pullen@Sun.COM if (i == NS_LDAP_ADMIN_BINDDN_P ||
5109576SJulian.Pullen@Sun.COM i == NS_LDAP_ADMIN_BINDPASSWD_P)
5119576SJulian.Pullen@Sun.COM continue;
5129576SJulian.Pullen@Sun.COM }
513*10132SMilan.Jurik@Sun.COM str = __s_api_strValue(ptr, i, NS_DOOR_FMT);
5140Sstevel@tonic-gate if (str == NULL)
5150Sstevel@tonic-gate continue;
516*10132SMilan.Jurik@Sun.COM if (__print2buf(configinfo, str, DOORLINESEP)) {
5170Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
518*10132SMilan.Jurik@Sun.COM gettext("__print2buf: Out of memory."));
5190Sstevel@tonic-gate MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
5206063Smj162486 strdup(errstr), NULL);
5210Sstevel@tonic-gate __s_api_release_config(ptr);
522*10132SMilan.Jurik@Sun.COM free(str);
5230Sstevel@tonic-gate return (errorp);
5240Sstevel@tonic-gate }
525*10132SMilan.Jurik@Sun.COM free(str);
5260Sstevel@tonic-gate }
5276842Sth160488 if (new == NULL)
5286842Sth160488 __s_api_release_config(ptr);
5296842Sth160488
5306842Sth160488 /*
5316842Sth160488 * The new interface of the configuration between ldap_cachemgr
5326842Sth160488 * & libsldap contains a header structure ldap_config_out_t.
5336842Sth160488 * The flatten configuration data configinfo->str is cloned
5346842Sth160488 * to cout->config_str, configinfo->len is saved in
5356842Sth160488 * cout->data_size and cout->cookie is set later after this function
5366842Sth160488 * is returned in ldap_cachemgr.
5376842Sth160488 * configinfo->str & configinfo->len are reused to save info of
5386842Sth160488 * header + data.
5396842Sth160488 * The format:
5406842Sth160488 * [cookie|data_size|config_str .............]
5416842Sth160488 */
5426842Sth160488
5436842Sth160488 if (configinfo->str) {
5446842Sth160488 len = sizeof (ldap_config_out_t) - sizeof (int) +
5456842Sth160488 configinfo->len;
5466842Sth160488 if ((cout = calloc(1, len)) == NULL) {
5476842Sth160488 free(configinfo->str);
5486842Sth160488 configinfo->str = NULL;
5496842Sth160488 configinfo->len = 0;
5506842Sth160488 (void) snprintf(errstr, sizeof (errstr),
5516842Sth160488 gettext("calloc: Out of memory."));
5526842Sth160488 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
5536842Sth160488 strdup(errstr), NULL);
5546842Sth160488 return (errorp);
5556842Sth160488 }
5566842Sth160488 /*
5576842Sth160488 * cout->cookie is set by the caller,
5586842Sth160488 * which is in ldap_cachemgr.
5596842Sth160488 */
5606842Sth160488 cout->data_size = configinfo->len;
5616842Sth160488 (void) memcpy(cout->config_str, configinfo->str,
5626842Sth160488 configinfo->len);
5636842Sth160488 free(configinfo->str);
5646842Sth160488 configinfo->str = (char *)cout;
5656842Sth160488 configinfo->len = len;
5666842Sth160488 }
5670Sstevel@tonic-gate return (NULL);
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_DumpLdif(char * filename)5720Sstevel@tonic-gate __ns_ldap_DumpLdif(char *filename)
5730Sstevel@tonic-gate {
5740Sstevel@tonic-gate ns_config_t *ptr;
5750Sstevel@tonic-gate char errstr[MAXERROR];
5760Sstevel@tonic-gate ns_ldap_error_t *errorp;
5770Sstevel@tonic-gate char *str;
5780Sstevel@tonic-gate FILE *fp;
5790Sstevel@tonic-gate ParamIndexType i = 0;
5800Sstevel@tonic-gate char *profile, *container, *base;
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate ptr = __s_api_get_default_config();
5830Sstevel@tonic-gate if (ptr == NULL) {
5840Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
5850Sstevel@tonic-gate gettext("No configuration information available."));
5860Sstevel@tonic-gate MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
5876063Smj162486 NULL);
5880Sstevel@tonic-gate return (errorp);
5890Sstevel@tonic-gate }
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate if (filename == NULL) {
5920Sstevel@tonic-gate fp = stdout;
5930Sstevel@tonic-gate } else {
5941914Scasper fp = fopen(filename, "wF");
5950Sstevel@tonic-gate if (fp == NULL) {
5960Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
5976063Smj162486 gettext("Unable to open filename %s for ldif "
5986063Smj162486 "dump (errno=%d)."), filename, errno);
5990Sstevel@tonic-gate MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE,
6006063Smj162486 strdup(errstr), NULL);
6010Sstevel@tonic-gate __s_api_release_config(ptr);
6020Sstevel@tonic-gate return (errorp);
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate (void) fchmod(fileno(fp), 0444);
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate
6070Sstevel@tonic-gate if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ptype != CHARPTR ||
6080Sstevel@tonic-gate ptr->paramList[NS_LDAP_PROFILE_P].ns_ptype != CHARPTR) {
6090Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
6106063Smj162486 gettext("Required BaseDN and/or Profile name "
6116063Smj162486 "ldif fields not present"));
6120Sstevel@tonic-gate MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE, strdup(errstr),
6136063Smj162486 NULL);
6140Sstevel@tonic-gate __s_api_release_config(ptr);
6150Sstevel@tonic-gate return (errorp);
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate
6180Sstevel@tonic-gate profile = ptr->paramList[NS_LDAP_PROFILE_P].ns_pc;
6190Sstevel@tonic-gate base = ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_pc;
6200Sstevel@tonic-gate container = _PROFILE_CONTAINER;
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate /*
6230Sstevel@tonic-gate * Construct DN, but since this is the profile, there is no need
6240Sstevel@tonic-gate * to worry about mapping. The profile itself can not be mapped
6250Sstevel@tonic-gate */
6260Sstevel@tonic-gate (void) fprintf(fp, "dn: cn=%s,ou=%s,%s\n", profile, container, base);
6270Sstevel@tonic-gate
6280Sstevel@tonic-gate /* dump objectclass names */
6290Sstevel@tonic-gate if (ptr->version == NS_LDAP_V1) {
6306063Smj162486 (void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n",
6316063Smj162486 _PROFILE1_OBJECTCLASS);
6320Sstevel@tonic-gate } else {
6336063Smj162486 (void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n",
6346063Smj162486 _PROFILE2_OBJECTCLASS);
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate
6370Sstevel@tonic-gate /* For each parameter - construct value */
6380Sstevel@tonic-gate for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
639*10132SMilan.Jurik@Sun.COM str = __s_api_strValue(ptr, i, NS_LDIF_FMT);
6400Sstevel@tonic-gate if (str == NULL)
6410Sstevel@tonic-gate continue;
6420Sstevel@tonic-gate /*
6438821SMichen.Chang@Sun.COM * don't dump binddn, bind password, admin binddn, admin
6448821SMichen.Chang@Sun.COM * bind password, enableShadowUpdate flag, or cert path
6458821SMichen.Chang@Sun.COM * as they are not part of version 2 profiles
6460Sstevel@tonic-gate */
6478821SMichen.Chang@Sun.COM if ((i != NS_LDAP_BINDDN_P) &&
6488821SMichen.Chang@Sun.COM (i != NS_LDAP_BINDPASSWD_P) &&
6498821SMichen.Chang@Sun.COM (i != NS_LDAP_ADMIN_BINDDN_P) &&
6508821SMichen.Chang@Sun.COM (i != NS_LDAP_ADMIN_BINDPASSWD_P) &&
6518821SMichen.Chang@Sun.COM (i != NS_LDAP_ENABLE_SHADOW_UPDATE_P) &&
6526063Smj162486 (i != NS_LDAP_HOST_CERTPATH_P))
6530Sstevel@tonic-gate (void) fprintf(fp, "%s\n", str);
654*10132SMilan.Jurik@Sun.COM free(str);
6550Sstevel@tonic-gate }
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate if (filename != NULL)
6580Sstevel@tonic-gate (void) fclose(fp);
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate __s_api_release_config(ptr);
6610Sstevel@tonic-gate return (NULL);
6620Sstevel@tonic-gate }
6630Sstevel@tonic-gate
6640Sstevel@tonic-gate /*
6650Sstevel@tonic-gate * This routine can process the configuration and/or
6660Sstevel@tonic-gate * the credential files at the same time.
6670Sstevel@tonic-gate * files is char *[3] = { "config", "cred", NULL };
6680Sstevel@tonic-gate */
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate static
6710Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_DumpConfigFiles(char ** files)6720Sstevel@tonic-gate __ns_ldap_DumpConfigFiles(char **files)
6730Sstevel@tonic-gate {
6740Sstevel@tonic-gate char *filename;
6750Sstevel@tonic-gate int fi;
6760Sstevel@tonic-gate int docred;
6770Sstevel@tonic-gate ns_config_t *ptr;
6780Sstevel@tonic-gate char *str;
6790Sstevel@tonic-gate char errstr[MAXERROR];
6800Sstevel@tonic-gate ParamIndexType i = 0;
6810Sstevel@tonic-gate FILE *fp;
6820Sstevel@tonic-gate int rc;
6836063Smj162486 ns_ldap_error_t *errorp = NULL;
6840Sstevel@tonic-gate struct stat buf;
6850Sstevel@tonic-gate int cfgtype;
6866063Smj162486 boolean_t file_export_error = B_FALSE;
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate ptr = __s_api_get_default_config();
6890Sstevel@tonic-gate if (ptr == NULL) {
6900Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
6916063Smj162486 gettext("No configuration information available."));
6920Sstevel@tonic-gate MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
6936063Smj162486 NULL);
6940Sstevel@tonic-gate return (errorp);
6950Sstevel@tonic-gate }
6960Sstevel@tonic-gate
6970Sstevel@tonic-gate for (fi = 0; fi < 2; fi++) {
6980Sstevel@tonic-gate docred = 0;
6990Sstevel@tonic-gate filename = files[fi];
7000Sstevel@tonic-gate if (filename == NULL)
7010Sstevel@tonic-gate continue;
7020Sstevel@tonic-gate if (fi == 1)
7030Sstevel@tonic-gate docred++;
7040Sstevel@tonic-gate rc = stat(filename, &buf);
7051914Scasper fp = fopen(filename, "wF");
7060Sstevel@tonic-gate if (fp == NULL) {
7070Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
7086063Smj162486 gettext("Unable to open filename %s"
7096063Smj162486 " for configuration dump (%s)."),
7106063Smj162486 filename, strerror(errno));
7116063Smj162486 MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE,
7126063Smj162486 strdup(errstr), NULL);
7130Sstevel@tonic-gate __s_api_release_config(ptr);
7140Sstevel@tonic-gate return (errorp);
7150Sstevel@tonic-gate }
7166063Smj162486 if (rc == 0) {
7176063Smj162486 if (fchmod(fileno(fp), buf.st_mode) != 0) {
7186063Smj162486 (void) snprintf(errstr, sizeof (errstr),
7196063Smj162486 gettext("Unable to set permissions for file"
7206063Smj162486 " %s for configuration dump (%s)."),
7216063Smj162486 filename, strerror(errno));
7226063Smj162486 (void) fclose(fp);
7236063Smj162486 file_export_error = B_TRUE;
7246063Smj162486 break;
7256063Smj162486 }
7266063Smj162486 } else {
7276063Smj162486 if (fchmod(fileno(fp), 0400) != 0) {
7286063Smj162486 (void) snprintf(errstr, sizeof (errstr),
7296063Smj162486 gettext("Unable to set permissions for file"
7306063Smj162486 " %s for configuration dump (%s)."),
7316063Smj162486 filename, strerror(errno));
7326063Smj162486 (void) fclose(fp);
7336063Smj162486 file_export_error = B_TRUE;
7346063Smj162486 break;
7356063Smj162486 }
7366063Smj162486 }
7376063Smj162486 if (fprintf(fp, "#\n# %s\n#\n", DONOTEDIT) < 0) {
7386063Smj162486 (void) snprintf(errstr, sizeof (errstr), gettext(
7396063Smj162486 "Writing to file %s for configuration dump failed "
7406063Smj162486 "(%s)."), filename, strerror(errno));
7416063Smj162486 file_export_error = B_TRUE;
7426063Smj162486 }
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate /* assume VERSION is set and it outputs first */
7450Sstevel@tonic-gate
7460Sstevel@tonic-gate /* For each parameter - construct value */
7476063Smj162486 for (i = 0; !file_export_error && (i <= NS_LDAP_MAX_PIT_P);
7486063Smj162486 i++) {
7490Sstevel@tonic-gate cfgtype = __s_api_get_configtype(i);
7500Sstevel@tonic-gate if ((docred == 0 && cfgtype == CREDCONFIG) ||
7516063Smj162486 (docred == 1 && cfgtype != CREDCONFIG))
7520Sstevel@tonic-gate continue;
7530Sstevel@tonic-gate
754*10132SMilan.Jurik@Sun.COM str = __s_api_strValue(ptr, i, NS_FILE_FMT);
7550Sstevel@tonic-gate if (str == NULL)
7560Sstevel@tonic-gate continue;
7576063Smj162486 if (fprintf(fp, "%s\n", str) < 0) {
7586063Smj162486 (void) snprintf(errstr, sizeof (errstr),
7596063Smj162486 gettext("Writing to file %s for"
7606063Smj162486 "configuration dump failed (%s)."),
7616063Smj162486 filename, strerror(errno));
7626063Smj162486 file_export_error = B_TRUE;
7636063Smj162486 }
7646063Smj162486
765*10132SMilan.Jurik@Sun.COM free(str);
7660Sstevel@tonic-gate }
7676063Smj162486 if (fclose(fp) != 0) {
7686063Smj162486 /* Break if error already hit */
7696063Smj162486 if (file_export_error)
7706063Smj162486 break;
7716063Smj162486
7726063Smj162486 (void) snprintf(errstr, sizeof (errstr), gettext(
7736063Smj162486 "Writing to file %s for configuration dump failed "
7746063Smj162486 "during file close (%s)."), filename,
7756063Smj162486 strerror(errno));
7766063Smj162486 file_export_error = B_TRUE;
7776063Smj162486 break;
7786063Smj162486 }
7796063Smj162486
7806063Smj162486 }
7816063Smj162486
7826063Smj162486 if (file_export_error) {
7836063Smj162486 MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE,
7846063Smj162486 strdup(errstr), NULL);
7856063Smj162486 (void) unlink(filename);
7860Sstevel@tonic-gate }
7870Sstevel@tonic-gate
7880Sstevel@tonic-gate __s_api_release_config(ptr);
7896063Smj162486 return (errorp);
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_DumpConfiguration(char * file)7930Sstevel@tonic-gate __ns_ldap_DumpConfiguration(char *file)
7940Sstevel@tonic-gate {
7950Sstevel@tonic-gate ns_ldap_error_t *ret;
7960Sstevel@tonic-gate char *files[3];
7970Sstevel@tonic-gate
7980Sstevel@tonic-gate files[0] = NULL;
7990Sstevel@tonic-gate files[1] = NULL;
8000Sstevel@tonic-gate files[2] = NULL;
8010Sstevel@tonic-gate if (strcmp(file, NSCONFIGFILE) == 0) {
8020Sstevel@tonic-gate files[0] = file;
8030Sstevel@tonic-gate } else if (strcmp(file, NSCONFIGREFRESH) == 0) {
8040Sstevel@tonic-gate files[0] = file;
8050Sstevel@tonic-gate } else if (strcmp(file, NSCREDFILE) == 0) {
8060Sstevel@tonic-gate files[1] = file;
8070Sstevel@tonic-gate } else if (strcmp(file, NSCREDREFRESH) == 0) {
8080Sstevel@tonic-gate files[1] = file;
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate ret = __ns_ldap_DumpConfigFiles(files);
8110Sstevel@tonic-gate return (ret);
8120Sstevel@tonic-gate }
8130Sstevel@tonic-gate
8140Sstevel@tonic-gate /*
8150Sstevel@tonic-gate * **************************************************************
8160Sstevel@tonic-gate * Misc Routines
8170Sstevel@tonic-gate * **************************************************************
8180Sstevel@tonic-gate */
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate ns_config_t *
__ns_ldap_make_config(ns_ldap_result_t * result)8210Sstevel@tonic-gate __ns_ldap_make_config(ns_ldap_result_t *result)
8220Sstevel@tonic-gate {
8232095Smj162486 int l, m;
824*10132SMilan.Jurik@Sun.COM char val[BUFSIZE];
8250Sstevel@tonic-gate char *attrname;
8260Sstevel@tonic-gate ns_ldap_entry_t *entry;
8270Sstevel@tonic-gate ns_ldap_attr_t *attr;
8280Sstevel@tonic-gate char **attrval;
8290Sstevel@tonic-gate ParamIndexType index;
8300Sstevel@tonic-gate ns_config_t *ptr;
8310Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
8320Sstevel@tonic-gate int prof_ver;
8330Sstevel@tonic-gate ns_config_t *curr_ptr = NULL;
8342095Smj162486 char errstr[MAXERROR];
8352095Smj162486 ns_ldap_error_t *errorp;
836*10132SMilan.Jurik@Sun.COM LineBuf buffer;
837*10132SMilan.Jurik@Sun.COM char *sepstr;
8380Sstevel@tonic-gate
8390Sstevel@tonic-gate if (result == NULL)
8400Sstevel@tonic-gate return (NULL);
8410Sstevel@tonic-gate
8422095Smj162486 if (result->entries_count > 1) {
8432095Smj162486 (void) snprintf(errstr, MAXERROR,
8446063Smj162486 gettext("Configuration Error: More than one profile "
8456063Smj162486 "found"));
8462095Smj162486 MKERROR(LOG_ERR, errorp, NS_PARSE_ERR, strdup(errstr), NULL);
8472095Smj162486 (void) __ns_ldap_freeError(&errorp);
8482095Smj162486 return (NULL);
8492095Smj162486 }
8502095Smj162486
8510Sstevel@tonic-gate ptr = __s_api_create_config();
8520Sstevel@tonic-gate if (ptr == NULL)
8530Sstevel@tonic-gate return (NULL);
8540Sstevel@tonic-gate
8550Sstevel@tonic-gate curr_ptr = __s_api_get_default_config();
8560Sstevel@tonic-gate if (curr_ptr == NULL) {
8570Sstevel@tonic-gate __s_api_destroy_config(ptr);
8580Sstevel@tonic-gate return (NULL);
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate /* Check to see if the profile is version 1 or version 2 */
8620Sstevel@tonic-gate prof_ver = 1;
8630Sstevel@tonic-gate entry = result->entry;
8642095Smj162486 for (l = 0; l < entry->attr_count; l++) {
8652095Smj162486 attr = entry->attr_pair[l];
8660Sstevel@tonic-gate
8672095Smj162486 attrname = attr->attrname;
8682095Smj162486 if (attrname == NULL)
8692095Smj162486 continue;
8702095Smj162486 if (strcasecmp(attrname, "objectclass") == 0) {
8712095Smj162486 for (m = 0; m < attr->value_count; m++) {
8722095Smj162486 if (strcasecmp(_PROFILE2_OBJECTCLASS,
8736063Smj162486 attr->attrvalue[m]) == 0) {
8742095Smj162486 prof_ver = 2;
8752095Smj162486 break;
8760Sstevel@tonic-gate }
8770Sstevel@tonic-gate }
8780Sstevel@tonic-gate }
8790Sstevel@tonic-gate }
8800Sstevel@tonic-gate /* update the configuration to accept v1 or v2 attributes */
8810Sstevel@tonic-gate if (prof_ver == 1) {
8820Sstevel@tonic-gate (void) strcpy(val, NS_LDAP_VERSION_1);
8836063Smj162486 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P,
8846063Smj162486 val, &error);
8850Sstevel@tonic-gate } else {
8860Sstevel@tonic-gate (void) strcpy(val, NS_LDAP_VERSION_2);
8876063Smj162486 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P,
8886063Smj162486 val, &error);
8890Sstevel@tonic-gate }
8900Sstevel@tonic-gate
8912095Smj162486 for (l = 0; l < entry->attr_count; l++) {
8922095Smj162486 attr = entry->attr_pair[l];
8930Sstevel@tonic-gate
8942095Smj162486 attrname = attr->attrname;
8952095Smj162486 if (attrname == NULL)
8962095Smj162486 continue;
8972095Smj162486 if (__s_api_get_profiletype(attrname, &index) != 0)
8982095Smj162486 continue;
8990Sstevel@tonic-gate
9002095Smj162486 attrval = attr->attrvalue;
9012095Smj162486 switch (index) {
9022095Smj162486 case NS_LDAP_SEARCH_DN_P:
9032095Smj162486 case NS_LDAP_SERVICE_SEARCH_DESC_P:
9042095Smj162486 case NS_LDAP_ATTRIBUTEMAP_P:
9052095Smj162486 case NS_LDAP_OBJECTCLASSMAP_P:
9062095Smj162486 case NS_LDAP_SERVICE_CRED_LEVEL_P:
9072095Smj162486 case NS_LDAP_SERVICE_AUTH_METHOD_P:
9082095Smj162486 /* Multiple Value - insert 1 at a time */
9092095Smj162486 for (m = 0; m < attr->value_count; m++) {
9102095Smj162486 (void) __ns_ldap_setParamValue(ptr, index,
9116063Smj162486 attrval[m], &error);
9122095Smj162486 }
9132095Smj162486 break;
9142095Smj162486 default:
915*10132SMilan.Jurik@Sun.COM (void) memset((void *)&buffer, 0, sizeof (LineBuf));
916*10132SMilan.Jurik@Sun.COM
9172095Smj162486 /* Single or Multiple Value */
9182095Smj162486 for (m = 0; m < attr->value_count; m++) {
919*10132SMilan.Jurik@Sun.COM sepstr = NULL;
920*10132SMilan.Jurik@Sun.COM if (m != attr->value_count - 1) {
921*10132SMilan.Jurik@Sun.COM sepstr = SPACESEP;
9220Sstevel@tonic-gate }
923*10132SMilan.Jurik@Sun.COM if (__print2buf(&buffer, attrval[m], sepstr))
924*10132SMilan.Jurik@Sun.COM goto makeconfigerror;
9250Sstevel@tonic-gate }
926*10132SMilan.Jurik@Sun.COM (void) __ns_ldap_setParamValue(ptr, index, buffer.str,
927*10132SMilan.Jurik@Sun.COM &error);
928*10132SMilan.Jurik@Sun.COM if (buffer.len > 0) {
929*10132SMilan.Jurik@Sun.COM free(buffer.str);
930*10132SMilan.Jurik@Sun.COM buffer.len = 0;
931*10132SMilan.Jurik@Sun.COM }
9322095Smj162486 break;
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate }
9350Sstevel@tonic-gate if (ptr->version != NS_LDAP_V1) {
9368821SMichen.Chang@Sun.COM ParamIndexType i;
9376063Smj162486 if (curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_ptype == CHARPTR) {
9386063Smj162486 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_BINDDN_P,
9396063Smj162486 curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_pc,
9406063Smj162486 &error);
9416063Smj162486 }
9426063Smj162486 if (curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ptype ==
9436063Smj162486 CHARPTR) {
9446063Smj162486 (void) __ns_ldap_setParamValue(ptr,
9456063Smj162486 NS_LDAP_BINDPASSWD_P,
9466063Smj162486 curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_pc,
9476063Smj162486 &error);
9486063Smj162486 }
9498821SMichen.Chang@Sun.COM i = NS_LDAP_ENABLE_SHADOW_UPDATE_P;
9508821SMichen.Chang@Sun.COM if (curr_ptr->paramList[i].ns_ptype == INT) {
951*10132SMilan.Jurik@Sun.COM char *valt;
952*10132SMilan.Jurik@Sun.COM valt = __s_get_shadowupdate_name(
9538821SMichen.Chang@Sun.COM curr_ptr->paramList[i].ns_i);
954*10132SMilan.Jurik@Sun.COM (void) __ns_ldap_setParamValue(ptr, i, valt, &error);
9558821SMichen.Chang@Sun.COM }
9568821SMichen.Chang@Sun.COM if (curr_ptr->paramList[NS_LDAP_ADMIN_BINDDN_P].ns_ptype ==
9578821SMichen.Chang@Sun.COM CHARPTR) {
9588821SMichen.Chang@Sun.COM (void) __ns_ldap_setParamValue(ptr,
9598821SMichen.Chang@Sun.COM NS_LDAP_ADMIN_BINDDN_P,
9608821SMichen.Chang@Sun.COM curr_ptr->paramList[NS_LDAP_ADMIN_BINDDN_P].ns_pc,
9618821SMichen.Chang@Sun.COM &error);
9628821SMichen.Chang@Sun.COM }
9638821SMichen.Chang@Sun.COM if (curr_ptr->paramList[NS_LDAP_ADMIN_BINDPASSWD_P].ns_ptype ==
9648821SMichen.Chang@Sun.COM CHARPTR) {
9658821SMichen.Chang@Sun.COM (void) __ns_ldap_setParamValue(ptr,
9668821SMichen.Chang@Sun.COM NS_LDAP_ADMIN_BINDPASSWD_P,
9678821SMichen.Chang@Sun.COM curr_ptr->
9688821SMichen.Chang@Sun.COM paramList[NS_LDAP_ADMIN_BINDPASSWD_P].ns_pc,
9698821SMichen.Chang@Sun.COM &error);
9708821SMichen.Chang@Sun.COM }
9716063Smj162486 if (curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_ptype ==
9726063Smj162486 CHARPTR) {
9736063Smj162486 (void) __ns_ldap_setParamValue(ptr,
9746063Smj162486 NS_LDAP_HOST_CERTPATH_P,
9756063Smj162486 curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_pc,
9766063Smj162486 &error);
9776063Smj162486 }
9780Sstevel@tonic-gate }
9790Sstevel@tonic-gate __s_api_release_config(curr_ptr);
9800Sstevel@tonic-gate return (ptr);
981*10132SMilan.Jurik@Sun.COM
982*10132SMilan.Jurik@Sun.COM makeconfigerror:
983*10132SMilan.Jurik@Sun.COM if (buffer.len > 0)
984*10132SMilan.Jurik@Sun.COM free(buffer.str);
985*10132SMilan.Jurik@Sun.COM
986*10132SMilan.Jurik@Sun.COM __s_api_debug_pause(LOG_ERR, NS_PARSE_ERR,
987*10132SMilan.Jurik@Sun.COM "__ns_ldap_make_config: Not enough memory");
988*10132SMilan.Jurik@Sun.COM return (NULL);
9890Sstevel@tonic-gate }
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate /*
9920Sstevel@tonic-gate * Download a profile into our internal structure. The calling application
9930Sstevel@tonic-gate * needs to DumpConfig() to save the information to NSCONFIGFILE and NSCREDFILE
9940Sstevel@tonic-gate * if desired.
9950Sstevel@tonic-gate */
9960Sstevel@tonic-gate int
__ns_ldap_download(const char * profile,char * addr,char * baseDN,ns_ldap_error_t ** errorp)9970Sstevel@tonic-gate __ns_ldap_download(const char *profile, char *addr, char *baseDN,
9980Sstevel@tonic-gate ns_ldap_error_t **errorp)
9990Sstevel@tonic-gate {
1000*10132SMilan.Jurik@Sun.COM char filter[BUFSIZE];
10010Sstevel@tonic-gate int rc;
10020Sstevel@tonic-gate ns_ldap_result_t *result = NULL;
10030Sstevel@tonic-gate ns_config_t *ptr = NULL;
10040Sstevel@tonic-gate ns_config_t *new_ptr = NULL;
10050Sstevel@tonic-gate char errstr[MAXERROR];
10060Sstevel@tonic-gate
10070Sstevel@tonic-gate *errorp = NULL;
10080Sstevel@tonic-gate if (baseDN == NULL)
10090Sstevel@tonic-gate return (NS_LDAP_INVALID_PARAM);
10100Sstevel@tonic-gate
10110Sstevel@tonic-gate ptr = __s_api_get_default_config();
10120Sstevel@tonic-gate if (ptr == NULL) {
10130Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
10140Sstevel@tonic-gate gettext("No configuration information available."));
10150Sstevel@tonic-gate MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
10166063Smj162486 NULL);
10170Sstevel@tonic-gate return (NS_LDAP_CONFIG);
10180Sstevel@tonic-gate }
10190Sstevel@tonic-gate
10206063Smj162486 rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SEARCH_BASEDN_P, baseDN,
10216063Smj162486 errorp);
10220Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) {
10230Sstevel@tonic-gate __s_api_release_config(ptr);
10240Sstevel@tonic-gate return (rc);
10250Sstevel@tonic-gate }
10260Sstevel@tonic-gate
10270Sstevel@tonic-gate rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SERVERS_P, addr, errorp);
10280Sstevel@tonic-gate __s_api_release_config(ptr);
10290Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS)
10300Sstevel@tonic-gate return (rc);
10310Sstevel@tonic-gate
10320Sstevel@tonic-gate (void) snprintf(filter, sizeof (filter), _PROFILE_FILTER,
10336063Smj162486 _PROFILE1_OBJECTCLASS, _PROFILE2_OBJECTCLASS, profile);
10340Sstevel@tonic-gate rc = __ns_ldap_list(_PROFILE_CONTAINER, (const char *)filter,
10356063Smj162486 NULL, NULL, NULL, 0, &result, errorp, NULL, NULL);
10360Sstevel@tonic-gate
10370Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS)
10380Sstevel@tonic-gate return (rc);
10390Sstevel@tonic-gate
10400Sstevel@tonic-gate new_ptr = __ns_ldap_make_config(result);
10410Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result);
10420Sstevel@tonic-gate
10432095Smj162486 if (new_ptr == NULL)
10442095Smj162486 return (NS_LDAP_OP_FAILED);
10452095Smj162486
10460Sstevel@tonic-gate rc = __s_api_crosscheck(new_ptr, errstr, B_FALSE);
10470Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) {
10480Sstevel@tonic-gate __s_api_destroy_config(new_ptr);
10490Sstevel@tonic-gate MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
10506063Smj162486 NULL);
10510Sstevel@tonic-gate return (NS_LDAP_CONFIG);
10520Sstevel@tonic-gate }
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate __s_api_init_config(new_ptr);
10550Sstevel@tonic-gate return (rc);
10560Sstevel@tonic-gate }
10570Sstevel@tonic-gate
10580Sstevel@tonic-gate /*
10590Sstevel@tonic-gate * **************************************************************
10600Sstevel@tonic-gate * Configuration Printing Routines
10610Sstevel@tonic-gate * **************************************************************
10620Sstevel@tonic-gate */
10630Sstevel@tonic-gate
10640Sstevel@tonic-gate /*
10650Sstevel@tonic-gate * Yes the use of stdio is okay here because all we are doing is sending
10660Sstevel@tonic-gate * output to stdout. This would not be necessary if we could get to the
10670Sstevel@tonic-gate * configuration pointer outside this file.
10680Sstevel@tonic-gate */
10690Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_print_config(int verbose)10700Sstevel@tonic-gate __ns_ldap_print_config(int verbose)
10710Sstevel@tonic-gate {
10720Sstevel@tonic-gate ns_config_t *ptr;
10730Sstevel@tonic-gate char errstr[MAXERROR];
10740Sstevel@tonic-gate ns_ldap_error_t *errorp;
10750Sstevel@tonic-gate char *str;
10760Sstevel@tonic-gate int i;
10770Sstevel@tonic-gate
10780Sstevel@tonic-gate ptr = __s_api_get_default_config();
10790Sstevel@tonic-gate if (ptr == NULL) {
10800Sstevel@tonic-gate errorp = __ns_ldap_LoadConfiguration();
10810Sstevel@tonic-gate if (errorp != NULL)
10820Sstevel@tonic-gate return (errorp);
10830Sstevel@tonic-gate ptr = __s_api_get_default_config();
10840Sstevel@tonic-gate if (ptr == NULL) {
10850Sstevel@tonic-gate (void) snprintf(errstr, sizeof (errstr),
10860Sstevel@tonic-gate gettext("No configuration information."));
10870Sstevel@tonic-gate MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
10886063Smj162486 strdup(errstr), NULL);
10890Sstevel@tonic-gate return (errorp);
10900Sstevel@tonic-gate }
10910Sstevel@tonic-gate }
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate if (verbose && (ptr->domainName != NULL)) {
10940Sstevel@tonic-gate (void) fputs("ptr->domainName ", stdout);
10950Sstevel@tonic-gate (void) fputs(ptr->domainName, stdout);
10960Sstevel@tonic-gate (void) putchar('\n');
10970Sstevel@tonic-gate }
10980Sstevel@tonic-gate /* For each parameter - construct value */
10990Sstevel@tonic-gate for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
11000Sstevel@tonic-gate /*
11010Sstevel@tonic-gate * Version 1 skipped this entry because:
11020Sstevel@tonic-gate *
11030Sstevel@tonic-gate * don't print default cache TTL for now since
11040Sstevel@tonic-gate * we don't store it in the ldap_client_file.
11050Sstevel@tonic-gate */
11060Sstevel@tonic-gate if ((i == NS_LDAP_CACHETTL_P) && (ptr->version == NS_LDAP_V1))
11070Sstevel@tonic-gate continue;
11080Sstevel@tonic-gate
11098821SMichen.Chang@Sun.COM /* the credential for shadow update is not to be exposed */
11108821SMichen.Chang@Sun.COM if (i == NS_LDAP_ADMIN_BINDDN_P ||
11118821SMichen.Chang@Sun.COM i == NS_LDAP_ADMIN_BINDPASSWD_P)
11128821SMichen.Chang@Sun.COM continue;
11138821SMichen.Chang@Sun.COM
1114*10132SMilan.Jurik@Sun.COM str = __s_api_strValue(ptr, i, NS_FILE_FMT);
11150Sstevel@tonic-gate if (str == NULL)
11160Sstevel@tonic-gate continue;
11170Sstevel@tonic-gate if (verbose)
11180Sstevel@tonic-gate (void) putchar('\t');
11190Sstevel@tonic-gate (void) fprintf(stdout, "%s\n", str);
1120*10132SMilan.Jurik@Sun.COM free(str);
11210Sstevel@tonic-gate }
11220Sstevel@tonic-gate
11230Sstevel@tonic-gate __s_api_release_config(ptr);
11240Sstevel@tonic-gate return (NULL);
11250Sstevel@tonic-gate }
1126