[Fedora-directory-commits] adminutil/lib/libadminutil acclanglist.c, NONE, 1.1 admutil.c, 1.6, 1.7 admutil_pvt.h, 1.2, 1.3 dbtadmutil.h, 1.1.1.1, 1.2 distadm.c, 1.2, 1.3 errRpt.c, 1.2, 1.3 form_post.c, 1.3, 1.4 libadminutil.properties, 1.1.1.1, 1.2 psetc.c, 1.3, 1.4 resource.c, 1.1.1.1, 1.2 srvutil.c, 1.2, 1.3 uginfo.c, 1.3, 1.4

Richard Allen Megginson (rmeggins) fedora-directory-commits at redhat.com
Wed Apr 4 19:37:43 UTC 2007


Author: rmeggins

Update of /cvs/dirsec/adminutil/lib/libadminutil
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv30346/adminutil/lib/libadminutil

Modified Files:
	admutil.c admutil_pvt.h dbtadmutil.h distadm.c errRpt.c 
	form_post.c libadminutil.properties psetc.c resource.c 
	srvutil.c uginfo.c 
Added Files:
	acclanglist.c 
Log Message:
Resolves: bug 234420
Bug Description: adminutil: Use FHS paths and general code cleanup
Reviewed by: nkinder (Thanks!)
Fix Description:
1) Added a propertydir parameter to Makefile.am.  This is where the .res files go.  This also gets baked into the code so that the library knows where to find them.
2) The icu code expects the .res files to be in a packagename directory - packagename/foo.res not packagename_foo.res.  I don't know how this ever worked.  I also added en_US.res and en.res - icu recommends having the actual locale file rather than just falling back to the default root.res - see http://icu-project.org/userguide/ResourceManagement.html
3) There was quite a bit of dead code that I got rid of
4) Fixed many compiler warnings
5) There were quite a few memory leaks.  The biggest one was probably in psetDelete, which did not actually delete the pset.  Another one was the resource string handling - this returns malloc'd memory, and was never freed.  I added the option to pass in a static sized buffer to hold the resource string - this may be truncated but we usually won't care.  There were several places where the code was calling PR_Free on a data structure pointer - doing a "shallow" free rather than a "deep" free of all of the pointers in the data structure.
6) I merged in configuration from dbswitch.conf and other config files so that we could get rid of them and just have adm.conf.  We'll have to take care of this during migration.
Platforms tested: RHEL4, FC6
Flag Day: no
Doc impact: no



--- NEW FILE acclanglist.c ---
/** BEGIN COPYRIGHT BLOCK
 * This Program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; version 2 of the License.
 * 
 * This Program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA.
 * 
 * In addition, as a special exception, Red Hat, Inc. gives You the additional
 * right to link the code of this Program with code not covered under the GNU
 * General Public License ("Non-GPL Code") and to distribute linked combinations
 * including the two, subject to the limitations in this paragraph. Non-GPL Code
 * permitted under this exception must only link to the code of this Program
 * through those well defined interfaces identified in the file named EXCEPTION
 * found in the source code files (the "Approved Interfaces"). The files of
 * Non-GPL Code may instantiate templates or use macros or inline functions from
 * the Approved Interfaces without causing the resulting work to be covered by
 * the GNU General Public License. Only Red Hat, Inc. may make changes or
 * additions to the list of Approved Interfaces. You must obey the GNU General
 * Public License in all respects for all of the Program code and other code used
 * in conjunction with the Program except the Non-GPL Code covered by this
 * exception. If you modify this file, you may extend this exception to your
 * version of the file, but you are not obligated to do so. If you do not wish to
 * provide this exception without modification, you must delete this exception
 * statement from your version and license this file solely under the GPL without
 * exception. 
 * 
 * 
 * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * END COPYRIGHT BLOCK **/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#include "libadminutil/resource.h"

/*
 *      Accept-Language = "Accept-Language" ":"
 *                        1#( language-range [ ";" "q" "=" qvalue ] )
 *      language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
 *
 *      NLS_AccLangList() assumes that "Accept-Language:" has already
 *      been stripped off. It takes as input
 * 
 *      1#( ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) [ ";" "q" "=" qvalue ] )
 *
 *      and returns a list of languages, ordered by qvalues, in
 *      the array NLS_ACCEPT_LANGUAGE_LIST. 
 *      
 *      If there are to many languages (>NLS_MAX_ACCEPT_LANGUAGE) the excess
 *      is ignored. If the language-range is too long (>NLS_MAX_ACCEPT_LENGTH),
 *      the language-range is ignored. In these cases, NLS_AccLangList()
 *      will quietly return, perhaps with numLang = 0. numLang is
 *      returned by the function.  
 */


static size_t
AcceptLangList(const char* AcceptLanguage,
               ACCEPT_LANGUAGE_LIST AcceptLanguageList)
{
  char* input;
  char* cPtr;
  char* cPtr1;
  char* cPtr2;
  int i;
  int j;
  int countLang = 0;
  
  input = strdup(AcceptLanguage);
  if (input == (char*)NULL){
	  return 0;
  }

  cPtr1 = input-1;
  cPtr2 = input;

  /* put in standard form */
  while (*(++cPtr1)) {
    if      (isalpha(*cPtr1))  *cPtr2++ = tolower(*cPtr1); /* force lower case */
    else if (isspace(*cPtr1));                             /* ignore any space */
    else if (*cPtr1=='-')      *cPtr2++ = '_';             /* "-" -> "_"       */
    else if (*cPtr1=='*');                                 /* ignore "*"       */
    else                       *cPtr2++ = *cPtr1;          /* else unchanged   */
  }
  *cPtr2 = '\0';

  countLang = 0;

  if (strchr(input,';')) {
    /* deal with the quality values */

    float qvalue[MAX_ACCEPT_LANGUAGE];
    float qSwap;
    float bias = 0.0f;
    char* ptrLanguage[MAX_ACCEPT_LANGUAGE];
    char* ptrSwap;

    cPtr = strtok(input,",");
    while (cPtr) {
      qvalue[countLang] = 1.0f;
      if ((cPtr1 = strchr(cPtr,';'))) {
        sscanf(cPtr1,";q=%f",&qvalue[countLang]);
        *cPtr1 = '\0';
      }
      if (strlen(cPtr)<MAX_ACCEPT_LENGTH) {     /* ignore if too long */
        qvalue[countLang] -= (bias += 0.0001f); /* to insure original order */
        ptrLanguage[countLang++] = cPtr;
        if (countLang>=MAX_ACCEPT_LANGUAGE) break; /* quit if too many */
      }
      cPtr = strtok(NULL,",");
    }

    /* sort according to decending qvalue */
    /* not a very good algorithm, but count is not likely large */
    for ( i=0 ; i<countLang-1 ; i++ ) {
      for ( j=i+1 ; j<countLang ; j++ ) {
        if (qvalue[i]<qvalue[j]) {
          qSwap     = qvalue[i];
          qvalue[i] = qvalue[j];
          qvalue[j] = qSwap;
          ptrSwap        = ptrLanguage[i];
          ptrLanguage[i] = ptrLanguage[j];
          ptrLanguage[j] = ptrSwap;
        }
      }
    }
    for ( i=0 ; i<countLang ; i++ ) {
      strcpy(AcceptLanguageList[i],ptrLanguage[i]);
    }

  } else {
    /* simple case: no quality values */

    cPtr = strtok(input,",");
    while (cPtr) {
      if (strlen(cPtr)<MAX_ACCEPT_LENGTH) {        /* ignore if too long */
        strcpy(AcceptLanguageList[countLang++],cPtr);
        if (countLang>=MAX_ACCEPT_LANGUAGE) break; /* quit if too many */
      }
      cPtr = strtok(NULL,",");
    }
  }

  free(input);

  return countLang;
}

/*
 *   Get prioritized locale list from NLS_AcceptLangList 
 *      
 *   Add additonal language to the list for fallback if locale 
 *   name is language_region
 *
 */


PR_IMPLEMENT( int )
XP_AccLangList(char* AcceptLanguage,
               ACCEPT_LANGUAGE_LIST AcceptLanguageList)
{
	int i;
	int n;
	char *defaultLanguage = "en";
	ACCEPT_LANGUAGE_LIST curLanguageList;
	int index = 0;
	char lang[3];
	int k;

	n = AcceptLangList(AcceptLanguage, curLanguageList);

	if (n == 0)
		return 0;

	memset(lang, 0, 3);
	for (i = 0; i < n; i++) {
		if (*lang && (strncmp(lang, curLanguageList[i], 2) != 0)) {
			/* add lang if current language is the last occurence in the list */
			for (k = i+1; (k < n) && strncmp(curLanguageList[k],lang,2); k++);

			if (k == n) {
				strcpy(AcceptLanguageList[index++], lang);
				*lang = '\0';
			}
		}

		strcpy(AcceptLanguageList[index++], curLanguageList[i]);

        /* Add current language for future appending.,make sure it's not on list */
        if ((strlen(curLanguageList[i]) > 2) && (curLanguageList[i][2] == '_')) {
		    strncpy(lang, curLanguageList[i], 2);
			lang[sizeof(lang)-1] = 0;
	        for (k = 0; (k < index) && strcmp(AcceptLanguageList[k], lang); k++);

	        if (k != index)   lang[0] = '\0';
        }
	}

	if (lang[0] != '\0')
		strcpy(AcceptLanguageList[index++], lang);	/* add new lang */

	/* Append defaultLanguage if it's not in the list */
	for (i = 0; (i < index) && strcmp(AcceptLanguageList[i], defaultLanguage); i++);

	if (i == index)
		strcpy(AcceptLanguageList[index++], defaultLanguage);

	return index;
}


Index: admutil.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/admutil.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- admutil.c	3 Nov 2006 17:41:05 -0000	1.6
+++ admutil.c	4 Apr 2007 19:37:36 -0000	1.7
@@ -24,6 +24,7 @@
 #include <ctype.h>
 #include "version.h"
 #include "admutil_pvt.h"
+#include "libadminutil/distadm.h"
 
 #ifdef XP_WIN32
 #define strcasecmp stricmp
@@ -53,6 +54,46 @@
 #define FILE_PATHSEP '/'
 #endif
 
+/* returns true if the given path is a valid file, false otherwise */
+static int
+is_file_ok(const char *path)
+{
+	PRFileInfo prinfo;
+	int ret = 0;
+
+	if (path && *path &&
+		(PR_SUCCESS == PR_GetFileInfo(path, &prinfo)) &&
+		prinfo.type == PR_FILE_FILE) {
+		ret = 1;
+	}
+
+	return ret;
+}
+
+/* returns full path and file name if the file was found somewhere, false otherwise */
+static char *
+find_file_in_paths(
+	const char *filename, /* the base filename to look for */
+	const char *path /* path given by caller */
+)
+{
+	char *retval = NULL;
+    char *adminutilConfDir = getenv(ADMINUTIL_CONFDIR_ENV_VAR);
+
+	/* try given path */
+	retval = PR_smprintf("%s/%s", path, filename);
+    if (!is_file_ok(retval) && adminutilConfDir) {
+        PR_smprintf_free(retval);
+        retval = PR_smprintf("%s/%s", adminutilConfDir, filename);
+        if (!is_file_ok(retval)) {
+            PR_smprintf_free(retval);
+            retval = NULL;
+        }
+    }
+
+	return retval;
+}
+
 /* Copy from libadmin.....  */
 static unsigned char uuset[] = {
 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
@@ -187,11 +228,17 @@
   NameType name;
   AttrNameList nlptr = nl;
   if (nl) {
-    while (name = *nlptr++) PR_Free(name);
+    while ((name = *nlptr++)) PR_Free(name);
     PR_Free(nl);
   }
 }
 
