diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | daemons/Makefile.am | 1 | ||||
-rw-r--r-- | daemons/configure.ac | 1 | ||||
-rw-r--r-- | daemons/ipa-kpasswd/Makefile.am | 59 | ||||
-rw-r--r-- | daemons/ipa-kpasswd/README | 2 | ||||
-rw-r--r-- | daemons/ipa-kpasswd/ipa_kpasswd.c | 1408 | ||||
-rw-r--r-- | daemons/ipa-kpasswd/ipa_kpasswd.init | 83 | ||||
-rw-r--r-- | freeipa.spec.in | 15 | ||||
-rw-r--r-- | install/tools/man/Makefile.am | 1 | ||||
-rw-r--r-- | install/tools/man/ipa-server-install.1 | 2 | ||||
-rw-r--r-- | install/tools/man/ipa_kpasswd.8 | 36 | ||||
-rw-r--r-- | ipa.1 | 2 | ||||
-rw-r--r-- | ipaserver/install/krbinstance.py | 2 | ||||
-rw-r--r-- | ipaserver/install/service.py | 2 | ||||
-rw-r--r-- | selinux/Makefile | 5 | ||||
-rw-r--r-- | selinux/ipa-server-selinux.spec.in | 5 | ||||
-rw-r--r-- | selinux/ipa_kpasswd/ipa_kpasswd.fc | 9 | ||||
-rw-r--r-- | selinux/ipa_kpasswd/ipa_kpasswd.te | 80 |
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 @@ -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) -') - |