8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libsldap / common / ns_confmgr.c
blob5b99b9b4c2d47c46bfc55c4b2587614dcf158460
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* libsldap - cachemgr side configuration components */
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <stdlib.h>
31 #include <libintl.h>
32 #include <string.h>
33 #include <ctype.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <syslog.h>
39 #include <locale.h>
40 #include <errno.h>
41 #include <sys/time.h>
43 #include "ns_sldap.h"
44 #include "ns_internal.h"
45 #include "ns_cache_door.h"
47 #define ALWAYS 1
51 * **************************************************************
52 * Configuration File Routines
53 * **************************************************************
57 /* Size of the errstr buffer needs to be MAXERROR */
58 static int
59 read_line(FILE *fp, char *buffer, int buflen, char *errstr)
61 int linelen;
62 char c;
64 *errstr = '\0';
66 for (linelen = 0; linelen < buflen; ) {
67 c = getc(fp);
68 if (c == EOF)
69 break;
70 switch (c) {
71 case '\n':
72 if (linelen > 0 && buffer[linelen - 1] == '\\') {
73 /* Continuation line found */
74 --linelen;
75 } else {
76 /* end of line found */
77 buffer[linelen] = '\0';
78 return (linelen);
80 break;
81 default:
82 buffer[linelen++] = c;
86 if (linelen >= buflen) {
87 (void) snprintf(errstr, MAXERROR,
88 gettext("Buffer overflow, line too long."));
89 return (-2);
90 } else if (linelen > 0 && buffer[linelen - 1] == '\\') {
91 (void) snprintf(errstr, MAXERROR,
92 gettext("Unterminated continuation line."));
93 return (-2);
94 } else {
95 /* end of file */
96 buffer[linelen] = '\0';
98 return (linelen > 0 ? linelen : -1);
102 static ns_parse_status
103 read_file(ns_config_t *ptr, int cred_file, ns_ldap_error_t **error)
105 ParamIndexType i = 0;
106 char errstr[MAXERROR];
107 char buffer[BUFSIZE], *name, *value;
108 int emptyfile, lineno;
109 FILE *fp;
110 int ret;
111 int linelen;
112 char *file;
113 int first = 1;
116 if (cred_file) {
117 file = NSCREDFILE;
118 } else {
119 file = NSCONFIGFILE;
121 fp = fopen(file, "rF");
122 if (fp == NULL) {
123 (void) snprintf(errstr, sizeof (errstr),
124 gettext("Unable to open filename '%s' "
125 "for reading (errno=%d)."), file, errno);
126 MKERROR(LOG_ERR, *error, NS_CONFIG_FILE, strdup(errstr), NULL);
127 return (NS_NOTFOUND);
130 emptyfile = 1;
131 lineno = 0;
132 for (; ; ) {
133 if ((linelen = read_line(fp, buffer, sizeof (buffer),
134 errstr)) < 0)
135 /* End of file */
136 break;
137 lineno++;
138 if (linelen == 0)
139 continue;
140 /* get rid of comment lines */
141 if (buffer[0] == '#')
142 continue;
143 emptyfile = 0;
144 name = NULL;
145 value = NULL;
146 __s_api_split_key_value(buffer, &name, &value);
147 if (name == NULL || value == NULL) {
148 (void) snprintf(errstr, sizeof (errstr),
149 gettext("Missing Name or Value on line %d."),
150 lineno);
151 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
152 strdup(errstr), NULL);
153 (void) fclose(fp);
154 return (NS_PARSE_ERR);
156 if (__s_api_get_versiontype(ptr, name, &i) != 0) {
157 (void) snprintf(errstr, sizeof (errstr),
158 gettext("Illegal profile type on line %d."),
159 lineno);
160 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
161 strdup(errstr), NULL);
162 (void) fclose(fp);
163 return (NS_PARSE_ERR);
165 if (!first && i == NS_LDAP_FILE_VERSION_P) {
166 (void) snprintf(errstr, sizeof (errstr),
167 gettext("Illegal NS_LDAP_FILE_VERSION "
168 "on line %d."), lineno);
169 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
170 strdup(errstr), NULL);
171 (void) fclose(fp);
172 return (NS_PARSE_ERR);
174 first = 0;
175 switch (__s_api_get_configtype(i)) {
176 case SERVERCONFIG:
177 case CLIENTCONFIG:
178 if (cred_file == 0) {
179 ret = __ns_ldap_setParamValue(ptr, i, value,
180 error);
181 if (ret != NS_SUCCESS) {
182 (void) fclose(fp);
183 return (ret);
185 } else if (i != NS_LDAP_FILE_VERSION_P) {
186 (void) snprintf(errstr, sizeof (errstr),
187 gettext("Illegal entry in '%s' on "
188 "line %d"), file, lineno);
189 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
190 strdup(errstr), NULL);
191 (void) fclose(fp);
192 return (NS_PARSE_ERR);
194 break;
195 case CREDCONFIG:
196 if (i == NS_LDAP_FILE_VERSION_P)
197 break;
198 if (cred_file) {
199 ret = __ns_ldap_setParamValue(ptr, i, value,
200 error);
201 if (ret != NS_SUCCESS) {
202 (void) fclose(fp);
203 return (ret);
205 } else {
206 (void) snprintf(errstr, sizeof (errstr),
207 gettext("Illegal entry in '%s' on "
208 "line %d"), file, lineno);
209 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
210 strdup(errstr), NULL);
211 (void) fclose(fp);
212 return (NS_PARSE_ERR);
216 (void) fclose(fp);
217 if (!cred_file && emptyfile) {
218 /* Error in read_line */
219 (void) snprintf(errstr, sizeof (errstr),
220 gettext("Empty config file: '%s'"), file);
221 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
222 NULL);
223 return (NS_PARSE_ERR);
225 if (linelen == -2) {
226 /* Error in read_line */
227 (void) snprintf(errstr, sizeof (errstr),
228 gettext("Line too long in '%s'"), file);
229 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
230 NULL);
231 return (NS_PARSE_ERR);
233 return (NS_SUCCESS);
237 static
238 ns_ldap_return_code
239 set_attr(ns_config_t *config_struct,
240 char *attr_name,
241 char *attr_val,
242 ns_ldap_error_t **errorp)
244 ParamIndexType idx;
245 char errmsg[MAXERROR];
247 if (errorp == NULL) {
248 return (NS_LDAP_INVALID_PARAM);
251 *errorp = NULL;
254 * This double call is made due to the presence of
255 * two sets of LDAP config. attribute names.
256 * An LDAP configuration can be obtained either from a server
257 * or from SMF. The former sends a DUA with attributes' names
258 * styled like "preferredServerList". But local configurations
259 * will have names inherited from the /var/ldap/ldap* files such as
260 * "NS_LDAP_SERVER_PREF".
261 * So, the standalone bits are able to process both sets of
262 * attributes' names.
264 if (__s_api_get_profiletype(attr_name, &idx) < 0 &&
265 __s_api_get_versiontype(config_struct, attr_name, &idx) < 0) {
266 (void) snprintf(errmsg, sizeof (errmsg),
267 gettext("Illegal DUAProfile property: <%s>."), attr_name);
268 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
269 return (NS_LDAP_CONFIG);
272 return (__ns_ldap_setParamValue(config_struct, idx, attr_val, errorp));
277 * This function creates a configuration which will be used
278 * for all LDAP requests in the Standalone mode.
280 * INPUT:
281 * config - a buffer returned by __ns_ldap_getConnectionInfo()'s
282 * dua_profile parameter.
285 ns_config_t *
286 __s_api_create_config_door_str(char *config, ns_ldap_error_t **errorp)
288 char *attr, *attrName, *attrVal, *rest;
289 ns_config_t *configStruct = NULL;
290 char errmsg[MAXERROR];
292 if (config == NULL || errorp == NULL)
293 return (NULL);
295 if ((configStruct = __s_api_create_config()) == NULL) {
296 return (NULL);
299 *errorp = NULL;
301 attr = strtok_r(config, DOORLINESEP, &rest);
302 if (!attr) {
303 __s_api_destroy_config(configStruct);
304 (void) snprintf(errmsg, sizeof (errmsg),
305 gettext("DUAProfile received from the server"
306 " has bad format"));
307 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
308 return (NULL);
311 do {
312 __s_api_split_key_value(attr, &attrName, &attrVal);
314 if (attrName == NULL || attrVal == NULL) {
315 __s_api_destroy_config(configStruct);
316 (void) snprintf(errmsg, sizeof (errmsg),
317 gettext("Attribute %s is not valid"), attr);
318 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG,
319 strdup(errmsg), NULL);
320 return (NULL);
323 /* Get the version of the profile. */
324 if (strcasecmp(attrName, "objectclass") == 0) {
325 if (strcasecmp(attrVal, _PROFILE2_OBJECTCLASS) == 0) {
326 if (__ns_ldap_setParamValue(configStruct,
327 NS_LDAP_FILE_VERSION_P,
328 NS_LDAP_VERSION_2,
329 errorp) != NS_LDAP_SUCCESS) {
330 __s_api_destroy_config(configStruct);
331 return (NULL);
333 } else if (strcasecmp(attrVal,
334 _PROFILE1_OBJECTCLASS) == 0) {
335 if (__ns_ldap_setParamValue(configStruct,
336 NS_LDAP_FILE_VERSION_P,
337 NS_LDAP_VERSION_1,
338 errorp) != NS_LDAP_SUCCESS) {
339 __s_api_destroy_config(configStruct);
340 return (NULL);
343 continue;
346 if (set_attr(configStruct, attrName, attrVal, errorp) !=
347 NS_LDAP_SUCCESS) {
348 __s_api_destroy_config(configStruct);
349 return (NULL);
351 } while (attr = strtok_r(NULL, DOORLINESEP, &rest));
353 if (__s_api_crosscheck(configStruct, errmsg, B_FALSE) != NS_SUCCESS) {
354 MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
355 __s_api_destroy_config(configStruct);
356 return (NULL);
359 return (configStruct);
364 * Cache Manager side of configuration file loading
367 ns_ldap_error_t *
368 __ns_ldap_LoadConfiguration()
370 ns_ldap_error_t *error = NULL;
371 ns_config_t *ptr = NULL;
372 char errstr[MAXERROR];
373 ns_parse_status ret;
376 ptr = __s_api_create_config();
377 if (ptr == NULL) {
378 (void) snprintf(errstr, sizeof (errstr),
379 gettext("__ns_ldap_LoadConfiguration: Out of memory."));
380 MKERROR(LOG_ERR, error, NS_CONFIG_NOTLOADED,
381 strdup(errstr), NULL);
382 return (error);
385 /* Load in Configuration file */
386 ret = read_file(ptr, 0, &error);
387 if (ret != NS_SUCCESS) {
388 __s_api_destroy_config(ptr);
389 return (error);
392 /* Load in Credential file */
393 ret = read_file(ptr, 1, &error);
394 if (ret != NS_SUCCESS) {
395 __s_api_destroy_config(ptr);
396 return (error);
399 if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
400 __s_api_destroy_config(ptr);
401 MKERROR(LOG_ERR, error, NS_CONFIG_SYNTAX, strdup(errstr), NULL);
402 return (error);
405 __s_api_init_config(ptr);
406 return (NULL);
411 __print2buf(LineBuf *line, const char *toprint, char *sep)
413 int newsz = 0;
414 int newmax = 0;
415 char *str;
417 if (line == NULL)
418 return (-1);
420 newsz = strlen(toprint) + line->len + 1;
421 if (sep != NULL) {
422 newsz += strlen(sep);
424 if (line->alloc == 0 || newsz > line->alloc) {
425 /* Round up to next buffer and add 1 */
426 newmax = (((newsz+(BUFSIZ-1))/BUFSIZ)+1) * BUFSIZ;
427 if (line->alloc == 0)
428 line->str = (char *)calloc(newmax, 1);
429 else {
431 * if realloc() returns NULL,
432 * the original buffer is untouched.
433 * It needs to be freed.
435 str = (char *)realloc(line->str, newmax);
436 if (str == NULL) {
437 free(line->str);
438 line->str = NULL;
440 else
441 line->str = str;
443 line->alloc = newmax;
444 if (line->str == NULL) {
445 line->alloc = 0;
446 line->len = 0;
447 return (-1);
450 /* now add new 'toprint' data to buffer */
451 (void) strlcat(line->str, toprint, line->alloc);
452 if (sep != NULL) {
453 (void) strlcat(line->str, sep, line->alloc);
455 line->len = newsz;
456 return (0);
461 * __ns_ldap_LoadDoorInfo is a routine used by the ldapcachemgr
462 * to create a configuration buffer to transmit back to a client
463 * domainname is transmitted to ldapcachemgr and ldapcachemgr uses
464 * it to select a configuration to transmit back. Otherwise it
465 * is essentially unused in sldap.
466 * If cred_only is not 0, then only the credentials for shadow
467 * update are taken care of.
470 ns_ldap_error_t *
471 __ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname,
472 ns_config_t *new, int cred_only)
474 ns_config_t *ptr;
475 char errstr[MAXERROR];
476 ns_ldap_error_t *errorp;
477 char *str;
478 ParamIndexType i = 0;
479 int len;
480 ldap_config_out_t *cout;
483 * If new is NULL, it outputs the flatten data of current default
484 * config, if it's non-NULL, it outputs the flatten data of a temporary
485 * config. It's used to compare the new config data with the current
486 * default config data.
488 if (new == NULL)
489 ptr = __s_api_get_default_config();
490 else
491 ptr = new;
492 if (ptr == NULL) {
493 (void) snprintf(errstr, sizeof (errstr),
494 gettext("No configuration information available for %s."),
495 domainname == NULL ? "<no domain specified>" : domainname);
496 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
497 strdup(errstr), NULL);
498 return (errorp);
500 (void) memset((char *)configinfo, 0, sizeof (LineBuf));
501 for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
502 if (cred_only) {
503 /* only exposed credential for shadow update */
504 if (i != NS_LDAP_ADMIN_BINDDN_P &&
505 i != NS_LDAP_ADMIN_BINDPASSWD_P)
506 continue;
507 } else {
508 /* credential for shadow update is not to be exposed */
509 if (i == NS_LDAP_ADMIN_BINDDN_P ||
510 i == NS_LDAP_ADMIN_BINDPASSWD_P)
511 continue;
513 str = __s_api_strValue(ptr, i, NS_DOOR_FMT);
514 if (str == NULL)
515 continue;
516 if (__print2buf(configinfo, str, DOORLINESEP)) {
517 (void) snprintf(errstr, sizeof (errstr),
518 gettext("__print2buf: Out of memory."));
519 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
520 strdup(errstr), NULL);
521 __s_api_release_config(ptr);
522 free(str);
523 return (errorp);
525 free(str);
527 if (new == NULL)
528 __s_api_release_config(ptr);
531 * The new interface of the configuration between ldap_cachemgr
532 * & libsldap contains a header structure ldap_config_out_t.
533 * The flatten configuration data configinfo->str is cloned
534 * to cout->config_str, configinfo->len is saved in
535 * cout->data_size and cout->cookie is set later after this function
536 * is returned in ldap_cachemgr.
537 * configinfo->str & configinfo->len are reused to save info of
538 * header + data.
539 * The format:
540 * [cookie|data_size|config_str .............]
543 if (configinfo->str) {
544 len = sizeof (ldap_config_out_t) - sizeof (int) +
545 configinfo->len;
546 if ((cout = calloc(1, len)) == NULL) {
547 free(configinfo->str);
548 configinfo->str = NULL;
549 configinfo->len = 0;
550 (void) snprintf(errstr, sizeof (errstr),
551 gettext("calloc: Out of memory."));
552 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
553 strdup(errstr), NULL);
554 return (errorp);
557 * cout->cookie is set by the caller,
558 * which is in ldap_cachemgr.
560 cout->data_size = configinfo->len;
561 (void) memcpy(cout->config_str, configinfo->str,
562 configinfo->len);
563 free(configinfo->str);
564 configinfo->str = (char *)cout;
565 configinfo->len = len;
567 return (NULL);
571 ns_ldap_error_t *
572 __ns_ldap_DumpLdif(char *filename)
574 ns_config_t *ptr;
575 char errstr[MAXERROR];
576 ns_ldap_error_t *errorp;
577 char *str;
578 FILE *fp;
579 ParamIndexType i = 0;
580 char *profile, *container, *base;
582 ptr = __s_api_get_default_config();
583 if (ptr == NULL) {
584 (void) snprintf(errstr, sizeof (errstr),
585 gettext("No configuration information available."));
586 MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
587 NULL);
588 return (errorp);
591 if (filename == NULL) {
592 fp = stdout;
593 } else {
594 fp = fopen(filename, "wF");
595 if (fp == NULL) {
596 (void) snprintf(errstr, sizeof (errstr),
597 gettext("Unable to open filename %s for ldif "
598 "dump (errno=%d)."), filename, errno);
599 MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE,
600 strdup(errstr), NULL);
601 __s_api_release_config(ptr);
602 return (errorp);
604 (void) fchmod(fileno(fp), 0444);
607 if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ptype != CHARPTR ||
608 ptr->paramList[NS_LDAP_PROFILE_P].ns_ptype != CHARPTR) {
609 (void) snprintf(errstr, sizeof (errstr),
610 gettext("Required BaseDN and/or Profile name "
611 "ldif fields not present"));
612 MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE, strdup(errstr),
613 NULL);
614 __s_api_release_config(ptr);
615 return (errorp);
618 profile = ptr->paramList[NS_LDAP_PROFILE_P].ns_pc;
619 base = ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_pc;
620 container = _PROFILE_CONTAINER;
623 * Construct DN, but since this is the profile, there is no need
624 * to worry about mapping. The profile itself can not be mapped
626 (void) fprintf(fp, "dn: cn=%s,ou=%s,%s\n", profile, container, base);
628 /* dump objectclass names */
629 if (ptr->version == NS_LDAP_V1) {
630 (void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n",
631 _PROFILE1_OBJECTCLASS);
632 } else {
633 (void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n",
634 _PROFILE2_OBJECTCLASS);
637 /* For each parameter - construct value */
638 for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
639 str = __s_api_strValue(ptr, i, NS_LDIF_FMT);
640 if (str == NULL)
641 continue;
643 * don't dump binddn, bind password, admin binddn, admin
644 * bind password, enableShadowUpdate flag, or cert path
645 * as they are not part of version 2 profiles
647 if ((i != NS_LDAP_BINDDN_P) &&
648 (i != NS_LDAP_BINDPASSWD_P) &&
649 (i != NS_LDAP_ADMIN_BINDDN_P) &&
650 (i != NS_LDAP_ADMIN_BINDPASSWD_P) &&
651 (i != NS_LDAP_ENABLE_SHADOW_UPDATE_P) &&
652 (i != NS_LDAP_HOST_CERTPATH_P))
653 (void) fprintf(fp, "%s\n", str);
654 free(str);
657 if (filename != NULL)
658 (void) fclose(fp);
660 __s_api_release_config(ptr);
661 return (NULL);
665 * This routine can process the configuration and/or
666 * the credential files at the same time.
667 * files is char *[3] = { "config", "cred", NULL };
670 static
671 ns_ldap_error_t *
672 __ns_ldap_DumpConfigFiles(char **files)
674 char *filename;
675 int fi;
676 int docred;
677 ns_config_t *ptr;
678 char *str;
679 char errstr[MAXERROR];
680 ParamIndexType i = 0;
681 FILE *fp;
682 int rc;
683 ns_ldap_error_t *errorp = NULL;
684 struct stat buf;
685 int cfgtype;
686 boolean_t file_export_error = B_FALSE;
688 ptr = __s_api_get_default_config();
689 if (ptr == NULL) {
690 (void) snprintf(errstr, sizeof (errstr),
691 gettext("No configuration information available."));
692 MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
693 NULL);
694 return (errorp);
697 for (fi = 0; fi < 2; fi++) {
698 docred = 0;
699 filename = files[fi];
700 if (filename == NULL)
701 continue;
702 if (fi == 1)
703 docred++;
704 rc = stat(filename, &buf);
705 fp = fopen(filename, "wF");
706 if (fp == NULL) {
707 (void) snprintf(errstr, sizeof (errstr),
708 gettext("Unable to open filename %s"
709 " for configuration dump (%s)."),
710 filename, strerror(errno));
711 MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE,
712 strdup(errstr), NULL);
713 __s_api_release_config(ptr);
714 return (errorp);
716 if (rc == 0) {
717 if (fchmod(fileno(fp), buf.st_mode) != 0) {
718 (void) snprintf(errstr, sizeof (errstr),
719 gettext("Unable to set permissions for file"
720 " %s for configuration dump (%s)."),
721 filename, strerror(errno));
722 (void) fclose(fp);
723 file_export_error = B_TRUE;
724 break;
726 } else {
727 if (fchmod(fileno(fp), 0400) != 0) {
728 (void) snprintf(errstr, sizeof (errstr),
729 gettext("Unable to set permissions for file"
730 " %s for configuration dump (%s)."),
731 filename, strerror(errno));
732 (void) fclose(fp);
733 file_export_error = B_TRUE;
734 break;
737 if (fprintf(fp, "#\n# %s\n#\n", DONOTEDIT) < 0) {
738 (void) snprintf(errstr, sizeof (errstr), gettext(
739 "Writing to file %s for configuration dump failed "
740 "(%s)."), filename, strerror(errno));
741 file_export_error = B_TRUE;
744 /* assume VERSION is set and it outputs first */
746 /* For each parameter - construct value */
747 for (i = 0; !file_export_error && (i <= NS_LDAP_MAX_PIT_P);
748 i++) {
749 cfgtype = __s_api_get_configtype(i);
750 if ((docred == 0 && cfgtype == CREDCONFIG) ||
751 (docred == 1 && cfgtype != CREDCONFIG))
752 continue;
754 str = __s_api_strValue(ptr, i, NS_FILE_FMT);
755 if (str == NULL)
756 continue;
757 if (fprintf(fp, "%s\n", str) < 0) {
758 (void) snprintf(errstr, sizeof (errstr),
759 gettext("Writing to file %s for"
760 "configuration dump failed (%s)."),
761 filename, strerror(errno));
762 file_export_error = B_TRUE;
765 free(str);
767 if (fclose(fp) != 0) {
768 /* Break if error already hit */
769 if (file_export_error)
770 break;
772 (void) snprintf(errstr, sizeof (errstr), gettext(
773 "Writing to file %s for configuration dump failed "
774 "during file close (%s)."), filename,
775 strerror(errno));
776 file_export_error = B_TRUE;
777 break;
782 if (file_export_error) {
783 MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE,
784 strdup(errstr), NULL);
785 (void) unlink(filename);
788 __s_api_release_config(ptr);
789 return (errorp);
792 ns_ldap_error_t *
793 __ns_ldap_DumpConfiguration(char *file)
795 ns_ldap_error_t *ret;
796 char *files[3];
798 files[0] = NULL;
799 files[1] = NULL;
800 files[2] = NULL;
801 if (strcmp(file, NSCONFIGFILE) == 0) {
802 files[0] = file;
803 } else if (strcmp(file, NSCONFIGREFRESH) == 0) {
804 files[0] = file;
805 } else if (strcmp(file, NSCREDFILE) == 0) {
806 files[1] = file;
807 } else if (strcmp(file, NSCREDREFRESH) == 0) {
808 files[1] = file;
810 ret = __ns_ldap_DumpConfigFiles(files);
811 return (ret);
815 * **************************************************************
816 * Misc Routines
817 * **************************************************************
820 ns_config_t *
821 __ns_ldap_make_config(ns_ldap_result_t *result)
823 int l, m;
824 char val[BUFSIZE];
825 char *attrname;
826 ns_ldap_entry_t *entry;
827 ns_ldap_attr_t *attr;
828 char **attrval;
829 ParamIndexType index;
830 ns_config_t *ptr;
831 ns_ldap_error_t *error = NULL;
832 int prof_ver;
833 ns_config_t *curr_ptr = NULL;
834 char errstr[MAXERROR];
835 ns_ldap_error_t *errorp;
836 LineBuf buffer;
837 char *sepstr;
839 if (result == NULL)
840 return (NULL);
842 if (result->entries_count > 1) {
843 (void) snprintf(errstr, MAXERROR,
844 gettext("Configuration Error: More than one profile "
845 "found"));
846 MKERROR(LOG_ERR, errorp, NS_PARSE_ERR, strdup(errstr), NULL);
847 (void) __ns_ldap_freeError(&errorp);
848 return (NULL);
851 ptr = __s_api_create_config();
852 if (ptr == NULL)
853 return (NULL);
855 curr_ptr = __s_api_get_default_config();
856 if (curr_ptr == NULL) {
857 __s_api_destroy_config(ptr);
858 return (NULL);
861 /* Check to see if the profile is version 1 or version 2 */
862 prof_ver = 1;
863 entry = result->entry;
864 for (l = 0; l < entry->attr_count; l++) {
865 attr = entry->attr_pair[l];
867 attrname = attr->attrname;
868 if (attrname == NULL)
869 continue;
870 if (strcasecmp(attrname, "objectclass") == 0) {
871 for (m = 0; m < attr->value_count; m++) {
872 if (strcasecmp(_PROFILE2_OBJECTCLASS,
873 attr->attrvalue[m]) == 0) {
874 prof_ver = 2;
875 break;
880 /* update the configuration to accept v1 or v2 attributes */
881 if (prof_ver == 1) {
882 (void) strcpy(val, NS_LDAP_VERSION_1);
883 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P,
884 val, &error);
885 } else {
886 (void) strcpy(val, NS_LDAP_VERSION_2);
887 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P,
888 val, &error);
891 for (l = 0; l < entry->attr_count; l++) {
892 attr = entry->attr_pair[l];
894 attrname = attr->attrname;
895 if (attrname == NULL)
896 continue;
897 if (__s_api_get_profiletype(attrname, &index) != 0)
898 continue;
900 attrval = attr->attrvalue;
901 switch (index) {
902 case NS_LDAP_SEARCH_DN_P:
903 case NS_LDAP_SERVICE_SEARCH_DESC_P:
904 case NS_LDAP_ATTRIBUTEMAP_P:
905 case NS_LDAP_OBJECTCLASSMAP_P:
906 case NS_LDAP_SERVICE_CRED_LEVEL_P:
907 case NS_LDAP_SERVICE_AUTH_METHOD_P:
908 /* Multiple Value - insert 1 at a time */
909 for (m = 0; m < attr->value_count; m++) {
910 (void) __ns_ldap_setParamValue(ptr, index,
911 attrval[m], &error);
913 break;
914 default:
915 (void) memset((void *)&buffer, 0, sizeof (LineBuf));
917 /* Single or Multiple Value */
918 for (m = 0; m < attr->value_count; m++) {
919 sepstr = NULL;
920 if (m != attr->value_count - 1) {
921 sepstr = SPACESEP;
923 if (__print2buf(&buffer, attrval[m], sepstr))
924 goto makeconfigerror;
926 (void) __ns_ldap_setParamValue(ptr, index, buffer.str,
927 &error);
928 if (buffer.len > 0) {
929 free(buffer.str);
930 buffer.len = 0;
932 break;
935 if (ptr->version != NS_LDAP_V1) {
936 ParamIndexType i;
937 if (curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_ptype == CHARPTR) {
938 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_BINDDN_P,
939 curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_pc,
940 &error);
942 if (curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ptype ==
943 CHARPTR) {
944 (void) __ns_ldap_setParamValue(ptr,
945 NS_LDAP_BINDPASSWD_P,
946 curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_pc,
947 &error);
949 i = NS_LDAP_ENABLE_SHADOW_UPDATE_P;
950 if (curr_ptr->paramList[i].ns_ptype == INT) {
951 char *valt;
952 valt = __s_get_shadowupdate_name(
953 curr_ptr->paramList[i].ns_i);
954 (void) __ns_ldap_setParamValue(ptr, i, valt, &error);
956 if (curr_ptr->paramList[NS_LDAP_ADMIN_BINDDN_P].ns_ptype ==
957 CHARPTR) {
958 (void) __ns_ldap_setParamValue(ptr,
959 NS_LDAP_ADMIN_BINDDN_P,
960 curr_ptr->paramList[NS_LDAP_ADMIN_BINDDN_P].ns_pc,
961 &error);
963 if (curr_ptr->paramList[NS_LDAP_ADMIN_BINDPASSWD_P].ns_ptype ==
964 CHARPTR) {
965 (void) __ns_ldap_setParamValue(ptr,
966 NS_LDAP_ADMIN_BINDPASSWD_P,
967 curr_ptr->
968 paramList[NS_LDAP_ADMIN_BINDPASSWD_P].ns_pc,
969 &error);
971 if (curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_ptype ==
972 CHARPTR) {
973 (void) __ns_ldap_setParamValue(ptr,
974 NS_LDAP_HOST_CERTPATH_P,
975 curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_pc,
976 &error);
979 __s_api_release_config(curr_ptr);
980 return (ptr);
982 makeconfigerror:
983 if (buffer.len > 0)
984 free(buffer.str);
986 __s_api_debug_pause(LOG_ERR, NS_PARSE_ERR,
987 "__ns_ldap_make_config: Not enough memory");
988 return (NULL);
992 * Download a profile into our internal structure. The calling application
993 * needs to DumpConfig() to save the information to NSCONFIGFILE and NSCREDFILE
994 * if desired.
997 __ns_ldap_download(const char *profile, char *addr, char *baseDN,
998 ns_ldap_error_t **errorp)
1000 char filter[BUFSIZE];
1001 int rc;
1002 ns_ldap_result_t *result = NULL;
1003 ns_config_t *ptr = NULL;
1004 ns_config_t *new_ptr = NULL;
1005 char errstr[MAXERROR];
1007 *errorp = NULL;
1008 if (baseDN == NULL)
1009 return (NS_LDAP_INVALID_PARAM);
1011 ptr = __s_api_get_default_config();
1012 if (ptr == NULL) {
1013 (void) snprintf(errstr, sizeof (errstr),
1014 gettext("No configuration information available."));
1015 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
1016 NULL);
1017 return (NS_LDAP_CONFIG);
1020 rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SEARCH_BASEDN_P, baseDN,
1021 errorp);
1022 if (rc != NS_LDAP_SUCCESS) {
1023 __s_api_release_config(ptr);
1024 return (rc);
1027 rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SERVERS_P, addr, errorp);
1028 __s_api_release_config(ptr);
1029 if (rc != NS_LDAP_SUCCESS)
1030 return (rc);
1032 (void) snprintf(filter, sizeof (filter), _PROFILE_FILTER,
1033 _PROFILE1_OBJECTCLASS, _PROFILE2_OBJECTCLASS, profile);
1034 rc = __ns_ldap_list(_PROFILE_CONTAINER, (const char *)filter,
1035 NULL, NULL, NULL, 0, &result, errorp, NULL, NULL);
1037 if (rc != NS_LDAP_SUCCESS)
1038 return (rc);
1040 new_ptr = __ns_ldap_make_config(result);
1041 (void) __ns_ldap_freeResult(&result);
1043 if (new_ptr == NULL)
1044 return (NS_LDAP_OP_FAILED);
1046 rc = __s_api_crosscheck(new_ptr, errstr, B_FALSE);
1047 if (rc != NS_LDAP_SUCCESS) {
1048 __s_api_destroy_config(new_ptr);
1049 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
1050 NULL);
1051 return (NS_LDAP_CONFIG);
1054 __s_api_init_config(new_ptr);
1055 return (rc);
1059 * **************************************************************
1060 * Configuration Printing Routines
1061 * **************************************************************
1065 * Yes the use of stdio is okay here because all we are doing is sending
1066 * output to stdout. This would not be necessary if we could get to the
1067 * configuration pointer outside this file.
1069 ns_ldap_error_t *
1070 __ns_ldap_print_config(int verbose)
1072 ns_config_t *ptr;
1073 char errstr[MAXERROR];
1074 ns_ldap_error_t *errorp;
1075 char *str;
1076 int i;
1078 ptr = __s_api_get_default_config();
1079 if (ptr == NULL) {
1080 errorp = __ns_ldap_LoadConfiguration();
1081 if (errorp != NULL)
1082 return (errorp);
1083 ptr = __s_api_get_default_config();
1084 if (ptr == NULL) {
1085 (void) snprintf(errstr, sizeof (errstr),
1086 gettext("No configuration information."));
1087 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
1088 strdup(errstr), NULL);
1089 return (errorp);
1093 if (verbose && (ptr->domainName != NULL)) {
1094 (void) fputs("ptr->domainName ", stdout);
1095 (void) fputs(ptr->domainName, stdout);
1096 (void) putchar('\n');
1098 /* For each parameter - construct value */
1099 for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
1101 * Version 1 skipped this entry because:
1103 * don't print default cache TTL for now since
1104 * we don't store it in the ldap_client_file.
1106 if ((i == NS_LDAP_CACHETTL_P) && (ptr->version == NS_LDAP_V1))
1107 continue;
1109 /* the credential for shadow update is not to be exposed */
1110 if (i == NS_LDAP_ADMIN_BINDDN_P ||
1111 i == NS_LDAP_ADMIN_BINDPASSWD_P)
1112 continue;
1114 str = __s_api_strValue(ptr, i, NS_FILE_FMT);
1115 if (str == NULL)
1116 continue;
1117 if (verbose)
1118 (void) putchar('\t');
1119 (void) fprintf(stdout, "%s\n", str);
1120 free(str);
1123 __s_api_release_config(ptr);
1124 return (NULL);