+PR_IMPLEMENT(void)
+deleteValue(ValueType val)
+{
+    admutil_strsFree((char **)val);
+}
+
 PR_IMPLEMENT(AttributeList)
 createAttributeList(int entries)
 {
@@ -238,7 +285,7 @@
   AttributePtr attr;
   AttributeList nvlptr = nvl;
   if (nvl) {
-    while (attr = *nvlptr++) {
+    while ((attr = *nvlptr++)) {
       if (attr->attrName) PR_Free(attr->attrName);
       if (attr->attrVal) admutil_strsFree(attr->attrVal);
       PR_Free(attr);
@@ -400,7 +447,7 @@
   while (node) {
     nextptr = node->next;
     if (node->name) PR_Free (node->name);
-    if (node->dflag) PR_Free (node->val);
+    if (node->dflag) deleteValue ((ValueType)node->val);
     PR_Free (node);
     node= nextptr;
   }
@@ -504,7 +551,7 @@
   if (!strcasecmp(list->name, name)) {
     nextptr = list->next;
     if (list->name) PR_Free(list->name);
-    if (list->dflag) PR_Free (list->val);
+    if (list->dflag) deleteValue ((ValueType)list->val);
     PR_Free(list);
     return nextptr;
   }
@@ -514,7 +561,7 @@
     if (!strcasecmp(node->next->name, name)) {
       nextptr = node->next->next;
       if (node->next->name) PR_Free (node->next->name);
-      if (node->next->dflag) PR_Free (node->next->val);
+      if (node->next->dflag) deleteValue ((ValueType)node->next->val);
       PR_Free (node->next);
       node->next = nextptr;
       return list;
@@ -554,7 +601,7 @@
   if (!list) return;
 
   while (node) {
-    admutil_strsFree((ValueType)(node->val));
+    deleteValue(node->val);
     node = node->next;
   }
 
@@ -591,7 +638,7 @@
   char           *attrName, *nodeName;
   ListNodePtr     resultList = NULL, nodePtr, attrPtr;
 
-  while (nv = *nvlptr++) {
+  while ((nv = *nvlptr++)) {
     PR_snprintf(namebuf, sizeof(namebuf), "%s", nv->attrName);
     attrName = strrchr(namebuf, '.');
     if (!attrName) {
@@ -685,7 +732,7 @@
 {
   TreeNodePtr  target;
 
-  if (target = treeFindNode(root, name) ) return valListConvert(target->val);
+  if ((target = treeFindNode(root, name))) return valListConvert(target->val);
   else return NULL;
 }
 
@@ -700,7 +747,7 @@
 
   if (vals) {
     val = PL_strdup(vals[0]);
-    admutil_strsFree(vals);
+    deleteValue(vals);
     return val;
   }
   else return NULL;
@@ -866,7 +913,7 @@
   while (listPtr) {
     PR_snprintf(valBuf, sizeof(valBuf), "%s", listPtr->name);
     sptr = valBuf;
-    while (cptr = strchr(sptr, '\n')) {
+    while ((cptr = strchr(sptr, '\n'))) {
       *cptr++ = '\0';
       fprintf(fstream, "%s\n ", sptr);
       sptr=cptr;
@@ -886,7 +933,7 @@
   char        linebuf[MAX_LEN], *name=NULL, *val=NULL;
   char        valBuf[BUFSIZ], *valptr = valBuf;
   int         valBuf_len = sizeof(valBuf);
-  TreeNodePtr rootNode = NULL, tmpNode = NULL;
+  TreeNodePtr rootNode = NULL;
 
   if (!fstream) return NULL;
   if (!errorcode) return NULL;
@@ -894,7 +941,7 @@
   valBuf[0] = '\0';
 
   while(1) {
-    switch(status = admutil_getline(fstream, MAX_LEN, lineno++, linebuf)) {
+    switch(status = admutil_getline(fstream, sizeof(linebuf), lineno++, linebuf)) {
     case -1:
       /* Error on reading, SET ERRORCODE */
       *errorcode = ADMUTIL_SYSTEM_ERR;
@@ -1028,7 +1075,7 @@
 {
   if (mod) {
     if (mod->mod_type) PR_Free ( mod->mod_type );
-    if (mod->mod_values) PR_Free (mod->mod_values);
+    if (mod->mod_values) admutil_strsFree (mod->mod_values);
     PR_Free( mod );
   }
 }
@@ -1040,7 +1087,7 @@
   LDAPMod** modsptr = mods;
 
   if (mods) {
-    while (mod = *modsptr++) deleteMod(mod);
+    while ((mod = *modsptr++)) deleteMod(mod);
     PR_Free(mods);
   }
 
@@ -1073,49 +1120,59 @@
     *u = *t;
 }
 
+/*
+ * Write the info back to its config file
+ */
+PR_IMPLEMENT(int)
+admldapWriteInfoFile(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  int errorcode = ADMUTIL_OP_OK;
+  FILE *fileStream = NULL;
+
+  if (admInfo && admInfo->configInfo && admInfo->configFilePath) {
+	if((fileStream = fopen(admInfo->configFilePath, "w")) == NULL) {
+	  /* Error open file  */
+		errorcode = ADMUTIL_SYSTEM_ERR;
+		goto done;
+	}
+	treeExport(fileStream, NULL, admInfo->configInfo);
+  }
+
+done:
+  if (fileStream) {
+	fclose(fileStream);
+  }
+  return errorcode;
+}
+
+/* This function is useful if you just want to read the adm.conf info
+   without opening an ldap connection
+*/
 PR_IMPLEMENT(AdmldapInfo) 
-admldapBuildInfoCbk(char* configRoot, char *(*cbk)(), int *errorcode)
+admldapBuildInfoOnly(char* configRoot, int *errorcode)
 {
   FILE           *fileStream;
-  char           *serverRoot = getenv("NETSITE_ROOT");
-  char           *sieDN = NULL, *siePasswd = NULL;
   AdmldapHdnlPtr admInfo = NULL;
   TreeNodePtr    configInfo = NULL;
-  char           path[PATH_MAX], ldapInfoPath[PATH_MAX], buf[MAX_LEN],
+  char           *path = NULL;
+  char           buf[MAX_LEN],
                  *name= NULL, *password=NULL;
-  char           *p;
-  int            status, ldapError;
-  char           *ldapurl, *tmpptr;
+  int            status;
   LDAPURLDesc    *ldapInfo;
-  int            secureLDAP = 0;
 
   *errorcode = ADMUTIL_OP_OK;
 
-  if (configRoot) {
-    PR_snprintf(path, sizeof(path), "%s%cadm.conf", configRoot, FILE_PATHSEP);
-    PR_snprintf(ldapInfoPath, sizeof(ldapInfoPath),
-                "%s%c..%c..%cshared%cconfig%cdbswitch.conf",
-                configRoot, FILE_PATHSEP, FILE_PATHSEP, FILE_PATHSEP, 
-                FILE_PATHSEP, FILE_PATHSEP);
-  }
-  else {
-    if (serverRoot) {
-      PR_snprintf(path, sizeof(path),
-                  "%s%cadmin-serv%cconfig%cadm.conf",
-                  serverRoot, FILE_PATHSEP, FILE_PATHSEP, FILE_PATHSEP);
-      PR_snprintf(ldapInfoPath, sizeof(ldapInfoPath),
-                  "%s%cshared%cconfig%cdbswitch.conf",
-                  serverRoot, FILE_PATHSEP, FILE_PATHSEP, FILE_PATHSEP);
-    }
-    else {
-      *errorcode = ADMUTIL_ENV_ERR;
-      return NULL;
-    }
+  path = find_file_in_paths("adm.conf", configRoot);
+  if (!path) {
+    *errorcode = ADMUTIL_ENV_ERR;
+	return NULL;
   }
 
   if((fileStream = fopen(path, "r")) == NULL) {
     /* Error open file  */
     *errorcode = ADMUTIL_SYSTEM_ERR;
+    PR_smprintf_free(path);
     return NULL;
   }
 
@@ -1128,7 +1185,8 @@
   if (!admInfo) { *errorcode = ADMUTIL_SYSTEM_ERR; return NULL; }
   memset(admInfo, '\0', sizeof(AdmldapHdnl));
 
-  admInfo->configFilePath = PL_strdup(path);
+  admInfo->configFilePath = path; /* hand off memory */
+  path = NULL;
   if (!admInfo->configFilePath) {
       PR_Free(admInfo);
       *errorcode = ADMUTIL_SYSTEM_ERR;
@@ -1137,62 +1195,104 @@
 
   admInfo->configInfo = configInfo;
 
-
-  if((fileStream = fopen(ldapInfoPath, "r")) == NULL) {
+  if (!(admInfo->serverDirectoryURL = treeFindValueAt(admInfo->configInfo, "ldapurl", 0))) { /* admInfo owns malloced memory now */
     /* Error open file  */
     *errorcode = ADMUTIL_SYSTEM_ERR;
     destroyAdmldap((AdmldapInfo)admInfo);
     return NULL;
   }
 
-  /* There is one line in dbswitch.conf, of the form:
-   *
-   * directory default ldap://skydome.mcom.com:5555/baseDN
-   */
-  p = fgets(ldapInfoPath, PATH_MAX, fileStream);
-  fclose(fileStream);
-
-  if (!p) {
+  if (ldap_url_parse(admInfo->serverDirectoryURL, &ldapInfo)) {
     *errorcode = ADMUTIL_SYSTEM_ERR;
-    destroyAdmldap((AdmldapInfo)admInfo);
     return NULL;
   }
 
-  if (tmpptr = strchr(p, '\n')) *tmpptr= '\0';
+  admInfo->ldapInfo = ldapInfo;
 
-  if ((ldapurl = strstr(p, "ldap")) == NULL) {
-    *errorcode = ADMUTIL_SYSTEM_ERR;
-    return NULL;
+  /* sieDN owns malloced memory returned by treeFindValueAt */
+  admInfo->sieDN = treeFindValueAt(admInfo->configInfo, "sie", 0);
+
+  /* Try to get local admin's name and password  */
+  path = find_file_in_paths("admpw", configRoot);
+  if (!path) {
+    *errorcode = ADMUTIL_ENV_ERR;
+    destroyAdmldap((AdmldapInfo)admInfo);
+	return NULL;
   }
 
-  admInfo->serverDirectoryURL = PL_strdup(ldapurl);
-  if (!admInfo->serverDirectoryURL) {
+  if((fileStream = fopen(path, "r")) == NULL) {
     /* Error open file  */
     *errorcode = ADMUTIL_SYSTEM_ERR;
+    PR_smprintf_free(path);
     destroyAdmldap((AdmldapInfo)admInfo);
     return NULL;
   }
 
-  if (ldap_url_parse(ldapurl, &ldapInfo)) {
+  switch(status = admutil_getline(fileStream, sizeof(buf), 1, buf)) {
+  case -1:
+    /* Error on reading, SET ERRORCODE */
     *errorcode = ADMUTIL_SYSTEM_ERR;
+    PR_smprintf_free(path);
+    destroyAdmldap((AdmldapInfo)admInfo);
+	fclose(fileStream);
     return NULL;
+    break;
+  case 1:
+    /* EOF */
+  default:
+    password = strchr(buf, ':');
+    *password++ = '\0';
+    while (*password) {
+      if (*password == ' ') password++;
+      else break;
+    }
+    
+    name = buf;
+    if (*password) {
+      *errorcode =  ADMUTIL_OP_OK;
+      admInfo->admpwFilePath = path; /* hand off memory */
+      path = NULL;
+      admInfo->localAdminName = PL_strdup(name);
+      admInfo->localAdminPassword = PL_strdup(password);
+    }
+    else {
+      *errorcode =  ADMUTIL_OP_FAIL;
+    }
+  }
+  fclose(fileStream);
+
+  PR_smprintf_free(path);
+
+  return (AdmldapInfo)admInfo;
+}
+
+PR_IMPLEMENT(AdmldapInfo) 
+admldapBuildInfoCbk(char* configRoot, char *(*cbk)(), int *errorcode)
+{
+  char           *siePasswd = NULL;
+  AdmldapHdnlPtr admInfo = NULL;
+  int            ldapError = LDAP_SUCCESS;
+  int            secureLDAP = 0;
+
+  *errorcode = ADMUTIL_OP_OK;
+  admInfo = (AdmldapHdnlPtr)admldapBuildInfoOnly(configRoot, errorcode);
+  if (*errorcode != ADMUTIL_OP_OK) {
+	  return (AdmldapInfo)admInfo;
   }
 
   /* returned value from ADM_Get... should NOT be freed */
   ADM_GetCurrentPassword(errorcode, &siePasswd); /* via PIPE */
 
-  if (ldapInfo->lud_options & LDAP_URL_OPT_SECURE) {
+  if (admldapGetSecurity((AdmldapInfo)admInfo)) {
     *errorcode = ADMUTIL_NO_SSL_SUPPORT;
     secureLDAP = 1;
   }
 
   if (!secureLDAP) {
-    admInfo->ldapHndl = ldap_init(ldapInfo->lud_host, ldapInfo->lud_port);
+    admInfo->ldapHndl = ldap_init(admInfo->ldapInfo->lud_host, admInfo->ldapInfo->lud_port);
   }
 
   /* authenticate to LDAP server*/
-  /* return value from treeFindValueAt should be freed */
-  sieDN = treeFindValueAt(admInfo->configInfo, "sie", 0);
 
   /*
    * Attempt to authenticate to the directory.  This code will retry
@@ -1222,7 +1322,7 @@
         }
 
         if (!secureLDAP) {
-          ldapError = ldap_simple_bind_s(admInfo->ldapHndl, sieDN, siePasswd);
+          ldapError = ldap_simple_bind_s(admInfo->ldapHndl, admInfo->sieDN, siePasswd);
           if (ldapError == LDAP_SUCCESS) break;
 
           /* Quit on errors other than password problems */
@@ -1266,71 +1366,12 @@
                              (void *)admInfo);
   }
 
-  if (sieDN != NULL) {
-      admInfo->sieDN=PL_strdup(sieDN);
-      /* return value from treeFindValueAt should be freed */
-      PR_Free(sieDN);
-  }
   if (siePasswd != NULL) {
       /* returned value from ADM_Get... should NOT be freed */
       admInfo->passwd=PL_strdup(siePasswd);
   }
 
-  admInfo->ldapInfo = ldapInfo;
-
-  /* Try to get local admin's name and password  */
-
-  if (configRoot) {
-    PR_snprintf(path, sizeof(path), "%s%cadmpw", configRoot, FILE_PATHSEP);
-  }
-  else {
-    if (!serverRoot) {
-      *errorcode = ADMUTIL_ENV_ERR;
-      destroyAdmldap((AdmldapInfo)admInfo);
-      return NULL;
-    }
-    PR_snprintf(path, sizeof(path), "%s%cadmin-serv%cconfig%cadmpw",
-                serverRoot, FILE_PATHSEP, FILE_PATHSEP, FILE_PATHSEP);
-  }
-
-  if((fileStream = fopen(path, "r")) == NULL) {
-    /* Error open file  */
-    *errorcode = ADMUTIL_SYSTEM_ERR;
-    destroyAdmldap((AdmldapInfo)admInfo);
-    return NULL;
-  }
-
-  switch(status = admutil_getline(fileStream, MAX_LEN, 1, buf)) {
-  case -1:
-    /* Error on reading, SET ERRORCODE */
-    *errorcode = ADMUTIL_SYSTEM_ERR;
-    destroyAdmldap((AdmldapInfo)admInfo);
-    return NULL;
-    break;
-  case 1:
-    /* EOF */
-  default:
-    password = strchr(buf, ':');
-    *password++ = '\0';
-    while (*password) {
-      if (*password == ' ') password++;
-      else break;
-    }
-    
-    name = buf;
-    if (*password) {
-      *errorcode =  ADMUTIL_OP_OK;
-      admInfo->admpwFilePath = PL_strdup(path);
-      admInfo->localAdminName = PL_strdup(name);
-      admInfo->localAdminPassword = PL_strdup(password);
-    }
-    else {
-      *errorcode =  ADMUTIL_OP_FAIL;
-    }
-    fclose(fileStream);
-
-    return (AdmldapInfo)admInfo;
-  }
+  return (AdmldapInfo)admInfo;
 }
 
 static char *
@@ -1358,10 +1399,6 @@
       PR_Free(admInfo->configFilePath); 
       admInfo->configFilePath=NULL; 
     }
-    if (admInfo->ldapFilePath) { 
-      PR_Free(admInfo->ldapFilePath);
-      admInfo->ldapFilePath = NULL;
-    }
     if (admInfo->serverDirectoryURL) {
       PR_Free(admInfo->serverDirectoryURL);
       admInfo->serverDirectoryURL = NULL; 
@@ -1383,6 +1420,11 @@
         PR_Free(admInfo->sieDN);
         admInfo->sieDN = NULL;
       }
+    if (admInfo->userDN)
+      {
+        PR_Free(admInfo->userDN);
+        admInfo->userDN = NULL;
+      }
     if (admInfo->passwd)
       {
         PR_Free(admInfo->passwd);
@@ -1445,25 +1487,29 @@
 }
 
 PR_IMPLEMENT(char*)
-admldapGetCertDBFile(AdmldapInfo info)
+admldapGetSecurityDir(AdmldapInfo info)
 {
   AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
-  char          *certdb;
+  char          *securitydir;
 
-  certdb = treeFindValueAt(admInfo->configInfo, "certDBFile", 0);
-  if (!certdb) return NULL;
-  else return certdb;
+  securitydir = treeFindValueAt(admInfo->configInfo, "securitydir", 0);
+  if (!securitydir) return NULL;
+  else return securitydir;
 }
 
-PR_IMPLEMENT(char*)
-admldapGetKeyDBFile(AdmldapInfo info)
+PR_IMPLEMENT(int)
+admldapSetSecurityDir(AdmldapInfo info, const char *securityDir)
 {
   AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
-  char          *keydb;
+  int removeFlag = 0;
 
-  keydb = treeFindValueAt(admInfo->configInfo, "keyDBFile", 0);
-  if (!keydb) return NULL;
-  else return keydb;
+  if (securityDir) {
+	/* remove old one */
+	treeRemoveNode(admInfo->configInfo, "securitydir", &removeFlag);
+	treeAddNameValue(admInfo->configInfo, "securitydir", (char *)securityDir);
+  }
+
+  return ADMUTIL_OP_OK;
 }
 
 PR_IMPLEMENT(char*)
@@ -1477,11 +1523,28 @@
   else return ldapSIEDN;
 }
 
+PR_IMPLEMENT(int)
+admldapSetSIEDN(AdmldapInfo info, const char *sieDN)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  int removeFlag = 0;
+
+  if (sieDN) {
+	/* remove old one */
+	PL_strfree(admInfo->sieDN);
+	treeRemoveNode(admInfo->configInfo, "sie", &removeFlag);
+	/* add new one */
+	admInfo->sieDN = PL_strdup(sieDN);
+	treeAddNameValue(admInfo->configInfo, "sie", (char *)sieDN);
+  }
+
+  return ADMUTIL_OP_OK;
+}
+
 PR_IMPLEMENT(char*)
 admldapGetSIEPWD(AdmldapInfo info)
 {
   AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
-  char          *password = NULL;
   if(admInfo->passwd)
     return PL_strdup(admInfo->passwd);
   else {
@@ -1504,6 +1567,64 @@
 
 }
 
+PR_IMPLEMENT(int)
+admldapSetISIEDN(AdmldapInfo info, const char *isieDN)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  int removeFlag = 0;
+
+  if (isieDN) {
+	/* remove old one */
+	treeRemoveNode(admInfo->configInfo, "isie", &removeFlag);
+	treeAddNameValue(admInfo->configInfo, "isie", (char *)isieDN);
+  }
+
+  return ADMUTIL_OP_OK;
+}
+
+PR_IMPLEMENT(char *)
+admldapGetDirectoryURL(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+
+  return PL_strdup(admInfo->serverDirectoryURL);
+}
+
+PR_IMPLEMENT(int)
+admldapSetDirectoryURL(AdmldapInfo info, const char *ldapurl)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  LDAPURLDesc    *ldapInfo;
+  int errorcode = ADMUTIL_OP_OK;
+  int removeFlag = 0;
+
+  if (!ldapurl || ldap_url_parse(ldapurl, &ldapInfo)) {
+	/* if the given url is not valid, don't do anything, just return an error */
+    errorcode = ADMUTIL_SYSTEM_ERR;
+    goto done;
+  }
+
+  /* The url is stored in 3 places in 3 different formats:
+	 1 - the serverDirectoryURL string
+	 2 - parsed in the ldapInfo structure
+	 3 - the "ldapurl" key in the configinfo
+  */
+  /* first, free the old values */
+  if (admInfo->ldapInfo) {
+    ldap_free_urldesc(admInfo->ldapInfo);
+  }
+  PL_strfree(admInfo->serverDirectoryURL);
+  treeRemoveNode(admInfo->configInfo, "ldapurl", &removeFlag);
+
+  /* set the new values */
+  admInfo->serverDirectoryURL = PL_strdup(ldapurl);
+  admInfo->ldapInfo = ldapInfo;
+  treeAddNameValue(admInfo->configInfo, "ldapurl", (char *)ldapurl);
+
+done:
+  return errorcode;
+}
+
 PR_IMPLEMENT(void)
 admldapSetLDAPHndl(AdmldapInfo info, LDAP *ld)
 {
@@ -1521,12 +1642,100 @@
   return admInfo->ldapHndl;
 }
 
-PR_IMPLEMENT(char *)
-admldapGetDirectoryURL(AdmldapInfo info)
+PR_IMPLEMENT(char*)
+admldapGetSysUser(AdmldapInfo info)
 {
   AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  char          *sysuser = NULL;
 
-  return PL_strdup(admInfo->serverDirectoryURL);
+  sysuser = treeFindValueAt(admInfo->configInfo, "sysuser", 0);
+  if (!sysuser) return NULL;
+  else  return sysuser;
+
+}
+
+PR_IMPLEMENT(char*)
+admldapGetSysGroup(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  char          *sysgroup = NULL;
+
+  sysgroup = treeFindValueAt(admInfo->configInfo, "sysgroup", 0);
+  if (!sysgroup) return NULL;
+  else  return sysgroup;
+
+}
+
+PR_IMPLEMENT(char*)
+admldapGetAdminDomain(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  char          *admindomain = NULL;
+
+  admindomain = treeFindValueAt(admInfo->configInfo, "AdminDomain", 0);
+  if (!admindomain) return NULL;
+  else  return admindomain;
+
+}
+
+PR_IMPLEMENT(char*)
+admldapGetExpressRefreshRate(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  char          *expressrefreshrate = NULL;
+
+  expressrefreshrate = treeFindValueAt(admInfo->configInfo, "ExpressRefreshRate", 0);
+  if (!expressrefreshrate) return NULL;
+  else  return expressrefreshrate;
+
+}
+
+PR_IMPLEMENT(char*)
+admldapGetExpressCGITimeout(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  char          *expresscgitimeout = NULL;
+
+  expresscgitimeout = treeFindValueAt(admInfo->configInfo, "ExpressCGITimeout", 0);
+  if (!expresscgitimeout) return NULL;
+  else  return expresscgitimeout;
+
+}
+
+PR_IMPLEMENT(char*)
+admldapGetLdapStart(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+  char          *ldapstart = NULL;
+
+  ldapstart = treeFindValueAt(admInfo->configInfo, "ldapStart", 0);
+  if (!ldapstart) return NULL;
+  else  return ldapstart;
+
+}
+
+PR_IMPLEMENT(char*)
+admldapGetConfigFileName(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+
+  return PL_strdup(admInfo->configFilePath);
+}
+
+PR_IMPLEMENT(char*)
+admldapGetAdmpwFilePath(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+
+  return PL_strdup(admInfo->admpwFilePath);
+}
+
+PR_IMPLEMENT(char*)
+admldapGetLocalAdminName(AdmldapInfo info)
+{
+  AdmldapHdnlPtr admInfo = (AdmldapHdnlPtr)info;
+
+  return PL_strdup(admInfo->localAdminName);
 }
 
 PR_IMPLEMENT(char *)
@@ -1570,52 +1779,50 @@
 done:
   PR_smprintf_free(uidFilter);
   if (baseDN) PR_Free(baseDN);
-  if (userDN) {
+  if (userDN && (userDN != admInfo->userDN)) {
+    PL_strfree(admInfo->userDN); /* free old one, if any */
     admInfo->userDN = userDN;
   } else {
     userDN = treeFindValueAt(admInfo->configInfo, "userdn", 0);
 	if (userDN) {
-      admInfo->userDN = PL_strdup(userDN);
+      admInfo->userDN = userDN;
     } else {
       admInfo->userDN = NULL;
     }
   }
-  return admInfo->userDN;
+  return admInfo->userDN ? PL_strdup(admInfo->userDN) : NULL;
 }
 
 PR_IMPLEMENT(char*)
 admGetLocalAdmin(char* configRoot, int *errorcode)
 {
   FILE          *fileStream;
-  char          *serverRoot = getenv("NETSITE_ROOT");
-  TreeNodePtr   admInfo = NULL;
-  char          path[PATH_MAX], buf[MAX_LEN], *name;
+  char          *path = NULL, buf[MAX_LEN], *name = NULL;
   int           status;
 
   *errorcode = ADMUTIL_OP_OK;
 
-  if (configRoot) {
-    PR_snprintf(path, sizeof(path), "%s%cadmpw", configRoot, FILE_PATHSEP);
-  }
-  else {
-    if (!serverRoot) {
+  /* Try to get local admin's name and password  */
+  path = find_file_in_paths("admpw", configRoot);
+  if (!path) {
       *errorcode = ADMUTIL_ENV_ERR;
       return NULL;
-    }
-    PR_snprintf(path, sizeof(path), "%s%cadmin-serv%cconfig%cadmpw",
-                serverRoot, FILE_PATHSEP, FILE_PATHSEP, FILE_PATHSEP);
   }
 
   if((fileStream = fopen(path, "r")) == NULL) {
     /* Error open file  */
     *errorcode = ADMUTIL_SYSTEM_ERR;
+    PR_smprintf_free(path);
     return NULL;
   }
+  PR_smprintf_free(path);
+  path = NULL;
 
-  switch(status = admutil_getline(fileStream, MAX_LEN, 1, buf)) {
+  switch(status = admutil_getline(fileStream, sizeof(buf), 1, buf)) {
   case -1:
     /* Error on reading, SET ERRORCODE */
     *errorcode = ADMUTIL_SYSTEM_ERR;
+    fclose(fileStream);
     return NULL;
     break;
   case 1:
@@ -1626,6 +1833,7 @@
     break;
     */
   default:
+    fclose(fileStream);
     name = strtok(buf, ":");
     if (!name) {
       *errorcode =  ADMUTIL_OP_FAIL;


Index: admutil_pvt.h
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/admutil_pvt.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- admutil_pvt.h	11 May 2006 23:30:31 -0000	1.2
+++ admutil_pvt.h	4 Apr 2007 19:37:36 -0000	1.3
@@ -158,7 +158,6 @@
 typedef struct _AdmldapHdnl {
   char         *configFilePath;
   TreeNodePtr  configInfo;
-  char         *ldapFilePath;
   char         *serverDirectoryURL;
   LDAPURLDesc  *ldapInfo;
   LDAP         *ldapHndl;


Index: dbtadmutil.h
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/dbtadmutil.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- dbtadmutil.h	20 Jul 2005 22:51:32 -0000	1.1.1.1
+++ dbtadmutil.h	4 Apr 2007 19:37:36 -0000	1.2
@@ -20,7 +20,7 @@
 #include "libadminutil/resource.h"
 #define resource_key(a,b)   a b
 
-#define RESOURCE_FILE "libadminutil"
+#define RESOURCE_FILE PACKAGE_NAME
 
 
   /*extracted from errRpt.c*/
@@ -62,6 +62,7 @@
 #define DBT_pset_ILLEGAL_OP 		resource_key(RESOURCE_FILE, "44")
 #define DBT_pset_NOT_IMPLEMENT 		resource_key(RESOURCE_FILE, "45")
 #define DBT_pset_UNKNOWN_ERROR_NO       resource_key(RESOURCE_FILE, "46")
+#define DBT_pset_ATTR_NOT_ALLOWED       resource_key(RESOURCE_FILE, "47")
 
   /*extracted from form_post.c  */
 #define DBT_formPost_Browser_err 	resource_key(RESOURCE_FILE, "61")


Index: distadm.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/distadm.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- distadm.c	29 Sep 2005 22:10:15 -0000	1.2
+++ distadm.c	4 Apr 2007 19:37:36 -0000	1.3
@@ -26,6 +26,9 @@
 #ifdef XP_WIN32
 #include <windows.h>
 #endif
+#if HAVE_UNISTD_H == 1
+#include <unistd.h>
+#endif
 
 /* Form new nspr20 */
 #include <nspr.h>
@@ -69,10 +72,7 @@
 PR_IMPLEMENT(int)
 ADMUTIL_Init(void)
 {
-  char *server_root = getenv("NETSITE_ROOT");
   char *lang = getenv("HTTP_ACCEPT_LANGUAGE");
-  char nls_dir[256];
-  char prop_dir[256];
   int errcode;
 
   if(!admutil_initialized)  {
@@ -81,12 +81,7 @@
   }
 
   if (!admutil_i18nResource) {
-    if (server_root) {
-      PR_snprintf(nls_dir, sizeof(nls_dir), "%s/lib/nls", server_root);
-      PR_snprintf(prop_dir, sizeof(prop_dir), "%s/lib/property", server_root);
-
-      admutil_i18nResource = res_init_resource(prop_dir, "libadminutil");
-    }
+    admutil_i18nResource = res_find_and_init_resource(PROPERTYDIR, NULL);
     if (lang) admutil_acceptLang = PL_strdup(lang);
   }
 
@@ -97,28 +92,6 @@
   return 0;
 }
 
-PR_IMPLEMENT(int)
-ADMUTIL_InitSimple(char* server_root, char* lang)
-{
-  char nls_dir[256];
-  char prop_dir[256];
-
-  if (!server_root) return -1;
-
-
-  if (!admutil_i18nResource) {
-    if (server_root) {
-
-      PR_snprintf(nls_dir, sizeof(nls_dir), "%s/lib/nls", server_root);
-      PR_snprintf(prop_dir, sizeof(prop_dir), "%s/lib/property", server_root);
-
-      admutil_i18nResource = res_init_resource(prop_dir, "libadminutil");
-    }
-    if (lang) admutil_acceptLang = PL_strdup(lang);
-  }
-  return 0;
-}
-
 #ifndef MALLOC
 #define MALLOC PR_Malloc
 #endif
@@ -156,13 +129,17 @@
     int _ai=ADM_Init();
     */
     char *t = getenv("PASSWORD_PIPE");
-    PRInt32 osfd;
-    PRFileDesc *fd;
+    PRInt32 osfd = 0;
+    PRFileDesc *fd = NULL;
     char *buf;
     PRInt32 bufsize;
     PRInt32 numread = 0;
     PRInt32 totalread = 0;
     char *head, *tail;
+    int retval = 0;
+    int rpterrcode = 0; /* for rpt_err */
+    char *errmsg = NULL, *errdetail = NULL;
+    int needfree = 0;
     
 
     /* No error in this case, because it's expected to happen sometimes */
@@ -170,13 +147,17 @@
         user = NULL;
         pass = NULL;
         auth = NULL;
-        return 0;
+        return retval;
     }
 
     osfd = atol(t);
-    fd = PR_ImportFile(osfd);
+    if (osfd == STDIN_FILENO) {
+        fd = PR_STDIN;
+    } else {
+        fd = PR_ImportFile(osfd);
+    }
 
-    buf = (char *) MALLOC(BIG_LINE);
+    buf = (char *) PR_Malloc(BIG_LINE);
     bufsize = BIG_LINE;
 
     while(1)  {
@@ -187,32 +168,28 @@
 #endif
         totalread += numread;
         if(numread < 0)  {
-            PR_Close(fd);
             /* MLM XXX - ERROR CODE */
+            rpterrcode = SYSTEM_ERROR;
+            retval = -1;
 	        if (admutil_i18nResource) {
-	          rpt_err(SYSTEM_ERROR,
-		          (char*)res_getstring(admutil_i18nResource,
+              errmsg = (char*)res_getstring(admutil_i18nResource,
 				        DBT_distadm_pipeErr,
-				        admutil_acceptLang),
-		          (char*)res_getstring(admutil_i18nResource,
+				        admutil_acceptLang, NULL, 0, NULL);
+              errdetail = (char*)res_getstring(admutil_i18nResource,
 				        DBT_distadm_pipeErrDetail,
-				        admutil_acceptLang),
-		          NULL);
+				        admutil_acceptLang, NULL, 0, NULL);
+              needfree = 1;
 	        }
 	        else {
-	          rpt_err(SYSTEM_ERROR, 
-		          "Could not read from pipe",
-		          "Could not read authentication information from pipe.",
-		          NULL);
+              errmsg = "Could not read from pipe";
+              errdetail = "Could not read authentication information from pipe.";
 	        }
-            return -1;
+            goto cleanup;
         }  else  
         if(numread == 0)  {
-            PR_Close(fd);
             break;
         }
         if(buf[numread - 1] == '\0')  {
-            PR_Close(fd);
             break;
         }
     }
@@ -271,7 +248,18 @@
             }
         }
     }
-    return 0;
+cleanup:
+    if (fd != PR_STDIN) {
+        PR_Close(fd);
+    }
+    if (errmsg) {
+        rpt_err(rpterrcode, errmsg, errdetail, NULL);
+        if (needfree) {
+            PL_strfree(errmsg);
+            PL_strfree(errdetail);
+        }
+    }
+    return retval;
 }
 
 PR_IMPLEMENT(int)


Index: errRpt.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/errRpt.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- errRpt.c	22 Mar 2006 23:47:14 -0000	1.2
+++ errRpt.c	4 Apr 2007 19:37:36 -0000	1.3
@@ -147,43 +147,46 @@
 
 void _rpt_err(int type, const char *info, const char *details, const char* extra, int shouldexit)
 {
-  const char *errorString;
+  const char *errorString = NULL;
   char* acceptLang = admutil_acceptLang;
+  int needfree = 0;
 
   if (admutil_i18nResource) {
+    needfree = 1;
     switch (type) {
     case FILE_ERROR:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_FILE_ERROR, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_FILE_ERROR, acceptLang, NULL, 0, NULL);
       break;
     case MEMORY_ERROR:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_MEMORY_ERROR, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_MEMORY_ERROR, acceptLang, NULL, 0, NULL);
       break;
     case SYSTEM_ERROR:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_SYSTEM_ERROR, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_SYSTEM_ERROR, acceptLang, NULL, 0, NULL);
       break;
     case INCORRECT_USAGE:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_INCORRECT_USAGE, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_INCORRECT_USAGE, acceptLang, NULL, 0, NULL);
       break;
     case ELEM_MISSING:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_ELEM_MISSING, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_ELEM_MISSING, acceptLang, NULL, 0, NULL);
       break;
     case REGISTRY_DATABASE_ERROR:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_REGISTRY_DATABASE_ERROR, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_REGISTRY_DATABASE_ERROR, acceptLang, NULL, 0, NULL);
       break;
     case NETWORK_ERROR:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_NETWORK_ERROR, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_NETWORK_ERROR, acceptLang, NULL, 0, NULL);
       break;
     case GENERAL_FAILURE:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_GENERAL_FAILURE, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_GENERAL_FAILURE, acceptLang, NULL, 0, NULL);
       break;
     case WARNING:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_WARNING, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_WARNING, acceptLang, NULL, 0, NULL);
       break;
     case APP_ERROR:
-      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_APP_ERROR, acceptLang);
+      errorString = res_getstring(admutil_i18nResource, DBT_errRpt_APP_ERROR, acceptLang, NULL, 0, NULL);
       break;
     default:
-      errorString = "";
+      errorString = NULL;
+      needfree = 0;
     }
   }
   else errorString =  err_headers[type];
@@ -199,6 +202,10 @@
   if (details) fprintf(stdout, "NMC_ErrDetail: %s\n", details);
   if (extra) fprintf(stdout, "%s\n", extra);
 
+  if (needfree) {
+    PL_strfree((char *)errorString);
+  }
+
   if(shouldexit)  {
 #ifdef  XP_WIN32
     WSACleanup();


Index: form_post.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/form_post.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- form_post.c	11 May 2006 14:23:21 -0000	1.3
+++ form_post.c	4 Apr 2007 19:37:36 -0000	1.4
@@ -91,16 +91,18 @@
 {
     char *vars = NULL, *tmp = NULL;
     int cl;
+    char buf1[BUFSIZ];
+    char buf2[BUFSIZ];
 
     if(!(tmp = getenv("CONTENT_LENGTH"))) {
         if (admutil_i18nResource) {
             rpt_err(INCORRECT_USAGE,
                     (char*)res_getstring(admutil_i18nResource,
                                          DBT_formPost_Browser_err,
-                                         admutil_acceptLang),
+                                         admutil_acceptLang, buf1, sizeof(buf1), NULL),
                     (char*)res_getstring(admutil_i18nResource,
                                          DBT_formPost_Browser_errDetail,
-                                         admutil_acceptLang),
+                                         admutil_acceptLang, buf2, sizeof(buf2), NULL),
                     NULL);
         }
         else {
@@ -119,7 +121,7 @@
                   NULL,
                   (char*)res_getstring(admutil_i18nResource,
                                        DBT_formPost_PostStdinErr,
-                                       admutil_acceptLang),
+                                       admutil_acceptLang, buf1, sizeof(buf1), NULL),
                   NULL);
       }
       else {
@@ -136,7 +138,7 @@
                   NULL,
                   (char*)res_getstring(admutil_i18nResource,
                                        DBT_formPost_PostStdinErr,
-                                       admutil_acceptLang),
+                                       admutil_acceptLang, buf1, sizeof(buf1), NULL),
                   NULL);
       }
       else {
@@ -165,6 +167,7 @@
     int vars = 0;
     register int x = 0;
     char *tmp;
+    char buf[BUFSIZ];
 
     if (!(in = PL_strdup(in))) {
       if (admutil_i18nResource) {
@@ -172,7 +175,7 @@
                   NULL,
                   (char*)res_getstring(admutil_i18nResource,
                                        DBT_formPost_PostStdinErr,
-                                       admutil_acceptLang),
+                                       admutil_acceptLang, buf, sizeof(buf), NULL),
                   NULL);
       }
       else {
@@ -203,7 +206,7 @@
                   NULL,
                   (char*)res_getstring(admutil_i18nResource,
                                        DBT_formPost_PostStdinErr,
-                                       admutil_acceptLang),
+                                       admutil_acceptLang, buf, sizeof(buf), NULL),
                   NULL);
       }
       else {
@@ -228,7 +231,7 @@
                         NULL,
                         (char*)res_getstring(admutil_i18nResource,
                                              DBT_formPost_PostStdinErr,
-                                             admutil_acceptLang),
+                                             admutil_acceptLang, buf, sizeof(buf), NULL),
                         NULL);
             }
             else {
@@ -253,6 +256,7 @@
     register int x = 0;
     int len = PL_strlen(varname);
     char *ans = NULL;
+    char buf[BUFSIZ];
    
     while(input[x])  {
     /*  We want to get rid of the =, so len, len+1 */
@@ -263,7 +267,7 @@
                             NULL,
                             (char*)res_getstring(admutil_i18nResource,
                                                  DBT_formPost_PostStdinErr,
-                                                 admutil_acceptLang),
+                                                 admutil_acceptLang, buf, sizeof(buf), NULL),
                             NULL);
                 }
                 else {
@@ -321,6 +325,7 @@
     register int n, x;
     int len = PL_strlen(varname);
     char **ans = NULL;
+    char buf[BUFSIZ];
 
     for(n=0; input[n]; n++);
     ans = new_strlist(n + 1);
@@ -335,7 +340,7 @@
                             NULL,
                             (char*)res_getstring(admutil_i18nResource,
                                                  DBT_formPost_PostStdinErr,
-                                                 admutil_acceptLang),
+                                                 admutil_acceptLang, buf, sizeof(buf), NULL),
                             NULL);
                 }
                 else {


Index: libadminutil.properties
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/libadminutil.properties,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- libadminutil.properties	20 Jul 2005 22:51:32 -0000	1.1.1.1
+++ libadminutil.properties	4 Apr 2007 19:37:36 -0000	1.2
@@ -20,60 +20,66 @@
 
 // ICU resource file
 
+// the format is <name><number> where <name> is the PACKAGE_NAME
+// as defined in configure.ac - this must correspond to the
+// #define RESOURCE_FILE PACKAGE_NAME
+// in dbtadminutil.h
+
 root {
 
 //*extracted from errRpt.c*/
-libadminutil1 {"File System Error"}
-libadminutil2 {"Memory Error"}
-libadminutil3 {"System Error"}
-libadminutil4 {"Incorrect Usage"}
-libadminutil5 {"Form Element Missing"}
-libadminutil6 {"Registry Database Error"}
-libadminutil7 {"Network Error"}
-libadminutil8 {"Unexpected Failure"}
-libadminutil9 {"Warning"}
-libadminutil10 {"Application Error"}
+adminutil1 {"File System Error"}
+adminutil2 {"Memory Error"}
+adminutil3 {"System Error"}
+adminutil4 {"Incorrect Usage"}
+adminutil5 {"Form Element Missing"}
+adminutil6 {"Registry Database Error"}
+adminutil7 {"Network Error"}
+adminutil8 {"Unexpected Failure"}
+adminutil9 {"Warning"}
+adminutil10 {"Application Error"}
 
 //*extracted from pset.c */
-libadminutil21 {"Operation OK"}
-libadminutil22 {"Operation failed"}
-libadminutil23 {"System (OS/LDAP) related error"}
-libadminutil24 {"Environment variable error"}
-libadminutil25 {"Arguments error"}
-libadminutil26 {"Null handle"}
-libadminutil27 {"Operated in local cache mode"}
-libadminutil28 {"Failed to open local cache"}
-libadminutil29 {"Authentication failed"}
-libadminutil30 {"Access failed - improper permission"}
-libadminutil31 {"Entry does not exist"}
-libadminutil32 {"Attribute does not exist"}
-libadminutil33 {"Entry exist"}
-libadminutil34 {"Attribute exist"}
-libadminutil35 {"Not an entry"}
-libadminutil36 {"Not an attribute"}
-libadminutil37 {"NULL LDAP Handler"}
-libadminutil38 {"No Distinguished Name"}
-libadminutil39 {"No data"}
-libadminutil40 {"No value"}
-libadminutil41 {"No parent node"}
-libadminutil42 {"Only get partial data"}
-libadminutil43 {"Operation only success partially, some failed"}
-libadminutil44 {"Illegal operation"}
-libadminutil45 {"Not implemented yet"}
-libadminutil46 {"Unknown Error Number"}
+adminutil21 {"Operation OK"}
+adminutil22 {"Operation failed"}
+adminutil23 {"System (OS/LDAP) related error"}
+adminutil24 {"Environment variable error"}
+adminutil25 {"Arguments error"}
+adminutil26 {"Null handle"}
+adminutil27 {"Operated in local cache mode"}
+adminutil28 {"Failed to open local cache"}
+adminutil29 {"Authentication failed"}
+adminutil30 {"Access failed - improper permission"}
+adminutil31 {"Entry does not exist"}
+adminutil32 {"Attribute does not exist"}
+adminutil33 {"Entry exist"}
+adminutil34 {"Attribute exist"}
+adminutil35 {"Not an entry"}
+adminutil36 {"Not an attribute"}
+adminutil37 {"NULL LDAP Handler"}
+adminutil38 {"No Distinguished Name"}
+adminutil39 {"No data"}
+adminutil40 {"No value"}
+adminutil41 {"No parent node"}
+adminutil42 {"Only get partial data"}
+adminutil43 {"Operation only success partially, some failed"}
+adminutil44 {"Illegal operation"}
+adminutil45 {"Not implemented yet"}
+adminutil46 {"Unknown Error Number"}
+adminutil47 {"Attribute disallowed by entry objectclasses"}
 
 //*extracted from form_post.c  */
-libadminutil61 {"Browser Error"}
-libadminutil62 {"Your browser sent no content length with a POST command. Please be sure to use a fully compliant browser."}
-libadminutil63 {"The POST variables could not be read from stdin."}
-libadminutil64 {"Bad wildcard pattern"}
-libadminutil65 {"Illegal pattern <%s>"}
-libadminutil66 {"You should use commas to separate hosts, not spaces."}
-libadminutil67 {"Bad regular expression"}
-libadminutil68 {"The pattern <%s> is not a valid regular expression.\n"}
+adminutil61 {"Browser Error"}
+adminutil62 {"Your browser sent no content length with a POST command. Please be sure to use a fully compliant browser."}
+adminutil63 {"The POST variables could not be read from stdin."}
+adminutil64 {"Bad wildcard pattern"}
+adminutil65 {"Illegal pattern <%s>"}
+adminutil66 {"You should use commas to separate hosts, not spaces."}
+adminutil67 {"Bad regular expression"}
+adminutil68 {"The pattern <%s> is not a valid regular expression.\n"}
 
 //*extracted from  distadm.c */
-libadminutil81 {"Could not read from pipe"}
-libadminutil82 {"Could not read authentication information from pipe."}
+adminutil81 {"Could not read from pipe"}
+adminutil82 {"Could not read authentication information from pipe."}
 
 }


Index: psetc.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/psetc.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- psetc.c	11 May 2006 23:30:31 -0000	1.3
+++ psetc.c	4 Apr 2007 19:37:36 -0000	1.4
@@ -30,6 +30,7 @@
 #include <prio.h>
 #include "psetc_pvt.h"
 #include "libadminutil/admutil.h"
+#include "libadminutil/distadm.h"
 #include "dbtadmutil.h"
 #include <ldap_ssl.h>
 
@@ -50,6 +51,46 @@
 extern Resource *admutil_i18nResource;
 extern char *admutil_acceptLang;
 
+/* returns true if the given path is a valid directory, false otherwise */
+static int
+is_dir_ok(const char *path)
+{
+	PRFileInfo prinfo;
+	int ret = 0;
+
+	if (path && *path &&
+		(PR_SUCCESS == PR_GetFileInfo(path, &prinfo)) &&
+		prinfo.type == PR_FILE_DIRECTORY) {
+		ret = 1;
+	}
+
+	return ret;
+}
+
+/* returns full path and file name if the file was found somewhere, false otherwise
+   file may not yet exist, but we will create it if the dir exists */
+static char *
+find_file_in_paths(
+	const char *filename, /* the base filename to look for */
+	const char *path /* path given by caller */
+)
+{
+	char *retval = NULL;
+    char *adminutilConfDir = getenv(ADMINUTIL_CONFDIR_ENV_VAR);
+
+	/* try given path */
+    if (!is_dir_ok(path)) {
+        if (is_dir_ok(adminutilConfDir)) {
+            path = adminutilConfDir;
+        } else {
+            return retval;
+        }
+    }
+	retval = PR_smprintf("%s/%s", path, filename);
+
+	return retval;
+}
+
 static int LDAP_CALL LDAP_CALLBACK
 pset_ldap_rebind_proc (LDAP *ld, char **whop, char **passwdp,
                        int *authmethodp, int freeit, void *arg)
@@ -117,6 +158,23 @@
   PR_Free(target);
 }
 
