summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--daemons/Makefile.am1
-rw-r--r--daemons/configure.ac1
-rw-r--r--daemons/ipa-kpasswd/Makefile.am59
-rw-r--r--daemons/ipa-kpasswd/README2
-rw-r--r--daemons/ipa-kpasswd/ipa_kpasswd.c1408
-rw-r--r--daemons/ipa-kpasswd/ipa_kpasswd.init83
-rw-r--r--freeipa.spec.in15
-rw-r--r--install/tools/man/Makefile.am1
-rw-r--r--install/tools/man/ipa-server-install.12
-rw-r--r--install/tools/man/ipa_kpasswd.836
-rw-r--r--ipa.12
-rw-r--r--ipaserver/install/krbinstance.py2
-rw-r--r--ipaserver/install/service.py2
-rw-r--r--selinux/Makefile5
-rw-r--r--selinux/ipa-server-selinux.spec.in5
-rw-r--r--selinux/ipa_kpasswd/ipa_kpasswd.fc9
-rw-r--r--selinux/ipa_kpasswd/ipa_kpasswd.te80
18 files changed, 14 insertions, 1700 deletions
diff --git a/.gitignore b/.gitignore
index fb0d12edc..19da265b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,6 @@ daemons/config.status
daemons/config.sub
daemons/depcomp
daemons/install-sh
-daemons/ipa-kpasswd/ipa_kpasswd
daemons/ipa-version.h
daemons/libtool
daemons/ltmain.sh
diff --git a/daemons/Makefile.am b/daemons/Makefile.am
index 254d20b45..031df16ac 100644
--- a/daemons/Makefile.am
+++ b/daemons/Makefile.am
@@ -14,7 +14,6 @@ export AM_CFLAGS
SUBDIRS = \
ipa-kdb \
- ipa-kpasswd \
ipa-slapi-plugins \
$(NULL)
diff --git a/daemons/configure.ac b/daemons/configure.ac
index 5e411fe36..e238d8b15 100644
--- a/daemons/configure.ac
+++ b/daemons/configure.ac
@@ -289,7 +289,6 @@ AC_SUBST(LDFLAGS)
AC_CONFIG_FILES([
Makefile
ipa-kdb/Makefile
- ipa-kpasswd/Makefile
ipa-slapi-plugins/Makefile
ipa-slapi-plugins/ipa-enrollment/Makefile
ipa-slapi-plugins/ipa-lockout/Makefile
diff --git a/daemons/ipa-kpasswd/Makefile.am b/daemons/ipa-kpasswd/Makefile.am
deleted file mode 100644
index 40e8c58f0..000000000
--- a/daemons/ipa-kpasswd/Makefile.am
+++ /dev/null
@@ -1,59 +0,0 @@
-NULL =
-
-INCLUDES = \
- -I. \
- -I$(srcdir) \
- -DPREFIX=\""$(prefix)"\" \
- -DBINDIR=\""$(bindir)"\" \
- -DLIBDIR=\""$(libdir)"\" \
- -DLIBEXECDIR=\""$(libexecdir)"\" \
- -DDATADIR=\""$(datadir)"\" \
- $(AM_CFLAGS) \
- $(OPENLDAP_CFLAGS) \
- $(KRB5_CFLAGS) \
- $(WARN_CFLAGS) \
- $(NULL)
-
-sbin_PROGRAMS = \
- ipa_kpasswd \
- $(NULL)
-
-ipa_kpasswd_SOURCES = \
- ipa_kpasswd.c \
- $(NULL)
-
-ipa_kpasswd_LDADD = \
- $(OPENLDAP_LIBS) \
- $(KRB5_LIBS) \
- $(NULL)
-
-install-exec-local:
- mkdir -p $(DESTDIR)$(localstatedir)/cache/ipa/kpasswd
- chmod 700 $(DESTDIR)$(localstatedir)/cache/ipa/kpasswd
-
-uninstall-local:
- -rmdir $(DESTDIR)$(localstatedir)/cache/ipa/kpasswd
- -rmdir $(DESTDIR)$(localstatedir)/cache/ipa
-
-EXTRA_DIST = \
- README \
- ipa_kpasswd.init \
- $(NULL)
-
-MAINTAINERCLEANFILES = \
- *~ \
- Makefile.in
-
-initdir=$(sysconfdir)/rc.d/init.d
-
-install-data-hook: ipa_kpasswd.init
-
- if test '!' -d $(DESTDIR)$(initdir); then \
- $(mkinstalldirs) $(DESTDIR)$(initdir); \
- chmod 755 $(DESTDIR)$(initdir); \
- fi
-
- $(INSTALL_SCRIPT) $(srcdir)/ipa_kpasswd.init $(DESTDIR)$(initdir)/ipa_kpasswd
-
-uninstall-hook:
- rm -f $(DESTDIR)$(initdir)/ipa_kpasswd
diff --git a/daemons/ipa-kpasswd/README b/daemons/ipa-kpasswd/README
deleted file mode 100644
index c0a2767a4..000000000
--- a/daemons/ipa-kpasswd/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This is an implementation of the RFC3244 kpasswd protocol.
-It is used to proxy password change operations to Directory Server.
diff --git a/daemons/ipa-kpasswd/ipa_kpasswd.c b/daemons/ipa-kpasswd/ipa_kpasswd.c
deleted file mode 100644
index f973e425d..000000000
--- a/daemons/ipa-kpasswd/ipa_kpasswd.c
+++ /dev/null
@@ -1,1408 +0,0 @@
-
-/* Kpasswd-LDAP proxy */
-
-/* Authors: Simo Sorce <ssorce@redhat.com>
- *
- * Copyright (C) 2007, 2008 Red Hat
- * see file 'COPYING' for use and warranty information
- *
- * 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, either version 3 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <sys/poll.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <netdb.h>
-#include <syslog.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <time.h>
-#include <krb5.h>
-#include <ldap.h>
-#include <sasl/sasl.h>
-#include <ifaddrs.h>
-
-#define DEFAULT_KEYTAB "FILE:/var/kerberos/krb5kdc/kpasswd.keytab"
-#define TMP_TEMPLATE "/var/cache/ipa/kpasswd/krb5_cc.XXXXXX"
-#define KPASSWD_PORT 464
-
-/* blacklist entries are released only BLCAKLIST_TIMEOUT seconds
- * after the children performing the noperation has finished.
- * this is to avoid races */
-
-#define BLACKLIST_TIMEOUT 5
-
-struct blacklist {
- struct blacklist *next;
- char *address;
- pid_t pid;
- time_t expire;
-};
-
-static struct blacklist *global_blacklist = NULL;
-
-struct socklist {
- int fd;
- int socktype;
- int dest_addr_len;
- struct sockaddr_storage dest_addr;
- struct socklist *next;
-};
-
-int check_blacklist(char *address)
-{
- struct blacklist *bl, *prev_bl;
- time_t now = time(NULL);
-
- if (!global_blacklist) {
- return 0;
- }
-
- prev_bl = NULL;
- bl = global_blacklist;
- while (bl) {
- if (bl->expire && (bl->expire < now)) {
- if (prev_bl) {
- prev_bl->next = bl->next;
- free(bl->address);
- free(bl);
- bl = prev_bl->next;
- } else {
- global_blacklist = bl->next;
- free(bl->address);
- free(bl);
- bl = global_blacklist;
- }
- continue;
- }
-
- if (strcmp(address, bl->address) == 0) {
- return 1;
- }
-
- prev_bl = bl;
- bl = bl->next;
- }
-
- return 0;
-}
-
-int add_blacklist(pid_t pid, char *address)
-{
- struct blacklist *bl, *gbl;
-
- bl = malloc(sizeof(struct blacklist));
- if (!bl) return -1;
-
- bl->next = NULL;
- bl->pid = pid;
- bl->expire = 0;
- bl->address = strdup(address);
- if (!bl->address) {
- free(bl);
- return -1;
- }
-
- if (!global_blacklist) {
- global_blacklist = bl;
- return 0;
- }
-
- gbl = global_blacklist;
- while (gbl->next) {
- gbl = gbl->next;
- }
- gbl->next = bl;
- return 0;
-}
-
-int remove_blacklist(pid_t pid)
-{
- struct blacklist *bl;
-
- if (!global_blacklist) {
- return -1;
- }
-
- bl = global_blacklist;
- while (bl) {
- if (pid == bl->pid) {
- bl->expire = time(NULL) + BLACKLIST_TIMEOUT;
- return 0;
- }
- bl = bl->next;
- }
- return -1;
-}
-
-int debug = 0;
-char *srv_pri_name = "kadmin/changepw";
-char *keytab_name = NULL;
-
-static int get_krb5_ticket(char *tmp_file)
-{
- char *ccname;
- char *realm_name = NULL;
- krb5_context context = NULL;
- krb5_keytab keytab = NULL;
- krb5_ccache ccache = NULL;
- krb5_principal kprincpw;
- krb5_creds my_creds;
- krb5_get_init_creds_opt options;
- krb5_error_code krberr;
- int ret;
-
- krberr = krb5_init_context(&context);
- if (krberr) {
- syslog(LOG_ERR, "Failed to init kerberos context");
- return -1;
- }
-
- krberr = krb5_get_default_realm(context, &realm_name);
- if (krberr) {
- syslog(LOG_ERR, "Failed to get default realm name: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- krberr = krb5_build_principal(context, &kprincpw,
- strlen(realm_name), realm_name,
- "kadmin", "changepw", NULL);
- if (krberr) {
- syslog(LOG_ERR, "Unable to build principal: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- krberr = krb5_kt_resolve(context, keytab_name, &keytab);
- if (krberr) {
- syslog(LOG_ERR, "Failed to read keytab file: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- ret = asprintf(&ccname, "FILE:%s", tmp_file);
- if (ret == -1) {
- syslog(LOG_ERR, "Out of memory!");
- goto done;
- }
-
- ret = setenv("KRB5CCNAME", ccname, 1);
- if (ret == -1) {
- syslog(LOG_ERR, "Unable to set env. variable KRB5CCNAME!");
- goto done;
- }
-
- krberr = krb5_cc_resolve(context, ccname, &ccache);
- if (krberr) {
- syslog(LOG_ERR, "Failed to set cache name: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- memset(&my_creds, 0, sizeof(my_creds));
- memset(&options, 0, sizeof(options));
-
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
- /* set a very short lifetime, we don't keep the ticket around */
- krb5_get_init_creds_opt_set_tkt_life(&options, 300);
-
- krberr = krb5_get_init_creds_keytab(context, &my_creds, kprincpw,
- keytab, 0, NULL,
- &options);
-
- if (krberr) {
- syslog(LOG_ERR, "Failed to init credentials: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- krberr = krb5_cc_initialize(context, ccache, kprincpw);
- if (krberr) {
- syslog(LOG_ERR, "Failed to init ccache: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- krberr = krb5_cc_store_cred(context, ccache, &my_creds);
- if (krberr) {
- syslog(LOG_ERR, "Failed to store creds: %s",
- krb5_get_error_message(context, krberr));
- ret = -1;
- goto done;
- }
-
- ret = 0;
-
-done:
- /* TODO: mem cleanup */
- if (keytab) krb5_kt_close(context, keytab);
- if (context) krb5_free_context(context);
- return ret;
-}
-
-int ldap_sasl_interact(LDAP *ld, unsigned flags, void *priv_data, void *sit)
-{
- sasl_interact_t *in = NULL;
- int ret = LDAP_OTHER;
- char *realm_name = (char *)priv_data;
-
- if (!ld) return LDAP_PARAM_ERROR;
-
- for (in = sit; in && in->id != SASL_CB_LIST_END; in++) {
- switch(in->id) {
- case SASL_CB_USER:
- in->result = srv_pri_name;
- in->len = strlen(srv_pri_name);
- ret = LDAP_SUCCESS;
- break;
- case SASL_CB_GETREALM:
- in->result = realm_name;
- in->len = strlen(realm_name);
- ret = LDAP_SUCCESS;
- break;
- default:
- if (debug > 0) {
- syslog(LOG_ERR,
- "Unhandled SASL int. option %ld",
- in->id);
- }
- in->result = NULL;
- in->len = 0;
- ret = LDAP_OTHER;
- }
- }
- return ret;
-}
-
-/* from DS ldaprot.h */
-#define LDAP_TAG_PWP_WARNING 0xA0 /* context specific + constructed + 0 */
-#define LDAP_TAG_PWP_SECSLEFT 0x80L /* context specific + primitive */
-#define LDAP_TAG_PWP_GRCLOGINS 0x81L /* context specific + primitive + 1 */
-#define LDAP_TAG_PWP_ERROR 0x81L /* context specific + primitive + 1 */
-
-int ldap_pwd_change(char *client_name, char *realm_name, krb5_data pwd, char **errstr)
-{
- char *tmp_file = NULL;
- int version;
- LDAP *ld = NULL;
- BerElement *ctrl = NULL;
- BerElement *sctrl = NULL;
- struct berval *control = NULL;
- struct berval newpw;
- char hostname[1024];
- char *uri;
- struct berval **ncvals;
- char *filter;
- char *attrs[] = {"krbprincipalname", NULL};
- char *root_attrs[] = {"namingContexts", NULL};
- char *userdn = NULL;
- char *retoid = NULL;
- struct berval *retdata = NULL;
- struct timeval tv;
- LDAPMessage *entry, *res = NULL;
- LDAPControl **srvctrl = NULL;
- char *exterr0 = NULL;
- char *exterr1 = NULL;
- char *exterr2 = NULL;
- char *err = NULL;
- int msgid;
- int ret, rc;
- int fd;
- int kpwd_err = KRB5_KPASSWD_HARDERROR;
- int i;
-
- tmp_file = strdup(TMP_TEMPLATE);
- if (!tmp_file) {
- syslog(LOG_ERR, "Out of memory!");
- goto done;
- }
-
- fd = mkstemp(tmp_file);
- if (fd == -1) {
- syslog(LOG_ERR,
- "Failed to create tmp file with errno: %d", errno);
- goto done;
- }
- /* close mimmediately, we don't need to keep the file open,
- * just that it exist and has a unique name */
- close(fd);
-
- /* In the long term we may want to do this in the main daemon
- * and just renew when needed.
- * Right now do it at every password change for robustness */
- ret = get_krb5_ticket(tmp_file);
- if (ret) {
- syslog(LOG_ERR, "Unable to kinit!");
- goto done;
- }
-
- newpw.bv_len = pwd.length;
- newpw.bv_val = pwd.data;
-
- /* retrieve server name and build uri */
- ret = gethostname(hostname, 1023);
- if (ret == -1) {
- syslog(LOG_ERR, "Unable to get the hostname!");
- goto done;
- }
-
- ret = asprintf(&uri, "ldap://%s:389", hostname);
- if (ret == -1) {
- syslog(LOG_ERR, "Out of memory!");
- goto done;
- }
-
- /* connect to ldap server */
- /* TODO: support referrals ? */
- ret = ldap_initialize(&ld, uri);
- free(uri);
- if(ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "Unable to connect to ldap server: %s",
- ldap_err2string(ret));
- goto done;
- }
-
- version = LDAP_VERSION3;
- ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
- if (ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "Unable to set ldap protocol version");
- goto done;
- }
-
- ret = ldap_sasl_interactive_bind_s(ld,
- NULL, "GSSAPI",
- NULL, NULL,
- LDAP_SASL_AUTOMATIC,
- ldap_sasl_interact, realm_name);
- if (ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "Unable to bind to ldap server");
- goto done;
- }
-
- /* find base dn */
- tv.tv_sec = 10;
- tv.tv_usec = 0;
-
- ret = ldap_search_ext_s(ld, "", LDAP_SCOPE_BASE,
- "objectclass=*", root_attrs, 0,
- NULL, NULL, &tv, 0, &res);
-
- if (ret != LDAP_SUCCESS) {
- syslog(LOG_ERR,
- "Search for %s on rootdse failed with error %d",
- root_attrs[0], ret);
- goto done;
- }
-
- /* for now just use the first result we get */
- entry = ldap_first_entry(ld, res);
- ncvals = ldap_get_values_len(ld, entry, root_attrs[0]);
- if (!ncvals) {
- syslog(LOG_ERR, "No values for %s", root_attrs[0]);
- goto done;
- }
-
- ldap_msgfree(res);
- res = NULL;
-
- /* find user dn */
- ret = asprintf(&filter, "krbPrincipalName=%s", client_name);
- if (ret == -1) {
- syslog(LOG_ERR, "Out of memory!");
- goto done;
- }
-
- tv.tv_sec = 10;
- tv.tv_usec = 0;
-
- for (i = 0; !userdn && ncvals[i]; i++) {
- ret = ldap_search_ext_s(ld, ncvals[i]->bv_val,
- LDAP_SCOPE_SUBTREE, filter, attrs, 1,
- NULL, NULL, &tv, 0, &res);
-
- if (ret != LDAP_SUCCESS) {
- break;
- }
-
- /* for now just use the first result we get */
- entry = ldap_first_entry(ld, res);
- if (entry) {
- userdn = ldap_get_dn(ld, entry);
- }
-
- ldap_msgfree(res);
- res = NULL;
- }
-
- ldap_value_free_len(ncvals);
-
- if (ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "Search for %s failed with error %d",
- filter, ret);
- if (ret == LDAP_CONSTRAINT_VIOLATION) {
- *errstr = strdup("Password Change Failed");
- kpwd_err = KRB5_KPASSWD_SOFTERROR;
- }
- goto done;
- }
-
- free(filter);
- filter = NULL;
-
- if (!userdn) {
- syslog(LOG_ERR, "No userdn, can't change password!");
- goto done;
- }
-
- /* build password change control */
- ctrl = ber_alloc_t(LBER_USE_DER);
- if (!ctrl) {
- syslog(LOG_ERR, "Out of memory!");
- goto done;
- }
-
- ret = ber_printf(ctrl, "{tstO}",
- LDAP_TAG_EXOP_MODIFY_PASSWD_ID, userdn,
- LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &newpw);
- if (ret < 0) {
- syslog(LOG_ERR, "ber printf failed!");
- goto done;
- }
-
- ret = ber_flatten(ctrl, &control);
- if (ret < 0) {
- syslog(LOG_ERR, "ber flattening failed!");
- goto done;
- }
-
- /* perform password change */
- ret = ldap_extended_operation(ld,
- LDAP_EXOP_MODIFY_PASSWD,
- control, NULL, NULL,
- &msgid);
- if (ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "ldap_extended_operation() failed. (%d)", ret);
- goto done;
- }
-
- tv.tv_sec = 10;
- tv.tv_usec = 0;
-
- ret = ldap_result(ld, msgid, 1, &tv, &res);
- if (ret == -1) {
- ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &rc);
- syslog(LOG_ERR, "ldap_result() failed. (%d)", rc);
- goto done;
- }
-
- ret = ldap_parse_extended_result(ld, res, &retoid, &retdata, 0);
- if(ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "ldap_parse_extended_result() failed.");
- ldap_msgfree(res);
- goto done;
- }
- if (retoid || retdata) {
- syslog(LOG_ERR, "ldap_parse_extended_result() returned data, but we don't handle it yet.");
- }
-
- ret = ldap_parse_result(ld, res, &rc, NULL, &err, NULL, &srvctrl, 0);
- if(ret != LDAP_SUCCESS) {
- syslog(LOG_ERR, "ldap_parse_result() failed.");
- goto done;
- }
- if (rc != LDAP_SUCCESS) {
- if (rc == LDAP_CONSTRAINT_VIOLATION) {
- kpwd_err = KRB5_KPASSWD_SOFTERROR;
- }
- ret = LDAP_OPERATIONS_ERROR;
- }
- if (err) {
- syslog(LOG_ERR, "ldap_parse_result(): [%s]", err);
- ldap_memfree(err);
- }
-
- if (srvctrl) {
-
- LDAPControl *pprc = NULL;
- int i;
-
- for (i = 0; srvctrl[i]; i++) {
- if (0 == strcmp(srvctrl[i]->ldctl_oid, LDAP_CONTROL_PASSWORDPOLICYRESPONSE)) {
- pprc = srvctrl[i];
- }
- }
- if (pprc) {
- sctrl = ber_init(&pprc->ldctl_value);
- }
-
- if (sctrl) {
- /*
- * PasswordPolicyResponseValue ::= SEQUENCE {
- * warning [0] CHOICE OPTIONAL {
- * timeBeforeExpiration [0] INTEGER (0 .. maxInt),
- * graceLoginsRemaining [1] INTEGER (0 .. maxInt) }
- * error [1] ENUMERATED OPTIONAL {
- * passwordExpired (0),
- * accountLocked (1),
- * changeAfterReset (2),
- * passwordModNotAllowed (3),
- * mustSupplyOldPassword (4),
- * invalidPasswordSyntax (5),
- * passwordTooShort (6),
- * passwordTooYoung (7),
- * passwordInHistory (8) } }
- */
-
- ber_tag_t rtag, btag;
- ber_int_t bint;
- rtag = ber_scanf(sctrl, "{t", &btag);
- if (btag == LDAP_TAG_PWP_WARNING) {
- rtag = ber_scanf(sctrl, "{ti}", &btag, &bint);
- if (btag == LDAP_TAG_PWP_SECSLEFT) {
- ret = asprintf(&exterr2, " (%d seconds left before password expires)", bint);
- } else {
- ret = asprintf(&exterr2, " (%d grace logins remaining)", bint);
- }
- if (ret == -1) {
- syslog(LOG_ERR, "OOM while creating error message ...");
- exterr2 = NULL;
- }
- rtag = ber_scanf(sctrl, "t", &btag);
- }
- if (btag == LDAP_TAG_PWP_ERROR) {
- rtag = ber_scanf(sctrl, "e", &bint);
- switch(bint) {
- case 0:
- ret = asprintf(&exterr1, " Err%d: Password Expired.", bint);
- break;
- case 1:
- ret = asprintf(&exterr1, " Err%d: Account locked.", bint);
- break;
- case 2:
- ret = asprintf(&exterr1, " Err%d: Password changed after reset.", bint);
- break;
- case 3:
- ret = asprintf(&exterr1, " Err%d: Password change not allowed.", bint);
- break;
- case 4:
- ret = asprintf(&exterr1, " Err%d: [Shouldn't happen].", bint);
- break;
- case 5:
- ret = asprintf(&exterr1, " Err%d: Password too simple.", bint);
- break;
- case 6:
- ret = asprintf(&exterr1, " Err%d: Password too short.", bint);
- break;
- case 7:
- ret = asprintf(&exterr1, " Err%d: Too soon to change password.", bint);
- break;
- case 8:
- ret = asprintf(&exterr1, " Err%d: Password reuse not permitted.", bint);
- break;
- default:
- ret = asprintf(&exterr1, " Err%d: Unknown Errorcode.", bint);
- break;
- }
- if (ret == -1) {
- syslog(LOG_ERR, "OOM while creating error message ...");
- exterr1 = NULL;
- }
- }
- }
- }
-
- if (ret == LDAP_SUCCESS) {
- kpwd_err = KRB5_KPASSWD_SUCCESS;
- exterr0 = "Password change succeeded";
- } else {
- exterr0 = "Password change failed";
- }
- ret = asprintf(errstr, "%s%s%s", exterr0, exterr1?exterr1:"", exterr2?exterr2:"");
- if (ret == -1) {
- syslog(LOG_ERR, "OOM while creating error message ...");
- *errstr = NULL;
- }
-
-done:
- if (ctrl) ber_free(ctrl, 1);
- if (sctrl) ber_free(sctrl, 1);
- if (srvctrl) ldap_controls_free(srvctrl);
- if (res) ldap_msgfree(res);
- if (control) ber_bvfree(control);
- free(exterr1);
- free(exterr2);
- free(filter);
- free(userdn);
- if (ld) ldap_unbind_ext(ld, NULL, NULL);
- if (tmp_file) {
- unlink(tmp_file);
- free(tmp_file);
- }
- return kpwd_err;
-}
-
-void handle_krb_packets(uint8_t *buf, ssize_t buflen,
- struct socklist *sd,
- struct sockaddr_storage *from,
- uint8_t **repbuf, ssize_t *replen)
-{
- krb5_auth_context auth_context;
- krb5_context context;
- krb5_keytab keytab;
- krb5_principal kprincpw;
- krb5_ticket *ticket;
- krb5_address lkaddr, rkaddr;
- krb5_data kreq, krep, kenc, kdec;
- krb5_replay_data replay;
- krb5_error krb5err;
- int krberr;
- size_t reqlen;
- size_t verno;
- char *client_name, *realm_name;
- char *result_string;
- int result_err;
- uint8_t *reply;
- ssize_t replylen;
-
- *replen = 0;
-
- result_string = NULL;
- auth_context = NULL;
- krep.length = 0;
- krep.data = NULL;
- kdec.length = 0;
- kdec.data = NULL;
- kprincpw = NULL;
- context = NULL;
- ticket = NULL;
-
- switch(((struct sockaddr *)from)->sa_family) {
- case AF_INET:
- lkaddr.addrtype = ADDRTYPE_INET;
- lkaddr.length = sizeof(((struct sockaddr_in *)&sd->dest_addr)->sin_addr);
- lkaddr.contents = (krb5_octet *) &(((struct sockaddr_in *)&sd->dest_addr)->sin_addr);
-
- rkaddr.addrtype = ADDRTYPE_INET;
- rkaddr.length = sizeof(((struct sockaddr_in *)from)->sin_addr);
- rkaddr.contents = (krb5_octet *) &(((struct sockaddr_in *)from)->sin_addr);
- break;
- case AF_INET6:
- if (IN6_IS_ADDR_V4MAPPED (&((struct sockaddr_in6 *)from)->sin6_addr)) {
- lkaddr.addrtype = ADDRTYPE_INET;
- lkaddr.length = 4;
- lkaddr.contents = 12 + (krb5_octet *) &(((struct sockaddr_in6 *)&sd->dest_addr)->sin6_addr);
-
- rkaddr.addrtype = ADDRTYPE_INET;
- rkaddr.length = 4;
- rkaddr.contents = 12 + (krb5_octet *) &(((struct sockaddr_in6 *)from)->sin6_addr);
- } else {
- lkaddr.addrtype = ADDRTYPE_INET6;
- lkaddr.length = sizeof(((struct sockaddr_in6 *)&sd->dest_addr)->sin6_addr);
- lkaddr.contents = (krb5_octet *) &(((struct sockaddr_in6 *)&sd->dest_addr)->sin6_addr);
-
- rkaddr.addrtype = ADDRTYPE_INET6;
- rkaddr.length = sizeof(((struct sockaddr_in6 *)from)->sin6_addr);
- rkaddr.contents = (krb5_octet *) &(((struct sockaddr_in6 *)from)->sin6_addr);
- }
- break;
- default:
- result_string = strdup("Invalid remopte IP address");
- result_err = KRB5_KPASSWD_MALFORMED;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
-
- if (buflen < 4) {
- result_string = strdup("Request truncated");
- result_err = KRB5_KPASSWD_MALFORMED;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
-
- reqlen = (buf[0] << 8) + buf[1];
-
- if (reqlen != buflen) {
- result_string = strdup("Unmatching request length");
- result_err = KRB5_KPASSWD_MALFORMED;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
-
- verno = (buf[2] << 8) + buf[3];
-
- if (verno != 1) {
- result_string = strdup("Unsupported version");
- result_err = KRB5_KPASSWD_BAD_VERSION;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
-
- kreq.length = (buf[4] << 8) + buf[5];
- if (kreq.length > (buflen - 6)) {
- result_string = strdup("Request truncated");
- result_err = KRB5_KPASSWD_MALFORMED;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
- kreq.data = (char *)&buf[6];
-
- krberr = krb5_init_context(&context);
- if (krberr) {
- result_string = strdup("Failed to init kerberos context");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
-
- krberr = krb5_get_default_realm(context, &realm_name);
- if (krberr) {
- result_string = strdup("Failed to get default realm name");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s", result_string);
- goto done;
- }
-
- krberr = krb5_auth_con_init(context, &auth_context);
- if (krberr) {
- result_string = strdup("Unable to init auth context");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- krberr = krb5_auth_con_setflags(context, auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
- if (krberr) {
- result_string = strdup("Unable to init auth context");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- krberr = krb5_build_principal(context, &kprincpw,
- strlen(realm_name), realm_name,
- "kadmin", "changepw", NULL);
- if (krberr) {
- result_string = strdup("Unable to build principal");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- krberr = krb5_kt_resolve(context, keytab_name, &keytab);
- if (krberr) {
- result_string = strdup("Unable to retrieve keytab");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- krberr = krb5_rd_req(context, &auth_context, &kreq,
- kprincpw, keytab, NULL, &ticket);
- if (krberr) {
- result_string = strdup("Unable to read request");
- result_err = KRB5_KPASSWD_AUTHERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- /* build the AP Reply before actually changing the password
- * this minimize the risk of a fatal error occurring _after_
- * the password have been successfully changed */
- krberr = krb5_mk_rep(context, auth_context, &krep);
- if (krberr) {
- result_string = strdup("Failed to to build reply");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- /* verify that this is an AS_REQ ticket */
- if (!(ticket->enc_part2->flags & TKT_FLG_INITIAL)) {
- result_string = strdup("Ticket must be derived from a password");
- result_err = KRB5_KPASSWD_AUTHERROR;
- syslog(LOG_ERR, "%s", result_string);
- goto kpreply;
- }
-
- krberr = krb5_unparse_name(context, ticket->enc_part2->client,
- &client_name);
- if (krberr) {
- result_string = strdup("Unable to parse client name");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s", result_string);
- goto kpreply;
- }
-
- krberr = krb5_auth_con_setaddrs(context, auth_context, NULL, &rkaddr);
- if (krberr) {
- result_string = strdup("Failed to set client address");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto kpreply;
- }
-
- /* decrypt the new password */
- kenc.length = reqlen - kreq.length - 6;
- kenc.data = kreq.data + kreq.length;
-
- /* rd_priv needs the remote address while mk_priv (used later)
- * requires the local address (from kadmin code) */
- krberr = krb5_rd_priv(context, auth_context, &kenc, &kdec, &replay);
- if (krberr) {
- result_string = strdup("Failed to decrypt password");
- result_err = KRB5_KPASSWD_HARDERROR;
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto kpreply;
- }
-
- if (debug > 100) {
- syslog(LOG_ERR, "Client %s trying to set password [%*s]",
- client_name, kdec.length, kdec.data);
- }
-
- /* Actually try to change the password */
- result_err = ldap_pwd_change(client_name, realm_name, kdec, &result_string);
- if (result_string == NULL) {
- result_string = strdup("Server Error while performing LDAP password change");
- }
- syslog(LOG_ERR, "%s", result_string);
-
- /* make sure password is cleared off before we free the memory */
- memset(kdec.data, 0, kdec.length);
- free(kdec.data);
- kdec.length = 0;
-
-kpreply:
-
- /* set-up the the clear text reply */
- kdec.length = 2 + strlen(result_string);
- kdec.data = malloc(kdec.length);
- if (!kdec.data) {
- syslog(LOG_ERR, "Out of memory!");
- kdec.length = 0;
- goto done;
- }
-
- kdec.data[0] = (result_err >> 8) & 0xff;
- kdec.data[1] = result_err & 0xff;
- memcpy(&kdec.data[2], result_string, strlen(result_string));
-
- free(result_string);
- result_string = NULL;
-
- krberr = krb5_auth_con_setaddrs(context, auth_context, &lkaddr, NULL);
- if (krberr) {
- result_string = strdup("Failed to set local address");
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- krberr = krb5_mk_priv(context, auth_context, &kdec, &kenc, &replay);
- if (krberr) {
- result_string = strdup("Failed to encrypt reply message");
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
-
- free(result_string);
- result_string = NULL;
- /* encryption was unsuccessful, let's return a krb error */
-
- /* the ap data is no more useful */
- free(krep.data);
- krep.length = 0;
-
- /* build a krberror encrypted paylod */
- krb5err.error = KRB5_CHPW_FAIL;
- krb5err.server = kprincpw;
- krb5err.client = NULL;
- krb5err.ctime = 0;
- krb5err.cusec = 0;
- krb5err.susec = 0;
- krberr = krb5_timeofday(context, &krb5err.stime);
- if (krberr) {
- result_string = strdup("Failed to set time of day");
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
-
- krb5err.text.length = 0;
- krb5err.e_data = kdec;
- krberr = krb5_mk_error(context, &krb5err, &kenc);
- if (krberr) {
- result_string = strdup("Failed to build error message");
- syslog(LOG_ERR, "%s: %s", result_string,
- krb5_get_error_message(context, krberr));
- goto done;
- }
- }
-
- replylen = 6 + krep.length + kenc.length;
- reply = malloc(replylen);
- if (!reply) {
- syslog(LOG_ERR, "Out of memory!");
- goto done;
- }
- *repbuf = reply;
-
- reply[0] = (replylen >> 8) & 0xff;
- reply[1] = replylen & 0xff;
- reply[2] = 0x00;
- reply[3] = 0x01;
- reply[4] = (krep.length >> 8) & 0xff;
- reply[5] = krep.length & 0xff;
-
- if (krep.length) {
- memcpy(&reply[6], krep.data, krep.length);
- }
- memcpy(&reply[6 + krep.length], kenc.data, kenc.length);
-
- *replen = replylen;
-
-done:
- free(result_string);
- if (auth_context) krb5_auth_con_free(context, auth_context);
- if (kprincpw) krb5_free_principal(context, kprincpw);
- if (krep.length) free(krep.data);
- if (ticket) krb5_free_ticket(context, ticket);
- if (kdec.length) free(kdec.data);
- if (context) krb5_free_context(context);
-}
-
-pid_t handle_conn(struct socklist *sd)
-{
- int mfd, tcp;
- pid_t pid;
- char addrto6[INET6_ADDRSTRLEN+1];
- char address[INET6_ADDRSTRLEN+1];
- uint8_t request[1500];
- ssize_t reqlen;
- uint8_t *reply;
- ssize_t replen;
- struct sockaddr_storage from;
- socklen_t fromlen;
- ssize_t sendret;
- int ret;
-
- fromlen = sizeof(from);
- mfd = 0;
- tcp = 0;
- reqlen = 0;
-
- /* receive request */
- if (sd->socktype == SOCK_STREAM) {
- tcp = 1;
- mfd = accept(sd->fd, (struct sockaddr *)&from, &fromlen);
- if (mfd == -1) {
- syslog(LOG_ERR, "Accept failed with error (%d) %s",
- errno, strerror(errno));
- return -1;
- }
- } else {
- /* read first to empty the buffer on udp connections */
- reqlen = recvfrom(sd->fd, request, sizeof(request), 0,
- (struct sockaddr *)&from, &fromlen);
- if (reqlen <= 0) {
- syslog(LOG_ERR, "Error receiving request (%d) %s",
- errno, strerror(errno));
- return -1;
- }
-
- }
-
- ret = getnameinfo((struct sockaddr *)&from, fromlen,
- addrto6, INET6_ADDRSTRLEN+1,
- NULL, 0, NI_NUMERICHOST);
- if (ret) {
- syslog(LOG_ERR, "Error retrieving host address\n");
- return -1;
- }
-
- if (debug > 0) {
- syslog(LOG_ERR, "Connection from %s", addrto6);
- }
-
- if (strchr(addrto6, ':') == NULL) {
- char *prefix6 = "::ffff:";
- /* this is an IPv4 formatted addr
- * convert to IPv6 mapped addr */
- memcpy(address, prefix6, 7);
- memcpy(&address[7], addrto6, INET6_ADDRSTRLEN-7);
- } else {
- /* regular IPv6 address, copy as is */
- memcpy(address, addrto6, INET6_ADDRSTRLEN);
- }
- /* make sure we have termination */
- address[INET6_ADDRSTRLEN] = '\0';
-
- /* Check blacklist for requests from the same IP until operations
- * are finished on the active client.
- * the password change may be slow and pam_krb5 sends up to 3 UDP
- * requests waiting 1 sec. each time.
- * We do not want to start 3 password changes at the same time */
-
- if (check_blacklist(address)) {
- if (debug > 0) {
- syslog(LOG_ERR, "[%s] blacklisted", address);
- }
- if (tcp) close(mfd);
- return 0;
- }
-
- /* now read data if it was a TCP connection */
- if (tcp) {
- reqlen = recvfrom(mfd, request, sizeof(request), 0,
- (struct sockaddr *)&from, &fromlen);
- if (reqlen <= 0) {
- syslog(LOG_ERR, "Error receiving request (%d) %s",
- errno, strerror(errno));
- close(mfd);
- return -1;
- }
- }
-#if 1
- /* handle kerberos and ldap operations in childrens */
- pid = fork();
- if (pid == -1) {
- syslog(LOG_ERR, "Fork failed with error (%d) %s",
- errno, strerror(errno));
- if (tcp) close(mfd);
- return 0;
- }
- if (pid != 0) { /* parent */
- if (tcp) close(mfd);
- add_blacklist(pid, address);
- return pid;
- }
-#endif
-
- /* children */
- if (debug > 0) syslog(LOG_ERR, "Servicing %s", address);
-
- /* TCP packets prepend the lenght as a 32bit network order field,
- * this information seem to be just redundant, so let's simply
- * skip it */
- if (tcp) {
- handle_krb_packets(request+4, reqlen-4, sd, &from, &reply, &replen);
- } else {
- handle_krb_packets(request, reqlen, sd, &from, &reply, &replen);
- }
-
- if (replen) { /* we have something to reply */
- if (tcp) {
- sendret = sendto(mfd, reply, replen, 0, NULL, 0);
- } else {
- sendret = sendto(sd->fd, reply, replen, 0, (struct sockaddr *)&from, fromlen);
- }
- if (sendret == -1) {
- syslog(LOG_ERR, "Error sending reply (%d)", errno);
- }
- }
- if (tcp) close(mfd);
- exit(0);
-}
-
-static int create_socket(struct addrinfo *ai, struct socklist **_sds,
- struct pollfd **_pfds, int *_nfds)
-{
- struct socklist *csd, *tsd;
- struct pollfd *pfds;
- int nfds;
- int ret;
- int tru = 1;
-
- pfds = *_pfds;
- nfds = *_nfds;
-
- csd = calloc(1, sizeof(struct socklist));
- if (csd == NULL) {
- syslog(LOG_ERR, "Out of memory, can't create socklist\n");
- return 1;
- }
- csd->socktype = ai->ai_socktype;
- csd->dest_addr_len = ai->ai_addrlen;
- memcpy(&csd->dest_addr, ai->ai_addr, ai->ai_addrlen);
-
- csd->fd = socket(csd->dest_addr.ss_family, csd->socktype, 0);
- if (csd->fd == -1) {
- syslog(LOG_ERR, "Unable to create socket (%s)",
- strerror(errno));
- goto errout;
- }
- ret = setsockopt(csd->fd, SOL_SOCKET, SO_REUSEADDR,
- (void *)&tru, sizeof(tru));
-
- ret = bind(csd->fd, (struct sockaddr *)&csd->dest_addr, csd->dest_addr_len);
- if (ret) {
- if (errno != EADDRINUSE) {
- syslog(LOG_ERR, "Unable to bind to socket");
- close(csd->fd);
- goto errout;
- }
- /* if EADDRINUSE it means we are on a machine
- * with a dual ipv4/ipv6 stack that does not
- * allow to bind on both at the same time as the
- * ipv6 bind already allows connections on ipv4
- * Just ignore */
- close(csd->fd);
- free(csd);
- return 0;
- }
-
- if (csd->socktype == SOCK_STREAM) {
- ret = listen(csd->fd, SOMAXCONN);
- if (ret) {
- syslog(LOG_ERR, "Unable to listen to TCP socket (%s)",
- strerror(errno));
- close(csd->fd);
- goto errout;
- }
- }
-
- pfds = realloc(pfds, sizeof(struct pollfd) * (nfds +1));
- if (pfds == NULL) {
- syslog(LOG_ERR, "Out of memory, can't alloc pollfd array\n");
- close(csd->fd);
- goto errout;
- }
- pfds[nfds].events = POLLIN;
- pfds[nfds].fd = csd->fd;
- nfds++;
-
- if (*_sds) {
- for (tsd = *_sds; tsd->next; tsd = tsd->next) /* skip */ ;
- tsd->next = csd;
- } else {
- *_sds = csd;
- }
-
- *_pfds = pfds;
- *_nfds = nfds;
-
- return 0;
-
-errout:
- free(csd);
- return 1;
-}
-
-int main(int argc, char *argv[])
-{
- pid_t pid;
- struct ifaddrs *ifa, *tifa;
- struct addrinfo *ai, *tai;
- struct addrinfo hints;
- char host[NI_MAXHOST];
- struct socklist *sds, *csd;
- struct pollfd *pfds;
- int nfds;
- int ret;
- char *env;
-
- /* log to syslog */
- openlog("kpasswd", LOG_PID, LOG_DAEMON);
-
- /* do not keep any fs busy */
- ret = chdir("/");
- if (ret == -1) {
- syslog(LOG_ERR, "Unable to change dir to '/'");
- exit(-1);
- }
-
- /* daemonize */
- pid = fork();
- if (pid == -1) {
- syslog(LOG_ERR, "Error fork() failed!");
- exit(-1);
- }
- if (pid != 0) { /* parent */
- exit(0);
- }
-
- /* new session */
- setsid();
-
- /* close std* descriptors */
- close(0);
- close(1);
- close(2);
-
- /* fork again to make sure we completely detach from parent process */
- pid = fork();
- if (pid == -1) {
- syslog(LOG_ERR, "Error fork() failed!");
- exit(-1);
- }
- if (pid != 0) { /* parent */
- exit(0);
- }
-
- /* source env vars */
- env = getenv("KRB5_KTNAME");
- if (!env) {
- env = DEFAULT_KEYTAB;
- }
- keytab_name = strdup(env);
- if (!keytab_name) {
- syslog(LOG_ERR, "Out of memory!");
- }
-
- env = getenv("IPA_KPASSWD_DEBUG");
- if (env) {
- debug = strtol(env, NULL, 0);
- }
-
- ret = getifaddrs(&ifa);
- if (ret) {
- syslog(LOG_ERR, "getifaddrs failed: %s", gai_strerror(ret));
- exit(1);
- }
-
- /* Write out the pid file after the sigterm handler */
- const char *pid_file = "/var/run/ipa_kpasswd.pid";
- FILE *f = fopen(pid_file, "w");
- int fail = 1;
- if (f) {
- int n_bytes = fprintf(f, "%ld\n", (long) getpid());
- if (fclose(f) == 0 && 0 < n_bytes)
- fail = 0;
- }
- if (fail) {
- syslog(LOG_ERR, "Couldn't create pid file %s: %s",
- pid_file, strerror(errno));
- exit(1);
- }
-
- nfds = 0;
- pfds = NULL;
- sds = NULL;
-
- for (tifa = ifa; tifa; tifa = tifa->ifa_next) {
-
- if (NULL == tifa->ifa_addr)
- /* uhmm no address ?? skip it */
- continue;
-
- if (tifa->ifa_addr->sa_family != AF_INET &&
- tifa->ifa_addr->sa_family != AF_INET6) {
- /* not interesting for us */
- continue;
- }
-
- ret = getnameinfo(tifa->ifa_addr, sizeof(struct sockaddr_storage),
- host, sizeof(host), NULL, 0, NI_NUMERICHOST);
- if (ret) {
- syslog(LOG_ERR, "Error converting address (%s)",
- gai_strerror(ret));
- continue;
- } else {
- syslog(LOG_INFO, "Setting up socket for [%s]", host);
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_NUMERICHOST;
- hints.ai_family = AF_UNSPEC;
-
- /* this should return 2 entries, one for UDP and one for TCP */
- ret = getaddrinfo(host, "kpasswd", &hints, &ai);
- if (ret) {
- syslog(LOG_ERR, "Error getting address info (%s) for [%s]",
- gai_strerror(ret), host);
- continue;
- }
-
- for (tai = ai; tai; tai = tai->ai_next) {
- char *socktype = (tai->ai_socktype==SOCK_STREAM)?"TCP":"UDP";
- ret = create_socket(tai, &sds, &pfds, &nfds);
- if (ret) {
- syslog(LOG_ERR,
- "Failed to set up %s socket for [%s]",
- socktype, host);
- }
- }
- }
-
- if (nfds == 0) {
- syslog(LOG_ERR, "Failed to setup any socket. Aborting");
- exit(1);
- }
-
- /* now that sockets are set up, enter the poll loop */
-
- while (1) {
- int cstatus, cid, i;
-
- ret = poll(pfds, nfds, 3000);
-
- switch(ret) {
- case 0:
- break;
- case -1:
- if (errno != EINTR) {
- syslog(LOG_ERR,
- "Unexpected error in poll (%d) %s",
- errno, strerror(errno));
- exit(5);
- }
- break;
- default:
- for (i = 0; i < nfds; i++) {
- if (pfds[i].revents & POLLIN) {
- for (csd = sds; csd; csd = csd->next) {
- if (csd->fd == pfds[i].fd) {
- handle_conn(csd);
- }
- }
- }
- }
- }
-
- /* check for children exiting */
- cid = waitpid(-1, &cstatus, WNOHANG);
- if (cid != -1 && cid != 0) {
- if (debug > 0)
- syslog(LOG_ERR, "pid %d completed operations!\n", cid);
- remove_blacklist(cid);
- }
- }
-}
diff --git a/daemons/ipa-kpasswd/ipa_kpasswd.init b/daemons/ipa-kpasswd/ipa_kpasswd.init
deleted file mode 100644
index d7244bed6..000000000
--- a/daemons/ipa-kpasswd/ipa_kpasswd.init
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/sh
-#
-# ipa_kpasswd This starts and stops ipa_kpasswd
-#
-# chkconfig: - 36 64
-# description: ipa_kpasswd IPA Kpasswd daemon
-# processname: /usr/sbin/ipa_kpasswd
-# configdir: /etc/sysconfig/ipa-kpasswd
-#
-
-# Source function library.
-if [ -f /etc/rc.d/init.d/functions ] ; then
-. /etc/rc.d/init.d/functions
-fi
-# Source networking configuration.
-if [ -f /etc/sysconfig/network ] ; then
-. /etc/sysconfig/network
-fi
-
-# Check that networking is up.
-if [ "${NETWORKING}" = "no" ]
-then
- echo "Networking is down"
- exit 0
-fi
-
-# Source networking configuration.
-if [ -f /etc/sysconfig/ipa-kpasswd ] ; then
-. /etc/sysconfig/ipa-kpasswd
-fi
-
-NAME="ipa_kpasswd"
-PROG="/usr/sbin/ipa_kpasswd"
-
-start() {
- echo -n $"Starting $NAME: "
- daemon $NAME
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/ipa_kpasswd || \
- RETVAL=1
- return $RETVAL
-}
-
-stop() {
- echo -n $"Shutting down $NAME: "
- killproc $NAME
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/ipa_kpasswd
- return $RETVAL
-}
-
-restart() {
- stop
- start
-}
-
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- status $PROG
- ;;
- restart)
- restart
- ;;
- condrestart)
- [ -f /var/lock/subsys/ipa_kpasswd ] && restart || :
- ;;
- reload)
- exit 3
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart|condrestart}"
- exit 2
-esac
-
-exit $?
diff --git a/freeipa.spec.in b/freeipa.spec.in
index fb2462105..d25aee693 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -305,6 +305,7 @@ ln -s ../../../..%{_sysconfdir}/ipa/html/ipa_error.css \
mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d/
/bin/touch %{buildroot}%{_sysconfdir}/httpd/conf.d/ipa.conf
/bin/touch %{buildroot}%{_sysconfdir}/httpd/conf.d/ipa-rewrite.conf
+mkdir -p %{buildroot}%{_initrddir}
install -m755 ipa.init %{buildroot}%{_initrddir}/ipa
%endif
@@ -326,7 +327,6 @@ rm -rf %{buildroot}
%post server
if [ $1 = 1 ]; then
/sbin/chkconfig --add ipa
- /sbin/chkconfig --add ipa_kpasswd
fi
if [ $1 -gt 1 ] ; then
/usr/sbin/ipa-upgradeconfig || :
@@ -336,7 +336,6 @@ fi
%preun server
if [ $1 = 0 ]; then
/sbin/chkconfig --del ipa
- /sbin/chkconfig --del ipa_kpasswd
/sbin/service ipa stop >/dev/null 2>&1 || :
fi
@@ -355,7 +354,7 @@ if [ -s /etc/selinux/config ]; then
fi
%post server-selinux
-semodule -s targeted -i /usr/share/selinux/targeted/ipa_kpasswd.pp /usr/share/selinux/targeted/ipa_httpd.pp /usr/share/selinux/targeted/ipa_dogtag.pp
+semodule -s targeted -i /usr/share/selinux/targeted/ipa_httpd.pp /usr/share/selinux/targeted/ipa_dogtag.pp
. %{_sysconfdir}/selinux/config
FILE_CONTEXT=%{_sysconfdir}/selinux/targeted/contexts/files/file_contexts
selinuxenabled
@@ -377,7 +376,7 @@ fi
%postun server-selinux
if [ $1 = 0 ]; then
-semodule -s targeted -r ipa_kpasswd ipa_httpd ipa_dogtag
+semodule -s targeted -r ipa_httpd ipa_dogtag
. %{_sysconfdir}/selinux/config
FILE_CONTEXT=%{_sysconfdir}/selinux/targeted/contexts/files/file_contexts
selinuxenabled
@@ -406,13 +405,11 @@ fi
%{_sbindir}/ipa-compat-manage
%{_sbindir}/ipa-nis-manage
%{_sbindir}/ipa-host-net-manage
-%{_sbindir}/ipa_kpasswd
%{_sbindir}/ipactl
%{_sbindir}/ipa-upgradeconfig
%{_sbindir}/ipa-compliance
%{_sysconfdir}/cron.d/ipa-compliance
%attr(755,root,root) %{_initrddir}/ipa
-%attr(755,root,root) %{_initrddir}/ipa_kpasswd
%dir %{python_sitelib}/ipaserver
%{python_sitelib}/ipaserver/*
%dir %{_usr}/share/ipa
@@ -467,7 +464,6 @@ fi
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore
%dir %{_localstatedir}/cache/ipa
%attr(700,apache,apache) %dir %{_localstatedir}/cache/ipa/sessions
-%attr(700,root,root) %dir %{_localstatedir}/cache/ipa/kpasswd
%attr(755,root,root) %{_libdir}/krb5/plugins/kdb/ipadb.so
%{_mandir}/man1/ipa-replica-conncheck.1.gz
%{_mandir}/man1/ipa-replica-install.1.gz
@@ -482,14 +478,12 @@ fi
%{_mandir}/man1/ipa-nis-manage.1.gz
%{_mandir}/man1/ipa-host-net-manage.1.gz
%{_mandir}/man1/ipa-ldap-updater.1.gz
-%{_mandir}/man8/ipa_kpasswd.8.gz
%{_mandir}/man8/ipactl.8.gz
%{_mandir}/man1/ipa-compliance.1.gz
%files server-selinux
%defattr(-,root,root,-)
%doc COPYING README Contributors.txt
-%{_usr}/share/selinux/targeted/ipa_kpasswd.pp
%{_usr}/share/selinux/targeted/ipa_httpd.pp
%{_usr}/share/selinux/targeted/ipa_dogtag.pp
%endif
@@ -540,6 +534,9 @@ fi
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf
%changelog
+* Wed Aug 25 2011 Simo Sorce <ssorce#redhat.com> - 3.0.0
+- Remove ipa_kpasswd.
+
* Tue Aug 23 2011 Jan Cholasta <jcholast@redhat.com> - 2.1.0-1
- Add subscription-manager dependency for RHEL.
diff --git a/install/tools/man/Makefile.am b/install/tools/man/Makefile.am
index 973e913ca..71d9b29c8 100644
--- a/install/tools/man/Makefile.am
+++ b/install/tools/man/Makefile.am
@@ -22,7 +22,6 @@ man1_MANS = \
man8_MANS = \
ipactl.8 \
- ipa_kpasswd.8 \
$(NULL)
install-data-hook:
diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1
index a247c19b7..a06b849c4 100644
--- a/install/tools/man/ipa-server-install.1
+++ b/install/tools/man/ipa-server-install.1
@@ -22,7 +22,7 @@ ipa\-server\-install \- Configure an IPA server
.SH "SYNOPSIS"
ipa\-server\-install [\fIOPTION\fR]...
.SH "DESCRIPTION"
-Configures the services needed by an IPA server. This includes setting up a Kerberos Key Distribution Center (KDC) with an LDAP back\-end, configuring Apache, configuring NTP and starting the ipa_kpasswd service provided by IPA. By default a dogtag\-based CA will be configured to issue server certificates.
+Configures the services needed by an IPA server. This includes setting up a Kerberos Key Distribution Center (KDC) and a Kadmin daemon with an LDAP back\-end, configuring Apache, configuring NTP and optionally configuring and starting an LDAP-backed DNS server. By default a dogtag\-based CA will be configured to issue server certificates.
.SH "OPTIONS"
.TP
\fB\-r\fR \fIREALM_NAME\fR, \fB\-\-realm\fR=\fIREALM_NAME\fR
diff --git a/install/tools/man/ipa_kpasswd.8 b/install/tools/man/ipa_kpasswd.8
deleted file mode 100644
index 3c0d8105d..000000000
--- a/install/tools/man/ipa_kpasswd.8
+++ /dev/null
@@ -1,36 +0,0 @@
-.\" A man page for ipa_kpasswd
-.\" Copyright (C) 2008 Red Hat, Inc.
-.\"
-.\" 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, either version 3 of the License, or
-.\" (at your option) any later version.
-.\"
-.\" 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, see <http://www.gnu.org/licenses/>.
-.\"
-.\" Author: Rob Crittenden <rcritten@redhat.com>
-.\"
-.TH "ipa_kpasswd" "8" "Mar 14 2008" "freeipa" ""
-.SH "NAME"
-ipa_kpasswd \- Proxy Kerberos password change requests
-.SH "SYNOPSIS"
-ipa_kpasswd
-.SH "DESCRIPTION"
-Implementation of the kpasswd protocol (RFC 3244).
-
-It is used to proxy password change operations to Directory Server.
-.SH "ENVIRONMENT VARIABLES"
-.TP
-KRB5_KTNAME
-Location of the keytab to be used by ipa_kpasswd
-.TP
-IPA_KPASSWD_DEBUG
-Enable additional syslog output from ipa_kpasswd. Setting greater than 0 gets basic output. Setting higher than 100 gets more.
-.SH "EXIT STATUS"
-\-1 if an error occurred
diff --git a/ipa.1 b/ipa.1
index e5f0c6dbe..4c8ba377e 100644
--- a/ipa.1
+++ b/ipa.1
@@ -192,7 +192,7 @@ IPA default configuration file.
2 If an entry is not found
.SH "SEE ALSO"
ipa\-client\-install(1), ipa\-compat\-manage(1), ipactl(1), ipa\-dns\-install(1),
-ipa\-getcert(1), ipa\-getkeytab(1), ipa\-join(1), ipa_kpasswd(1), ipa\-ldap\-updater(1),
+ipa\-getcert(1), ipa\-getkeytab(1), ipa\-join(1), ipa\-ldap\-updater(1),
ipa\-nis\-manage(1), ipa\-replica\-install(1), ipa\-replica\-manage(1), ipa\-replica\-prepare(1),
ipa\-rmkeytab(1), ipa\-server\-certinstall(2), ipa\-server\-install(1), ipa\-upgradeconfig(1),
ipa\-host\-net\-manage(1)
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 7f77fc1eb..9956b9fb7 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -71,7 +71,7 @@ def update_key_val_in_file(filename, key, val):
class KpasswdInstance(service.SimpleServiceInstance):
def __init__(self):
- service.SimpleServiceInstance.__init__(self, "ipa_kpasswd")
+ service.SimpleServiceInstance.__init__(self, "kadmin")
class KrbInstance(service.Service):
def __init__(self, fstore=None):
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 62db9baf5..2f80749ad 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -34,7 +34,7 @@ CACERT = "/etc/ipa/ca.crt"
SERVICE_LIST = {
'KDC':('krb5kdc', 10),
- 'KPASSWD':('ipa_kpasswd', 20),
+ 'KPASSWD':('kadmin', 20),
'DNS':('named', 30),
'HTTP':('httpd', 40),
'CA':('pki-cad', 50)
diff --git a/selinux/Makefile b/selinux/Makefile
index 62b7bf7ed..9e87bdd8f 100644
--- a/selinux/Makefile
+++ b/selinux/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS = ipa_kpasswd ipa_httpd ipa_dogtag
+SUBDIRS = ipa_httpd ipa_dogtag
POLICY_MAKEFILE = /usr/share/selinux/devel/Makefile
POLICY_DIR = $(DESTDIR)/usr/share/selinux/targeted
@@ -21,9 +21,8 @@ maintainer-clean: distclean
install: all
install -d $(POLICY_DIR)
- install -m 644 ipa_kpasswd/ipa_kpasswd.pp $(POLICY_DIR)
install -m 644 ipa_httpd/ipa_httpd.pp $(POLICY_DIR)
install -m 644 ipa_dogtag/ipa_dogtag.pp $(POLICY_DIR)
load:
- /usr/sbin/semodule -i ipa_kpasswd/ipa_kpasswd.pp ipa_httpd/ipa_httpd.pp
+ /usr/sbin/semodule -i ipa_httpd/ipa_httpd.pp
diff --git a/selinux/ipa-server-selinux.spec.in b/selinux/ipa-server-selinux.spec.in
index 3387553ab..b3c7d89cf 100644
--- a/selinux/ipa-server-selinux.spec.in
+++ b/selinux/ipa-server-selinux.spec.in
@@ -36,7 +36,6 @@ make DESTDIR=%{buildroot} install
%files
%{_usr}/share/selinux/targeted/ipa_webgui.pp
-%{_usr}/share/selinux/targeted/ipa_kpasswd.pp
%define saveFileContext() \
@@ -61,7 +60,7 @@ fi;
%saveFileContext targeted
%post
-semodule -s targeted -i /usr/share/selinux/targeted/ipa_webgui.pp /usr/share/selinux/targeted/ipa_kpasswd.pp
+semodule -s targeted -i /usr/share/selinux/targeted/ipa_webgui.pp
%relabel targeted
%preun
@@ -71,7 +70,7 @@ fi
%postun
if [ $1 = 0 ]; then
-semodule -s targeted -r ipa_webgui ipa_kpasswd
+semodule -s targeted -r ipa_webgui
%relabel targeted
fi
diff --git a/selinux/ipa_kpasswd/ipa_kpasswd.fc b/selinux/ipa_kpasswd/ipa_kpasswd.fc
deleted file mode 100644
index 2dcf827dd..000000000
--- a/selinux/ipa_kpasswd/ipa_kpasswd.fc
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# /usr
-#
-/usr/sbin/ipa_kpasswd -- gen_context(system_u:object_r:ipa_kpasswd_exec_t,s0)
-
-#
-# /var
-#
-/var/cache/ipa/kpasswd(/.*)? gen_context(system_u:object_r:ipa_kpasswd_ccache_t,s0)
diff --git a/selinux/ipa_kpasswd/ipa_kpasswd.te b/selinux/ipa_kpasswd/ipa_kpasswd.te
deleted file mode 100644
index 292be7b89..000000000
--- a/selinux/ipa_kpasswd/ipa_kpasswd.te
+++ /dev/null
@@ -1,80 +0,0 @@
-policy_module(ipa_kpasswd, 1.0)
-
-########################################
-#
-# Declarations
-#
-
-type ipa_kpasswd_t;
-type ipa_kpasswd_exec_t;
-type ipa_kpasswd_var_run_t;
-type ipa_kpasswd_ccache_t;
-init_daemon_domain(ipa_kpasswd_t, ipa_kpasswd_exec_t)
-
-########################################
-#
-# IPA kpasswd local policy
-#
-
-allow ipa_kpasswd_t self:capability { sys_nice dac_override };
-allow ipa_kpasswd_t self:tcp_socket create_stream_socket_perms;
-allow ipa_kpasswd_t self:udp_socket create_socket_perms;
-
-files_read_etc_files(ipa_kpasswd_t)
-files_search_usr(ipa_kpasswd_t)
-
-files_pid_file(ipa_kpasswd_var_run_t);
-allow ipa_kpasswd_t ipa_kpasswd_var_run_t:file manage_file_perms;
-files_pid_filetrans(ipa_kpasswd_t,ipa_kpasswd_var_run_t,file)
-
-auth_use_nsswitch(ipa_kpasswd_t)
-
-libs_use_ld_so(ipa_kpasswd_t)
-libs_use_shared_libs(ipa_kpasswd_t)
-
-logging_send_syslog_msg(ipa_kpasswd_t)
-
-miscfiles_read_localization(ipa_kpasswd_t)
-
-kerberos_use(ipa_kpasswd_t)
-kerberos_manage_host_rcache(ipa_kpasswd_t)
-kerberos_read_kdc_config(ipa_kpasswd_t)
-
-kernel_read_system_state(ipa_kpasswd_t)
-
-# /var/cache/ipa/kpasswd
-files_type(ipa_kpasswd_ccache_t)
-manage_dirs_pattern(ipa_kpasswd_t, ipa_kpasswd_ccache_t, ipa_kpasswd_ccache_t)
-manage_files_pattern(ipa_kpasswd_t, ipa_kpasswd_ccache_t, ipa_kpasswd_ccache_t)
-files_var_filetrans(ipa_kpasswd_t, ipa_kpasswd_ccache_t,dir)
-
-kernel_read_network_state(ipa_kpasswd_t)
-kernel_read_network_state_symlinks(ipa_kpasswd_t)
-
-corenet_tcp_sendrecv_all_if(ipa_kpasswd_t)
-corenet_udp_sendrecv_all_if(ipa_kpasswd_t)
-corenet_raw_sendrecv_all_if(ipa_kpasswd_t)
-corenet_tcp_sendrecv_all_nodes(ipa_kpasswd_t)
-corenet_udp_sendrecv_all_nodes(ipa_kpasswd_t)
-corenet_raw_sendrecv_all_nodes(ipa_kpasswd_t)
-corenet_tcp_sendrecv_all_ports(ipa_kpasswd_t)
-corenet_udp_sendrecv_all_ports(ipa_kpasswd_t)
-corenet_non_ipsec_sendrecv(ipa_kpasswd_t)
-corenet_tcp_bind_all_nodes(ipa_kpasswd_t)
-corenet_udp_bind_all_nodes(ipa_kpasswd_t)
-corenet_tcp_bind_kerberos_admin_port(ipa_kpasswd_t)
-corenet_udp_bind_kerberos_admin_port(ipa_kpasswd_t)
-require {
- type krb5kdc_conf_t;
-};
-
-allow ipa_kpasswd_t krb5kdc_conf_t:dir search_dir_perms;
-
-optional_policy(`
- gen_require(`
- type kerberos_password_port_t;
- ')
- corenet_tcp_bind_kerberos_password_port(ipa_kpasswd_t)
- corenet_udp_bind_kerberos_password_port(ipa_kpasswd_t)
-')
-