Author: nhosoi
Update of /cvs/dirsec/mod_admserv
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv26620
Modified Files:
mod_admserv.c
Log Message:
[191832] Admin Server password always remembers initial password on (part 2)
1) task_update_registry_server_bindpw updates the password of "uid=admin,
ou=Administrators, ou=TopologyManagement, o=NetscapeRoot"
2) in change_sie_password
2-1) increased outbuf size to 64 bytes to store the base64 encoded new password
by apr_sha1_base64.
2-2) we don't store the admin password in adm.conf; removed calling update_adm_conf.
2-3) if any of the updates fails (sie password in DS, in admpw, and uid=admin
password in DS), recover the old password to keep the passwords in sync.
3) eliminated update_adm_conf.
Index: mod_admserv.c
===================================================================
RCS file: /cvs/dirsec/mod_admserv/mod_admserv.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- mod_admserv.c 17 May 2006 00:01:55 -0000 1.24
+++ mod_admserv.c 15 Jun 2006 17:00:29 -0000 1.25
@@ -81,6 +81,8 @@
#define RUNTIME_COMMAND_BASE (char*)"commands/"
#define AUTH_URI "/admin-serv/authenticate"
+#define NETSCAPE_ROOT_BASEDN (char*)"o=NetscapeRoot"
+
/* Globals...hack. */
static char *serverroot = NULL;
static long cacheLifetime = 0; /* Defaults to 0 (entries immediately expire)
*/
@@ -1135,13 +1137,106 @@
* Miodrag (06-15-98)
* The following metthod is called from the runtime command
* "change_sie_password" after the sie password is changed
+ *
+ * Return value: if successful, 1; otherwise, 0 is returned.
*/
-static void
-task_update_registry_server_bindpw(char *password)
+static int
+task_update_registry_server_bindpw(char *uid, char *password, char* bindpw)
{
- if (registryServer.bindPW)
- free(registryServer.bindPW);
- registryServer.bindPW = password;
+ LDAP *ld;
+ int ldapError;
+ char *filter = NULL;
+ char *userDN = NULL;
+ LDAPMessage *result;
+ LDAPMod mod, *mods[2];
+ char *vals[2];
+ char *attrs[2];
+ int rval = 0;
+
+ /* update password for uid */
+ if (!(ld = openLDAPConnection(®istryServer))) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): cannot connect to the Configuration
Directory Server");
+ return rval;
+ }
+
+ filter = (char *)malloc(strlen(uid) + 5); /* "uid=<uid>" */
+ if (NULL == filter) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): cannot allocate %d byte
memory",
+ strlen(uid) + 5);
+ goto bailout;
+ }
+ attrs[0] = "dn"; /* we just need dn ... */
+ attrs[1] = NULL;
+ sprintf(filter, "uid=%s", uid);
+ ldapError = ldap_search_s(ld, NETSCAPE_ROOT_BASEDN, LDAP_SCOPE_SUBTREE,
+ filter, attrs, 0, &result);
+ if (ldapError != LDAP_SUCCESS || ldap_count_entries(ld, result) == 0) {
+ ldap_msgfree(result);
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): ldap_search %s under %s failed:
%s",
+ filter, NETSCAPE_ROOT_BASEDN, ldap_err2string(ldapError));
+ goto bailout;
+ } else {
+ LDAPMessage *entry = ldap_first_entry(ld, result);
+ userDN = ldap_get_dn(ld, entry);
+ ldap_msgfree(result);
+ }
+ if (NULL == userDN || 0 == strlen(userDN)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): ldap_search %s under %s returned
%s",
+ filter, NETSCAPE_ROOT_BASEDN, userDN?"empty string":"NULL");
+ goto bailout;
+ }
+
+ /* authenticate to LDAP server */
+ if (LDAP_SUCCESS != (ldapError = ldap_simple_bind_s(ld, userDN, bindpw))) {
+ switch (ldapError) {
+ case LDAP_INAPPROPRIATE_AUTH:
+ case LDAP_INVALID_CREDENTIALS:
+ case LDAP_INSUFFICIENT_ACCESS:
+ /* authenticate failed: Should not continue */
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): failed to authenticate as %s:
%s",
+ userDN, ldap_err2string(ldapError));
+ goto bailout;
+ case LDAP_NO_SUCH_OBJECT:
+ case LDAP_ALIAS_PROBLEM:
+ case LDAP_INVALID_DN_SYNTAX:
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): bad userdn %s: %s",
+ userDN, ldap_err2string(ldapError));
+ goto bailout;
+ default:
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): ldap error %s",
+ ldap_err2string(ldapError));
+ goto bailout;
+ }
+ }
+
+ mod.mod_op = LDAP_MOD_REPLACE;
+ mod.mod_type = "userPassword";
+ vals[0] = password;
+ vals[1] = NULL;
+ mod.mod_values = vals;
+ mods[0] = &mod;
+ mods[1] = NULL;
+ if (LDAP_SUCCESS != (ldapError = ldap_modify_s(ld, userDN, mods))) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "task_update_registry_server_bindpw(): ldap_modify for %s failed:
%s",
+ userDN, ldap_err2string(ldapError));
+ goto bailout;
+ }
+
+ registryServer.bindPW = password;
+ rval = 1;
+bailout:
+ closeLDAPConnection(ld);
+ if (NULL != filter)
+ free(filter);
+ return rval;
}
/*
@@ -1155,8 +1250,11 @@
char *newpw=query;
char filename[BIG_LINE];
char inbuf[BIG_LINE];
- char outbuf[32];
+ char outbuf[64]; /* needs at least 36 bytes */
char path[PATH_MAX];
+ char *origpw = apr_table_get(r->notes, RQ_NOTES_USERPW);
+ int ds_done = 0;
+ int admpwd_done = 0;
apr_snprintf(path, sizeof(path), "%s%cadmin-serv%cconfig",
serverroot, FILE_PATHSEP, FILE_PATHSEP);
@@ -1192,19 +1290,36 @@
uid = inbuf; *col=0; pw=col+1;
if (!update_ds(path, newpw, r)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "failed to update siepwd on DS");
return 0;
}
- if (!update_adm_conf(path, newpw)) {
- return 0;
- }
-
+ ds_done = 1;
apr_sha1_base64(newpw, strlen(newpw), outbuf);
if (!update_admpwd(path, uid, outbuf)) {
- return 0;
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "failed to update admpw");
+ goto recover;
}
+ admpwd_done = 1;
- task_update_registry_server_bindpw(strdup(newpw));
+ if (!task_update_registry_server_bindpw(uid, strdup(newpw), origpw)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "failed to update server bindpw");
+ goto recover;
+ }
+ apr_table_set(r->notes, RQ_NOTES_USERPW, newpw);
return 1;
+
+recover:
+ if (ds_done) {
+ update_ds(path, origpw, r);
+ }
+ if (admpwd_done) {
+ apr_sha1_base64(origpw, strlen(origpw), outbuf);
+ update_admpwd(path, uid, outbuf);
+ }
+ return 0;
}
/*
@@ -1243,57 +1358,6 @@
}
/*
- * Modify adm.conf
- */
-static int
-update_adm_conf(char *admroot, char *newpw)
-{
- FILE *f;
- int i, modified=0;
- static char filename[BIG_LINE];
- char buf[80];
- int linecnt=0;
- char *lines[50];
- static char inbuf[BIG_LINE];
-
- apr_snprintf(filename, sizeof(filename), "%s/adm.conf", admroot);
-
- f = fopen(filename, "r");
- if (f==NULL) {
- return 0;
- }
-
- while(fgets(inbuf, sizeof(inbuf), f) != NULL) {
- if (strstr(inbuf,"siepid:") == inbuf) { /* Line starts with
"Password:" */
- apr_snprintf(buf, sizeof(buf), "siepid: %s\n", newpw);
- lines[linecnt++] = strdup(buf);
- modified=1;
- } else {
- lines[linecnt++] = strdup(inbuf);
- }
- }
- fclose(f);
-
- if (!modified) {
- admSetCachedSIEPWD(newpw);
-
- return 1;
- }
-
- f = fopen(filename, "w");
- if (f==NULL) {
- return 0;
- }
-
- for (i=0; i < linecnt; i++) {
- fprintf(f, "%s", lines[i]);
- }
-
- fclose(f);
- return 1;
-}
-
-/*
* Modify userpassword in the DS
*/
static int
@@ -2594,8 +2658,6 @@
/* Cache lookup failed, or cache entry is expired. Try DS. */
/* First try o=NetscapeRoot in the registry server */
-# define NETSCAPE_ROOT_BASEDN (char*)"o=NetscapeRoot"
-
ret = authenticate_user(®istryServer, NETSCAPE_ROOT_BASEDN, r->user,
sent_pw, r);
if (ret != DECLINED) {
return OK;