+static void
+psetDeletePtr(PsetPtr psetp)
+{
+  if (psetp) {
+    if (psetp->info) psetNodeDestroy(psetp->info);
+    if (psetp->ldapFilter) PR_Free(psetp->ldapFilter);
+    if (psetp->ldunbindf) {
+      if (psetp->ld) ldap_unbind(psetp->ld);
+    }
+    if (psetp->configFile) PR_Free(psetp->configFile);
+    if (psetp->sieDN) PR_Free(psetp->sieDN);
+    if (psetp->binddn) PR_Free(psetp->binddn);
+    if (psetp->bindpw) PR_Free(psetp->bindpw);
+  
+    PR_Free(psetp);
+  }
+}
 
 void
 psetNodeLDAPDestroy(PsetNodePtr target, LDAP *ld)
@@ -198,7 +256,7 @@
     targetNode = target->attrFile;
   }
 
-  while (val = *vals++) treeAddValue(targetNode, val);
+  while ((val = *vals++)) treeAddValue(targetNode, val);
 
   return PSET_OP_OK;
 }
@@ -209,7 +267,7 @@
   TreeNodePtr targetNode, resultNode;
 
   if (target->attrFile) {
-    if (targetNode = treeFindNode(target->attrFile, name)) {
+    if ((targetNode = treeFindNode(target->attrFile, name))) {
       listDestroy(targetNode->val);
       targetNode->val = NULL;
       resultNode = treeAddValue(targetNode, val);
@@ -239,13 +297,13 @@
       (targetNode = treeFindNode(target->attrFile, name))) {
     listDestroy(targetNode->val);
     targetNode->val = NULL;
-    while (val = *vals++) treeAddValue(targetNode, val);
+    while ((val = *vals++)) treeAddValue(targetNode, val);
   }
   else {
     val = *vals++;
     resultNode = createTreeNode(name, val);
     if (resultNode) {
-      while (val = *vals++) treeAddValue(resultNode, val);
+      while ((val = *vals++)) treeAddValue(resultNode, val);
       if (target->attrFile) {
         treeAddNode(target->attrFile, resultNode);
       }
@@ -368,8 +426,8 @@
   if (!strncasecmp(nodePtr->attrName, name, nodeNameLen)) {
     node = nodePtr->children;
     while (node) {
-      if (result = psetNodeFindNode((PsetNodePtr)(node->val), ld, name,
-                                    nodeFlag, &dummy)) {
+      if ((result = psetNodeFindNode((PsetNodePtr)(node->val), ld, name,
+                                    nodeFlag, &dummy))) {
         *errorcode = PSET_OP_OK;
         return result;
       }
@@ -460,7 +518,7 @@
   }
 
   /* figure out the possible name for child  */
-  if (tmpPtr = strchr(newName, '.')) *tmpPtr = '\0';
+  if ((tmpPtr = strchr(newName, '.'))) *tmpPtr = '\0';
       
   node = nodePtr->children;
   while (node) {
@@ -513,7 +571,6 @@
   NameType            attrName;
   char                **vals;
   ListNodePtr         resultList=NULL, tmpList, node;
-  int                 i=0, j=0;
   char                wholeName[PATH_MAX];
 
   *errorcode = PSET_OP_OK;
@@ -580,7 +637,6 @@
   NameType            attrName;
   char                **vals;
   ListNodePtr         resultList=NULL, tmpList, node;
-  int                 i=0, j=0;
   char                wholeName[PATH_MAX];
 
   *errorcode = PSET_OP_OK;
@@ -657,6 +713,8 @@
 #endif
     ldap_memfree(nodeDN);
     if (ldaperror == LDAP_INSUFFICIENT_ACCESS) return PSET_ACCESS_FAIL;
+    /* attempt to add an attribute not part of the entry's objectclasses/schema */
+    else if (ldaperror == LDAP_OBJECT_CLASS_VIOLATION) return PSET_ATTR_NOT_ALLOWED;
     else return PSET_SYSTEM_ERR; /* error code return here */
   }
 
@@ -711,7 +769,7 @@
           }
           PR_snprintf(valBuf, valLen + 1, "%s", valList[i]);
           sptr = valBuf;
-          while (cptr = strchr(sptr, '\n')) {
+          while ((cptr = strchr(sptr, '\n'))) {
             *cptr++ = '\0';
             fprintf(fstream, "%s\n ", sptr);
             sptr=cptr;
@@ -756,12 +814,14 @@
 #ifdef LDAP_DEBUG
     ldap_perror( pset->ld, "ldap_search_s" );
 #endif
+    ldap_msgfree(result);
     if (ldaperror == LDAP_INSUFFICIENT_ACCESS) return PSET_ACCESS_FAIL;
     return PSET_SYSTEM_ERR;
   }
   
   if (ldap_count_entries(pset->ld, result) == 0) {
     /* error return : entry does not exist */
+    ldap_msgfree(result);
     return PSET_ENTRY_NOT_EXIST;
   }
 
@@ -806,8 +866,8 @@
   struct flock        flock_data;
 #endif
   char                linebuf[1024];
-  char                *name, *val, namebuf[128], *valBuf;
-  char                *nodeName, *attrName, *valptr = NULL;
+  char                *name, *val, namebuf[128], *valBuf = NULL;
+  char                *nodeName = NULL, *attrName = NULL, *valptr = NULL;
   int                 valBuf_len = 0;
   PsetNodePtr         lastPsetNode = NULL, target;
   PRStatus            prst = 0;
@@ -1028,7 +1088,7 @@
   }
 
   if (psets) {
-    while (psetl = *psets++) {
+    while ((psetl = *psets++)) {
       target = psetNodeFindNode(psetl->info, 
                                 NULL,
                                 name,
@@ -1083,15 +1143,16 @@
   case LDAP_MOD_REPLACE:
   case LDAP_MOD_DELETE:
     if (!valsptr) return PSET_ATTR_NOT_EXIST;
-    PR_Free (valsptr);
+    deleteValue (valsptr);
     break;
   case LDAP_MOD_ADD:
     if (valsptr) {
-      PR_Free (valsptr);
+      deleteValue (valsptr);
       return PSET_ATTR_EXIST;
     }
     break;
   default:
+    deleteValue (valsptr);
     return PSET_ILLEGAL_OP;
   }
 
@@ -1132,7 +1193,6 @@
   PsetPtr       pset = NULL;
   int           entries = 0, i = 0, errorcode = PSET_OP_OK;
   LDAPMod       **mods;
-  AttributeList nvlptr = nvl;
   PsetNodePtr   target;
   ListNodePtr   updateList = NULL, attrList, nodePtr, attrPtr;
   int           nodeFlag;
@@ -1147,6 +1207,7 @@
     if ((pset) && !(pset->info->ldapHolder) && 
         (pset->configFile) && 
         !(pset->fileRW)) {
+      destroyUpdateList(updateList);
       if (partial) return PSET_PARTIAL_OP;
       else return PSET_LOCAL_MODE;
     }
@@ -1168,18 +1229,20 @@
             if (partial) return PSET_PARTIAL_OP;
             else return PSET_ATTR_NOT_EXIST;
           }
-          else PR_Free (val);
+          else deleteValue (val);
           break;
         case LDAP_MOD_ADD:
           if (val) {
             /* Attribute already exist */
-            PR_Free (val);
+            deleteValue (val);
             destroyUpdateList(updateList);
             if (partial) return PSET_PARTIAL_OP;
             else return PSET_ATTR_EXIST;
           }
           break;
         default:
+          deleteValue (val);
+          destroyUpdateList(updateList);
           return PSET_ILLEGAL_OP;
         }
         attrPtr = attrPtr->next;
@@ -1232,17 +1295,21 @@
     nodePtr=nodePtr->next;
   }
   psetFileExportP(pset);
+  destroyUpdateList(updateList);
   return errorcode;
 }
 
 /*
   PsetHndl
-  psetCreate(LDAPServerPtr srv, char* sieDN, char* userDN, char* passwd,
-           char* configFile, int* errorcode)
+  psetCreate(char *serverID, char* configRoot, char* userDN, char* passwd,
+           int* errorcode)
  */
-/* SIE is in <serverRoot>/<serverID>/config/adm.conf
-   Local cache is <serverRoot>/<serverID>/config/local.conf
-   LDAP is in <serverRoot>/admin-serv/config/ldap.conf
+/*
+   The configRoot directory is expected to contain the adm.conf file
+   which we use to bootstrap our connection to the ldap server, and
+   the local.conf file which holds the read-only cached copy of our real
+   config information stored in the directory.  If the local.conf file is
+   not found there, look for it under NETSITE_ROOT/serverID/config.
  */
 
 PR_IMPLEMENT(PsetHndl)
@@ -1250,12 +1317,11 @@
            int* errorcode)
 {
   PsetHndl      pset;
-  AdmldapInfo   ldapInfo= NULL, admLdapInfo=NULL;
-  char          *serverRoot = getenv("NETSITE_ROOT");
-  char          path[PATH_MAX], *ldapHost=NULL, *sieDN = NULL;
+  AdmldapInfo   ldapInfo= NULL;
+  char          *path, *ldapHost=NULL, *sieDN = NULL;
   char          *userDN = NULL;
   char          *bindPasswd = NULL;
-  int           ldapPort = -1, dummy;
+  int           ldapPort = -1;
   
   ldapInfo = admldapBuildInfo(configRoot, errorcode);
 
@@ -1265,18 +1331,6 @@
   ldapHost = admldapGetHost(ldapInfo);
   ldapPort = admldapGetPort(ldapInfo);
 
-  /* For non-admin server, if no ldap information, get ldap host and port 
-     from admin server  */
-  if (strcasecmp(serverID, "admin-serv")) {
-    if (!ldapHost && serverRoot) {
-      PR_snprintf(path, sizeof(path), "%s%cadmin-serv%cconfig",
-                  serverRoot, FILE_PATHSEP, FILE_PATHSEP);
-      admLdapInfo = admldapBuildInfo(configRoot, &dummy);
-      ldapHost = admldapGetHost(admLdapInfo);
-      ldapPort = admldapGetPort(admLdapInfo);
-    }
-  }
-
   *errorcode = PSET_OP_OK;
 
   if (!ldapHost) ldapHost = PL_strdup("localhost");
@@ -1285,6 +1339,9 @@
   /* Get SIE and password  */
   sieDN = admldapGetSIEDN(ldapInfo);
   if (!user) {
+    ADM_GetUserDNString(errorcode, &user);
+  }
+  if (!user) {
     ADM_GetCurrentUsername(errorcode, &user);
   }
   /* if user is just attr val, get dn */
@@ -1299,16 +1356,18 @@
     }
   }
 
-  if (configRoot)
-    PR_snprintf(path, sizeof(path), "%s%clocal.conf", configRoot, FILE_PATHSEP);
-  else
-    PR_snprintf(path, sizeof(path), "%s%c%s%cconfig%clocal.conf",
-                serverRoot, FILE_PATHSEP, serverID, FILE_PATHSEP, FILE_PATHSEP);
+  /* find local.conf file */
+  if (!(path = find_file_in_paths("local.conf", configRoot))) {
+      /* error - no valid file or dir could be found */
+      *errorcode = PSET_ENV_ERR;
+  }
 
   pset = psetRealCreate(ldapHost, ldapPort, sieDN, userDN, bindPasswd, path,
                         errorcode);
   PR_Free(ldapHost);
   PR_Free(sieDN);
+  PR_smprintf_free(path);
+  PR_Free(userDN);
   if (!passwd) { if (bindPasswd) PR_Free(bindPasswd); }
   destroyAdmldap(ldapInfo);
   return pset;
@@ -1354,7 +1413,7 @@
 {
   LDAP          *ld = NULL;
   int           ldapError, unbindF = 0;
-  PsetHndl      pset;
+  PsetHndl      pset = NULL;
 
   if ((!ldapHost) || (ldapPort < 1) || (!sieDN)) {
     /* set error code to SIEDN not available */
@@ -1375,12 +1434,14 @@
   #ifdef LDAP_DEBUG
         ldap_perror( ld, "ldap_simple_bind_s" );
   #endif
+        ldap_unbind(ld);
         *errorcode = PSET_AUTH_FAIL;
         return pset;
       case LDAP_NO_SUCH_OBJECT:
       case LDAP_ALIAS_PROBLEM:
       case LDAP_INVALID_DN_SYNTAX:
         /* Not a good DN */
+        ldap_unbind(ld);
         *errorcode = PSET_ENTRY_NOT_EXIST;
         return pset;
       default:
@@ -1445,7 +1506,7 @@
 
     /* Retrieve data  */
     pset->info = psetNodeCreate("", NULL);
-    if (*errorcode = psetLDAPRefresh(pset)) {
+    if ((*errorcode = psetLDAPRefresh(pset))) {
       /* error on retrieving data, can I use local config data? 
          Maybe not!!
          */
@@ -1465,7 +1526,7 @@
     else *errorcode = PSET_LOCAL_OPEN_FAIL;
 
     if (*errorcode && *errorcode != PSET_LOCAL_MODE) {
-        PR_Free(psetRoot->ldapInfo);
+        psetDeletePtr(psetRoot->ldapInfo);        
         psetRoot->ldapInfo = NULL;
     }
   }
@@ -1514,7 +1575,6 @@
   return (PsetHndl)psetRoot;
 }
 
-
 PR_IMPLEMENT(int)
 psetDelete(PsetHndl pseth)
 {
@@ -1525,30 +1585,19 @@
 
   psetRoot = (PsetRootPtr)pseth;
 
-  pset = psetRoot->ldapInfo;
-
-  if (pset) {
-    if (pset->info) psetNodeDestroy(pset->info);
-    if (pset->ldapFilter) PR_Free(pset->ldapFilter);
-    if (pset->ldunbindf) {
-      if (pset->ld) ldap_unbind(pset->ld);
-    }
-    if (pset->configFile) PR_Free(pset->configFile);
-    if (pset->sieDN) PR_Free(pset->sieDN);
-    if (pset->binddn) PR_Free(pset->binddn);
-    if (pset->bindpw) PR_Free(pset->bindpw);
-  
-    PR_Free(pset);
-  }
+  psetDeletePtr(psetRoot->ldapInfo);
+  psetRoot->ldapInfo = NULL;
 
   psets = psetRoot->fileInfo;
 
   if (psets) {
-    while (pset= *psets++) {
+    while ((pset= *psets++)) {
       if (pset->info) psetNodeDestroy(pset->info);
       if (pset->configFile) PR_Free(pset->configFile);
     }
   }
+
+  PR_Free(psetRoot);
   
   return PSET_OP_OK;
 }
@@ -1618,13 +1667,22 @@
 psetGetObjectClass(PsetHndl pseth, NameType name, int* errorcode)
 {
   NameType objectclass;
+  ValueType value;
+  int needFree = 0;
 
   if(strstr(name, ".objectclass")) {
     objectclass = name;
   } else {
     objectclass = (NameType)PR_smprintf("%s.objectclass", name);
+    needFree = 1;
+  }
+  value = psetGetAttrValue(pseth, objectclass, errorcode);
+
+  if (needFree) {
+      PR_smprintf_free(objectclass);
   }
-  return psetGetAttrValue(pseth, objectclass, errorcode);
+
+  return value;
 }
 
 
@@ -1654,8 +1712,6 @@
   PsetRootPtr  psetRoot;
   PsetPtr      pset;
   PsetNodePtr  target;
-  int          entries = 0;
-  int          i = 0, j= 0;
   NameType     name;
   ListNodePtr  resultList = NULL, tmpList;
   AttributeList resultAttrList = NULL;
@@ -1671,7 +1727,7 @@
   }
   psetRoot = (PsetRootPtr)pseth;
 
-  while (name = *nl++) {
+  while ((name = *nl++)) {
     target = psetRootFindNode(psetRoot, name, &pset, &nodeFlag, 
                               &dummyError);
     if (target) {
@@ -1708,7 +1764,6 @@
   PsetNodePtr         psetNode;
   ListNodePtr         tmpList;
   AttributeList       resultList;
-  int                 i=0, j=0;
   int                 nodeFlag;
 
   *errorcode = PSET_OP_OK;
@@ -1747,7 +1802,6 @@
   PsetNodePtr         psetNode;
   ListNodePtr         tmpList;
   AttributeList       resultList;
-  int                 i=0, j=0;
   int                 nodeFlag;
 
   *errorcode = PSET_OP_OK;
@@ -1785,7 +1839,6 @@
   PsetRootPtr         psetRoot;
   PsetPtr             pset;
   PsetNodePtr         psetNode;
-  int                 i=0, j=0;
   int                 nodeFlag;
 
   *errorcode = PSET_OP_OK;
@@ -1928,7 +1981,7 @@
   nvl = createAttributeList(cnt);
   nlPtr = nl;
   i = 0;
-  while (name = *nlPtr++) addAttribute(nvl, i++, name, NULL);
+  while ((name = *nlPtr++)) addAttribute(nvl, i++, name, NULL);
   return psetRootModAttrList(psetRoot, LDAP_MOD_DELETE, nvl);
 }
 
@@ -1944,7 +1997,6 @@
   char         *dn;
   int          ldaperror, i, cnt, nodeFlag, errorCode;
   char         absAttrName[PATH_MAX], **names, *filter;
-  ListNodePtr  attrList = NULL;
   AttributePtr nv;
   AttributeList nvlPtr;
 
@@ -1969,8 +2021,8 @@
   if (!(pset->info->ldapHolder) &&
       !(pset->fileRW)) return PSET_LOCAL_MODE;
 
-  if (nodePtr = psetNodeFindNode(parentPtr, pset->ld, absAttrName, &nodeFlag,
-                                 &errorCode)) {
+  if ((nodePtr = psetNodeFindNode(parentPtr, pset->ld, absAttrName, &nodeFlag,
+                                 &errorCode))) {
     return PSET_ENTRY_EXIST;
   }
 
@@ -2003,7 +2055,7 @@
 
     nvlPtr = initList;
     i = 2;
-    while (nv = *nvlPtr++)
+    while ((nv = *nvlPtr++))
       mods[i++] = createMod(nv->attrName, nv->attrVal, 0);
     mods[i] = NULL;
 
@@ -2098,171 +2150,188 @@
   return psetFileExportP(pset);
 }
 
-PR_IMPLEMENT(const char*)
-psetErrorString(int errorNum, char* lang)
+PR_IMPLEMENT(char*)
+psetErrorString(int errorNum, char* lang, char *buffer, size_t bufsize, int *rc)
 {
   char *acceptLang = lang;
-  const char* errorStr = NULL;
+  char* errorStr = NULL;
+
+  if (buffer) {
+      *buffer = '\0';
+  }
 
   if (!acceptLang) acceptLang = admutil_acceptLang;
 
   switch (errorNum) {
   case PSET_OP_OK:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_OP_OK, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_OP_OK, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Operation OK";
+    else errorStr = "Operation OK";
     break;
   case  PSET_OP_FAIL:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_OP_FAIL, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_OP_FAIL, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Operation failed";
+    else errorStr = "Operation failed";
     break;
   case  PSET_SYSTEM_ERR:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_SYSTEM_ERR, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_SYSTEM_ERR, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "System (OS/LDAP) related error";
+    else errorStr = "System (OS/LDAP) related error";
     break;
   case  PSET_ENV_ERR:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ENV_ERR, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ENV_ERR, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Environment variable error";
+    else errorStr = "Environment variable error";
     break;
   case  PSET_ARGS_ERROR:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ARGS_ERROR, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ARGS_ERROR, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Arguments error";
+    else errorStr = "Arguments error";
     break;
   case  PSET_NULL_HANDLE:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NULL_HANDLE, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NULL_HANDLE, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Null handle";
+    else errorStr = "Null handle";
     break;
   case  PSET_LOCAL_MODE:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_LOCAL_MODE, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_LOCAL_MODE, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Operated in local cache mode";
+    else errorStr = "Operated in local cache mode";
     break;
   case  PSET_LOCAL_OPEN_FAIL:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_LOCAL_OPEN_FAIL, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_LOCAL_OPEN_FAIL, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Failed to open local cache";
+    else errorStr = "Failed to open local cache";
     break;
   case  PSET_AUTH_FAIL:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_AUTH_FAIL, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_AUTH_FAIL, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Authentication failed";
+    else errorStr = "Authentication failed";
     break;
   case  PSET_ACCESS_FAIL:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ACCESS_FAIL, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ACCESS_FAIL, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Access failed - improper permission";
+    else errorStr = "Access failed - improper permission";
     break;
   case  PSET_ENTRY_NOT_EXIST:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ENTRY_NOT_EXIST, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ENTRY_NOT_EXIST, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Entry does not exist";
+    else errorStr = "Entry does not exist";
     break;
   case  PSET_ATTR_NOT_EXIST:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ATTR_NOT_EXIST, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ATTR_NOT_EXIST, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Attribute does not exist";
+    else errorStr = "Attribute does not exist";
     break;
   case  PSET_ENTRY_EXIST:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ENTRY_EXIST, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ENTRY_EXIST, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Entry exist";
+    else errorStr = "Entry exist";
     break;
   case  PSET_ATTR_EXIST:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ATTR_EXIST, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ATTR_EXIST, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Attribute exist";
+    else errorStr = "Attribute exist";
     break;
   case  PSET_NOT_ENTRY:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NOT_ENTRY, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NOT_ENTRY, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Not an entry";
+    else errorStr = "Not an entry";
     break;
   case  PSET_NOT_ATTR:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NOT_ATTR, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NOT_ATTR, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Not an attribute";
+    else errorStr = "Not an attribute";
     break;
   case  PSET_NO_LDAP_HNDL:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_LDAP_HNDL, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_LDAP_HNDL, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "NULL LDAP Handler";
+    else errorStr = "NULL LDAP Handler";
     break;
   case  PSET_NO_DN:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_DN, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_DN, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "No Distinguished Name";
+    else errorStr = "No Distinguished Name";
     break;
   case  PSET_NO_DATA:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_DATA, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_DATA, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "No data";
+    else errorStr = "No data";
     break;
   case  PSET_NO_VALUE:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_VALUE, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_VALUE, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "No value";
+    else errorStr = "No value";
     break;
   case  PSET_NO_PARENT:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_PARENT, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NO_PARENT, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "No parent node";
+    else errorStr = "No parent node";
     break;
   case  PSET_PARTIAL_GET:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_PARTIAL_GET, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_PARTIAL_GET, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Only get partial data";
+    else errorStr = "Only get partial data";
     break;
   case  PSET_PARTIAL_OP:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_PARTIAL_OP, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_PARTIAL_OP, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Operation only success partially, some failed";
+    else errorStr = "Operation only success partially, some failed";
     break;
   case  PSET_ILLEGAL_OP:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ILLEGAL_OP, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ILLEGAL_OP, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Illegal operation";
+    else errorStr = "Illegal operation";
     break;
   case  PSET_NOT_IMPLEMENT:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NOT_IMPLEMENT, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_NOT_IMPLEMENT, acceptLang, buffer, bufsize, rc);
+    if (errorStr) return errorStr;
+    else errorStr = "Not implemented yet";
+    break;
+  case  PSET_ATTR_NOT_ALLOWED:
+    if (admutil_i18nResource) 
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_ATTR_NOT_ALLOWED, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Not implemented yet";
+    else errorStr = "Attribute disallowed by entry objectclasses";
     break;
   default:
     if (admutil_i18nResource) 
-      errorStr = res_getstring(admutil_i18nResource, DBT_pset_UNKNOWN_ERROR_NO, acceptLang);
+      errorStr = res_getstring(admutil_i18nResource, DBT_pset_UNKNOWN_ERROR_NO, acceptLang, buffer, bufsize, rc);
     if (errorStr) return errorStr;
-    else return "Unknown Error Number";
+    else errorStr = "Unknown Error Number";
   }
+
+  if (buffer) {
+      PL_strncpyz(buffer, errorStr, bufsize);
+      return buffer;
+  }
+
+  return PL_strdup(errorStr);
 }
 
 /* Setting  up LDAP referal */
@@ -2380,6 +2449,8 @@
 
   for(count=0; nodeObjectClass[count] != NULL; count++)
     addName(listName, count, nodeObjectClass[count]);
+  deleteValue(nodeObjectClass);
+  nodeObjectClass = NULL;
 
   count=0;
   temp_list = nodeAttrs;
@@ -2389,7 +2460,7 @@
   temp_list = nodeAttrs;
   count=0;
   while(temp_list && (attrPtr = *temp_list++)) {
-    if(temp_attr_name = strrchr(attrPtr->attrName, '.'))
+    if ((temp_attr_name = strrchr(attrPtr->attrName, '.')))
       temp_attr_name++;
     else
       temp_attr_name = attrPtr->attrName;
@@ -2402,7 +2473,7 @@
   /* install it in the dest tree */
 
   parent = PL_strdup(name);
-  if(temp_node_name = strrchr(parent, '.')) {
+  if ((temp_node_name = strrchr(parent, '.'))) {
     temp_node_name[0] = '\0';
     temp_node_name++;
   }
@@ -2432,7 +2503,7 @@
   /* process the children */
 
   nodeChildren = psetGetChildren(source, name, &errorcode);
-  while(temp_node_name = *nodeChildren++) {
+  while ((temp_node_name = *nodeChildren++)) {
     rv = psetRecursiveReplicate(source, dest, temp_node_name, source_groupDN, dest_groupDN);
     if (rv != PSET_OP_OK) {
         return rv;
@@ -2487,6 +2558,8 @@
 
   for(count=0; nodeObjectClass[count] != NULL; count++)
     addName(listName, count, nodeObjectClass[count]);
+  deleteValue(nodeObjectClass);
+  nodeObjectClass = NULL;
 
   count=0;
   temp_list = nodeAttrs;


Index: resource.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/resource.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- resource.c	20 Jul 2005 22:51:32 -0000	1.1.1.1
+++ resource.c	4 Apr 2007 19:37:36 -0000	1.2
@@ -22,16 +22,93 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "unicode/ures.h"
 #include "unicode/ustring.h"
 
+/* returns true if the given path is a valid directory, false otherwise */
+static int
+is_dir_ok(const char *path)
+{
+	PRFileInfo prinfo;
+	int ret = 0;
+
+	if (path && *path &&
+		(PR_SUCCESS == PR_GetFileInfo(path, &prinfo)) &&
+		prinfo.type == PR_FILE_DIRECTORY) {
+		ret = 1;
+	}
+
+	return ret;
+}
+
+/*
+  ----------------------------------------------------------------
+  res_find_and_init_resource
+
+  Initializes a property file path.  Looks for the package directory
+  in a variety of well known locations, in order, and stops after
+  the first successful attempt to stat the directory.
+  1) the given path, if any
+  2) the current working directory + "/property"
+  3) getenv(ADMINUTIL_CONFDIR_ENV_VAR) + "/property"
+  It is expected that applications will have their default property
+  directory compiled in (via configure ; make) and that's what they
+  will pass in as their first argument.  The other path lookup stuff
+  is really for legacy apps or apps in which the user wants to change
+  the property directory at runtime.
+  If package is NULL, then path already is package specific e.g.
+  path will usually be something like
+  /usr/share/adminutil - the resource files will be in this directory e.g.
+  /usr/share/adminutil/root.res,en.res,en_US.res, etc.
+  -----------------------------------------------------------------
+ */
+PR_IMPLEMENT(Resource*)
+res_find_and_init_resource(const char *path, const char *package)
+{
+	char resPath[PATH_MAX];
+    char *adminutilConfDir = getenv(ADMINUTIL_CONFDIR_ENV_VAR);
+	char *execPath;
+	Resource *resource = NULL;
+
+	/* case 1 */
+	if (is_dir_ok(path)) {
+		return res_init_resource(path, package);
+	}
+
+	/* case 2 */
+	resPath[0] = '\0';
+	execPath = getcwd(resPath, sizeof(resPath));
+	if (execPath) {
+		PL_strcatn(resPath, sizeof(resPath), "/property");
+		if (!is_dir_ok(resPath)) {
+			resPath[0] = '\0';
+		}
+	}
+
+	/* case 3 */
+	if (!resPath[0] && adminutilConfDir && *adminutilConfDir) {
+		PR_snprintf(resPath, sizeof(resPath), "%s/property", adminutilConfDir);
+		if (!is_dir_ok(resPath)) {
+			resPath[0] = '\0';
+		}
+	}
+
+	if (resPath[0]) {
+		resource = res_init_resource(resPath, package);
+	}
+
+	return resource;
+}
 
 /*
   ----------------------------------------------------------------
   res_init_resource
 
   Initializes a property file path.
+  package may be NULL - this means that path is already package specific
+  e.g. /usr/share/adminutil
   -----------------------------------------------------------------
 */
 PR_IMPLEMENT(Resource*)
@@ -41,19 +118,22 @@
   char *resPath;
   char path_last_char;
 
-  if (package == NULL || PL_strlen(package) == 0) {
-    return NULL;
-  }
-
   if (path == NULL) {
+      /* both path and package cannot be NULL */
+      if (package == NULL || PL_strlen(package) == 0) {
+          return NULL;
+      }
       path = "./";
   }
 
   path_last_char = path[PL_strlen(path) - 1];
   if (path_last_char != '/' && path_last_char != '\\') {
-    resPath = PR_smprintf("%s/%s", path, package);
+    resPath = PR_smprintf("%s%s%s", path,
+                          package ? "/" : "",
+                          package ? package : "");
   } else {
-    resPath = PR_smprintf("%s%s", path, package);
+    resPath = PR_smprintf("%s%s", path,
+                          package ? package : "");
   }
   
   resource = (Resource *)PR_Malloc(sizeof(Resource));
@@ -83,16 +163,20 @@
   Gets a string by key from a resource file
   -----------------------------------------------------------------------------
 */
-PR_IMPLEMENT(const char*)
-res_getstring(Resource* resource, char *key, char *locale)
+PR_IMPLEMENT(char*)
+res_getstring(Resource* resource, char *key, char *locale, char *buffer, size_t bufsize, int *rc)
 {
-  const char* result = NULL;
+  char* result = NULL;
+  int resultcode = -1;
   UResourceBundle *bundle = NULL;
   UErrorCode status = U_ZERO_ERROR;
-  
+
+  if (buffer) {
+      *buffer = '\0';
+  }
 
   if (resource == NULL || resource->path == NULL || key == NULL) {
-      return PL_strdup("");
+      goto done;
   }
 
   bundle = ures_open(resource->path, (const char*)locale, &status);
@@ -102,31 +186,54 @@
       const UChar *umsg = ures_getStringByKey(bundle, key, &umsglen, &status);
 
       if (U_SUCCESS(status) && umsg) {
-             int32_t msglen=-1;
-
-         /* Get first the required buffer size */
-         u_strToUTF8(NULL, 0, &msglen, umsg, umsglen, &status);
-         if (msglen >0) {				 
-             result = PR_Malloc(msglen+1);
-             if (result) {
-                  /* reset status, set to OVERFLOW by the last call to u_strToUTF8 */
-                  status = U_ZERO_ERROR; 
-                  /* now the real conversion with allocated buffer */
-                  u_strToUTF8((char*)result, msglen+1, &msglen, umsg, umsglen, &status);
-                  if (!U_SUCCESS(status)) {
-                      result = NULL;
-                  }
+         int32_t msglen=-1;
+         if (buffer) {
+             /* just convert the string into the given buffer - note that
+                there may be truncation/overflow - see below */
+             msglen = (int32_t)bufsize;
+             u_strToUTF8(buffer, msglen, &msglen, umsg, umsglen, &status);
+             buffer[bufsize] = '\0'; /* ensure null termination */
+         } else {
+             /* Get first the required buffer size */
+             u_strToUTF8(NULL, 0, &msglen, umsg, umsglen, &status);
+             if (msglen >0) {				 
+                 result = PR_Malloc(msglen+1);
+                 if (result) {
+                     /* reset status, set to OVERFLOW by the last call to u_strToUTF8 */
+                     status = U_ZERO_ERROR; 
+                     /* now the real conversion with allocated buffer */
+                     u_strToUTF8((char*)result, msglen+1, &msglen, umsg, umsglen, &status);
+                     if (!U_SUCCESS(status)) {
+                         result = NULL;
+                     }
+                 }
              }
          }
+         if (status == U_BUFFER_OVERFLOW_ERROR ||
+             status == U_STRING_NOT_TERMINATED_WARNING) {
+             resultcode = 1;
+         } else if (U_SUCCESS(status)) {
+             resultcode = 0;
+         } else {
+             resultcode = -1;
+         }
       }
 
       ures_close(bundle);
   }
 
-  if (result == NULL) {
+done:
+
+  if (buffer) {
+      result = buffer;
+  } else if (!result) {
       result = PL_strdup("");
   }
 
+  if (rc) {
+      *rc = resultcode;
+  }
+
   return result;
 }
 


Index: srvutil.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/srvutil.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- srvutil.c	16 Nov 2005 18:50:15 -0000	1.2
+++ srvutil.c	4 Apr 2007 19:37:36 -0000	1.3
@@ -32,9 +32,9 @@
 {
   char        *domainDN = NULL, *isie = NULL, *sie = NULL;
   char        *ptr = NULL, *adminName = NULL;
+  char        *host = NULL, *siepwd = NULL;
   PsetHndl    domainPset;
   int         errorCode;
-  ListNodePtr dnList=NULL, node=NULL;
   AttrNameList  nl;
 
   isie = admldapGetISIEDN(info);
@@ -63,11 +63,13 @@
   adminName++;
 
   /* Use domainDN to create a pset */
-  domainPset = psetRealCreate(admldapGetHost(info),
+  host = admldapGetHost(info);
+  siepwd = admldapGetSIEPWD(info);
+  domainPset = psetRealCreate(host,
 			      admldapGetPort(info),
 			      domainDN,
 			      sie,
-			      admldapGetSIEPWD(info),
+			      siepwd,
 			      NULL,
 			      &errorCode);
 
@@ -75,14 +77,20 @@
 
   nl = retrieveSIEs(domainPset, domainDN, adminName);
 
-  psetDelete(domainPset);  /* free sie, domainDN, internally */
+  psetDelete(domainPset);
   if (isie) PR_Free(isie);
+  if (sie) PR_Free(sie);
+  if (domainDN) PR_Free(domainDN);
+  if (host) PR_Free(host);
+  if (siepwd) PR_Free(siepwd);
   return nl;
 
 err:
   if (isie) PR_Free(isie);
   if (sie) PR_Free(sie);
   if (domainDN) PR_Free(domainDN);
+  if (host) PR_Free(host);
+  if (siepwd) PR_Free(siepwd);
   return NULL;
 }
 
@@ -98,12 +106,12 @@
   if (errorCode) return NULL;
 
   nl = childrenList;
-  while (name = *nl++) {
+  while ((name = *nl++)) {
     if (strcasecmp(name, adminName)) {
       sieList = psetGetChildren(domainPset, name, &errorCode);
       nl1 = sieList;
       isieLen = PL_strlen(name);
-      while (sieName = *nl1++) {
+      while ((sieName = *nl1++)) {
 	attrName = sieName+isieLen+1;
 	if (strcasecmp(attrName, "tasks")) {
 	  sieDN = attrName2dn(sieName, domainDN);
@@ -136,39 +144,48 @@
 PR_IMPLEMENT(AttributeList)
 getInstalledServerDNList(AdmldapInfo info)
 {
-  char          *domainDN, *isie;
-  PsetHndl      domainPset;
-  AttributeList resultList;
-  int           errorCode;
+  char          *domainDN = NULL, *isie = NULL, *sie = NULL;
+  char          *host = NULL, *siepwd = NULL;
+  PsetHndl      domainPset = NULL;
+  AttributeList resultList = NULL;
+  int           errorCode = 0;
 
   isie = admldapGetISIEDN(info);
 
   domainDN=strchr(isie, ',');
-  if (!domainDN) return NULL;
+  if (!domainDN) goto done;
 
   domainDN++;
 
   while (*domainDN == ' ' &&  *domainDN != '\0') domainDN++;
 
-  if (*domainDN == '\0') return NULL;
+  if (*domainDN == '\0') goto done;
 
   /* Use domainDN to create a pset */
 
-  domainPset = psetRealCreate(admldapGetHost(info),
+  host = admldapGetHost(info);
+  sie = admldapGetSIEDN(info);
+  siepwd = admldapGetSIEPWD(info);
+  domainPset = psetRealCreate(host,
 			      admldapGetPort(info),
 			      domainDN,
-			      admldapGetSIEDN(info),
-			      admldapGetSIEPWD(info),
+			      sie,
+			      siepwd,
 			      NULL,
 			      &errorCode);
 
-  if (!domainPset) return NULL;
+  if (!domainPset) goto done;
 
   resultList = retrieveISIEs(domainPset, domainDN);
+
+done:
   psetDelete(domainPset);
+  PL_strfree(host);
+  PL_strfree(sie);
+  PL_strfree(siepwd);
+  PL_strfree(isie);
 
   return resultList;
-
 }
 
 PR_IMPLEMENT(AttributeList)
@@ -177,7 +194,6 @@
   char          *name;
   int           errorCode, i, cnt = 0;
   ListNodePtr   dnList=NULL, node=NULL;
-  char          dn[1024], attrName[256];
   AttributeList resultList = NULL;
   AttrNameList  childrenList, nl;
   char          *nickName;
@@ -186,16 +202,20 @@
   if (errorCode) return NULL;
 
   nl = childrenList;
-  while (name = *nl++) {
-    PR_snprintf (attrName, sizeof(attrName), "%s.nsNickName", name);
+  while ((name = *nl++)) {
+    char *attrName = PR_smprintf("%s.nsNickName", name);
     nickName = psetGetAttrSingleValue(domainPset, attrName, &errorCode);
     if (nickName) {
-      PR_snprintf (dn, sizeof(dn), "cn=%s, %s", name, domainDN);
-      node = createListNode(nickName, PL_strdup(dn), 1);
+      ValueType val;
+      char *dn = PR_smprintf("cn=%s, %s", name, domainDN);
+      val = (ValueType)PR_Calloc(2, sizeof(char *));
+      val[0] = dn;
+      node = createListNode(nickName, val, 1);
       if (dnList)  listCat(dnList, node);
       else dnList = node;
       PR_Free(nickName);
     }
+    PR_smprintf_free(attrName);
   }
   deleteAttrNameList(childrenList);
 


Index: uginfo.c
===================================================================
RCS file: /cvs/dirsec/adminutil/lib/libadminutil/uginfo.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- uginfo.c	11 May 2006 23:30:31 -0000	1.3
+++ uginfo.c	4 Apr 2007 19:37:36 -0000	1.4
@@ -34,11 +34,8 @@
 static char*
 admldapCreateLDAPHndl(AdmldapInfo info, char *targetDN, int *error_code)
 {
-  char            *ldapHost = NULL;
-  int             ldapPort = 0;
   char            *sieDN = NULL;
-  char            *siePassword = NULL;
-  char            targetDNBuf[1024], *resultDN = NULL;
+  char            *resultDN = NULL;
   AdmldapHdnlPtr  hndl = (AdmldapHdnlPtr)info;
 
   if (!hndl) { *error_code = UG_EMPTY_LDAPINFO; return NULL; }
@@ -49,9 +46,7 @@
     /* No target DN given, try to figure it out */
     if (!sieDN) sieDN = admldapGetSIEDN(info);
     if (sieDN) {
-      PR_snprintf(targetDNBuf, sizeof(targetDNBuf), "cn=configuration, %s",
-                  sieDN);
-      resultDN = PL_strdup(targetDNBuf);
+      resultDN = PR_smprintf("cn=configuration, %s", sieDN);
     }
     else { 
       *error_code = UG_NO_TARGETDN; 
@@ -205,7 +200,7 @@
                             char** directoryInfoRef, int* error_code)
 {
 
-  int         errorCode = UG_OP_OK, status;
+  int         status;
   char        *dummyDirectoryInfoRef = NULL;
 
   if (!admldapGetUserDirectoryInfo(ld, targetDN, directoryURL, bindDN,
@@ -357,7 +352,7 @@
         if (NULL != temp) {
           PL_strncpy(failover_buffer, &(temp[1]), sizeof(failover_buffer));
           *temp = '\0';
-          if(temp = strrchr(failover_buffer, '/')) {
+          if ((temp = strrchr(failover_buffer, '/'))) {
             PL_strncat(url_buffer, temp, url_buflen);
             *temp = '\0';
           }




More information about the Fedora-directory-commits mailing list