mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
A utility for removing principals from a keytab.
When we un-enroll a client we'll do a bit of cleanup including removing any principals for the IPA realm from /etc/krb5.keytab. This removes principals in 2 ways: - By principal, only entries matching the full principal are removed - By realm. Any principal for that realm is removed This does not change the KDC at all, just removes entries from a file on the client machine.
This commit is contained in:
@@ -22,6 +22,7 @@ INCLUDES = \
|
||||
|
||||
sbin_PROGRAMS = \
|
||||
ipa-getkeytab \
|
||||
ipa-rmkeytab \
|
||||
ipa-join \
|
||||
$(NULL)
|
||||
|
||||
@@ -37,6 +38,15 @@ ipa_getkeytab_LDADD = \
|
||||
$(POPT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ipa_rmkeytab_SOURCES = \
|
||||
ipa-rmkeytab.c \
|
||||
$(NULL)
|
||||
|
||||
ipa_rmkeytab_LDADD = \
|
||||
$(KRB5_LIBS) \
|
||||
$(POPT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ipa_join_SOURCES = \
|
||||
config.c \
|
||||
ipa-join.c \
|
||||
|
||||
218
ipa-client/ipa-rmkeytab.c
Normal file
218
ipa-client/ipa-rmkeytab.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/* Authors: Rob Crittenden <rcritten@redhat.com>
|
||||
*
|
||||
* Copyright (C) 2009 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; version 2 only
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <krb5.h>
|
||||
#include <popt.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
remove_principal(krb5_context context, krb5_keytab ktid, const char *principal, int debug)
|
||||
{
|
||||
krb5_error_code krberr;
|
||||
krb5_keytab_entry entry, entry2;
|
||||
int rval = 0;
|
||||
int removed = 0;
|
||||
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
krberr = krb5_parse_name(context, principal, &entry.principal);
|
||||
if (krberr) {
|
||||
fprintf(stderr, "Unable to parse principal name\n");
|
||||
if (debug)
|
||||
fprintf(stderr, "krb5_parse_name %d: %s\n", krberr, error_message(krberr));
|
||||
rval = 4;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Loop through the keytab and remove all entries with this principal name
|
||||
* irrespective of the encryption type. A failure to find one after the
|
||||
* first means we're done.
|
||||
*/
|
||||
fprintf(stderr, "Removing principal %s\n", principal);
|
||||
while (1) {
|
||||
memset(&entry2, 0, sizeof(entry2));
|
||||
krberr = krb5_kt_get_entry(context, ktid,
|
||||
entry.principal,
|
||||
0,
|
||||
0,
|
||||
&entry2);
|
||||
if (krberr) {
|
||||
if (removed > 0)
|
||||
/* not found but we've removed some, we're done */
|
||||
break;
|
||||
if (krberr == ENOENT) {
|
||||
fprintf(stderr, "Failed to open keytab\n");
|
||||
rval = 3;
|
||||
goto done;
|
||||
}
|
||||
fprintf(stderr, "principal not found\n");
|
||||
if (debug)
|
||||
fprintf(stderr, "krb5_kt_get_entry %d: %s\n", krberr, error_message(krberr));
|
||||
rval = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
krberr = krb5_kt_remove_entry(context, ktid, &entry2);
|
||||
if (krberr) {
|
||||
fprintf(stderr, "Unable to remove entry\n");
|
||||
if (debug) {
|
||||
fprintf(stdout, "kvno %d\n", entry2.vno);
|
||||
fprintf(stderr, "krb5_kt_remove_entry %d: %s\n", krberr, error_message(krberr));
|
||||
}
|
||||
rval = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
krb5_free_keytab_entry_contents(context, &entry2);
|
||||
removed++;
|
||||
}
|
||||
|
||||
if (entry2.principal)
|
||||
krb5_free_keytab_entry_contents(context, &entry2);
|
||||
|
||||
done:
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
remove_realm(krb5_context context, krb5_keytab ktid, const char *realm, int debug)
|
||||
{
|
||||
krb5_error_code krberr;
|
||||
krb5_keytab_entry entry;
|
||||
krb5_kt_cursor kt_cursor;
|
||||
char * entry_princ_s = NULL;
|
||||
int rval = 0;
|
||||
|
||||
krberr = krb5_kt_start_seq_get(context, ktid, &kt_cursor);
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
while (krb5_kt_next_entry(context, ktid, &entry, &kt_cursor) == 0) {
|
||||
krberr = krb5_unparse_name(context, entry.principal, &entry_princ_s);
|
||||
if (krberr) {
|
||||
fprintf(stderr, "Unable to parse principal\n");
|
||||
if (debug) {
|
||||
fprintf(stderr, "krb5_unparse_name %d: %s\n", krberr, error_message(krberr));
|
||||
}
|
||||
rval = 4;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (strstr(entry_princ_s, realm) != NULL) {
|
||||
rval = remove_principal(context, ktid, entry_princ_s, debug);
|
||||
if (rval != 0)
|
||||
goto done;
|
||||
/* Have to reset the cursor */
|
||||
krberr = krb5_kt_start_seq_get(context, ktid, &kt_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
krb5_context context;
|
||||
krb5_error_code krberr;
|
||||
krb5_keytab ktid;
|
||||
char * ktname;
|
||||
char * atrealm;
|
||||
poptContext pc;
|
||||
static const char *keytab = NULL;
|
||||
static const char *principal = NULL;
|
||||
static const char *realm = NULL;
|
||||
int debug = 0;
|
||||
int ret, rval;
|
||||
struct poptOption options[] = {
|
||||
{ "debug", 'd', POPT_ARG_NONE, &debug, 0, "Print debugging information", "Debugging output" },
|
||||
{ "principal", 'p', POPT_ARG_STRING, &principal, 0, "The principal to get a keytab for (ex: ftp/ftp.example.com@EXAMPLE.COM)", "Kerberos Service Principal Name" },
|
||||
{ "keytab", 'k', POPT_ARG_STRING, &keytab, 0, "File were to store the keytab information", "Keytab File Name" },
|
||||
{ "realm", 'r', POPT_ARG_STRING, &realm, 0, "Remove all principals in this realm", "Realm name" },
|
||||
{ NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
memset(&ktid, 0, sizeof(ktid));
|
||||
|
||||
krberr = krb5_init_context(&context);
|
||||
if (krberr) {
|
||||
fprintf(stderr, "Kerberos context initialization failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pc = poptGetContext("ipa-rmkeytab", argc, (const char **)argv, options, 0);
|
||||
ret = poptGetNextOpt(pc);
|
||||
if (ret != -1 || (!principal && !realm) || !keytab) {
|
||||
poptPrintUsage(pc, stderr, 0);
|
||||
rval = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = asprintf(&ktname, "WRFILE:%s", keytab);
|
||||
if (ret == -1) {
|
||||
rval = 2;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* The remove_realm function just does a substring match. Ensure that
|
||||
* the string we pass in looks like a realm.
|
||||
*/
|
||||
if (realm) {
|
||||
if (realm[0] != '@')
|
||||
ret = asprintf(&atrealm, "@%s", realm);
|
||||
if (ret == -1) {
|
||||
rval = 2;
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
atrealm = strcpy(atrealm, realm);
|
||||
}
|
||||
|
||||
krberr = krb5_kt_resolve(context, ktname, &ktid);
|
||||
if (krberr) {
|
||||
fprintf(stderr, "Failed to open keytab '%s'\n", keytab);
|
||||
rval = 3;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (principal)
|
||||
rval = remove_principal(context, ktid, principal, debug);
|
||||
else if (realm)
|
||||
rval = remove_realm(context, ktid, atrealm, debug);
|
||||
|
||||
cleanup:
|
||||
if (rval == 0 || rval > 3) {
|
||||
krberr = krb5_kt_close(context, ktid);
|
||||
if (krberr) {
|
||||
fprintf(stderr, "Closing keytab failed\n");
|
||||
if (debug)
|
||||
fprintf(stderr, "krb5_kt_close %d: %s\n", krberr, error_message(krberr));
|
||||
}
|
||||
}
|
||||
|
||||
krb5_free_context(context);
|
||||
|
||||
poptFreeContext(pc);
|
||||
|
||||
return rval;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ NULL =
|
||||
|
||||
man_MANS = \
|
||||
ipa-getkeytab.1 \
|
||||
ipa-rmkeytab.1 \
|
||||
ipa-client-install.1 \
|
||||
ipa-join.1
|
||||
|
||||
|
||||
90
ipa-client/man/ipa-rmkeytab.1
Normal file
90
ipa-client/man/ipa-rmkeytab.1
Normal file
@@ -0,0 +1,90 @@
|
||||
.\" A man page for ipa-rmkeytab
|
||||
.\" Copyright (C) 2009 Red Hat, Inc.
|
||||
.\"
|
||||
.\" This is free software; you can redistribute it and/or modify it under
|
||||
.\" the terms of the GNU Library General Public License as published by
|
||||
.\" the Free Software Foundation; version 2 only
|
||||
.\"
|
||||
.\" 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 Library General Public
|
||||
.\" License along with this program; if not, write to the Free Software
|
||||
.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
.\"
|
||||
.\" Author: Rob Crittenden <rcritten@redhat.com>
|
||||
.\"
|
||||
.\"
|
||||
.TH "ipa-rmkeytab" "1" "Oct 30 2009" "freeipa" ""
|
||||
.SH "NAME"
|
||||
ipa\-rmkeytab \- Remove a kerberos principal from a keytab
|
||||
.SH "SYNOPSIS"
|
||||
ipa\-rmkeytab [ \fB\-p\fR principal\-name ] [ \fB\-k\fR keytab\-file ] [ \fB\-r\fR realm ] [ \fB\-d\fR ]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
Removes a kerberos principal from a \fIkeytab\fR.
|
||||
|
||||
Kerberos keytabs are used for services (like sshd) to
|
||||
perform kerberos authentication. A keytab is a file
|
||||
with one or more secrets (or keys) for a kerberos
|
||||
principal.
|
||||
|
||||
A kerberos service principal is a kerberos identity
|
||||
that can be used for authentication. Service principals
|
||||
contain the name of the service, the hostname of the
|
||||
server, and the realm name.
|
||||
|
||||
ipa\-rmkeytab provides two ways to remove principals.
|
||||
A specific principal can be removed or all principals for all
|
||||
principals for a given realm can be removed.
|
||||
|
||||
All encryption types and versions of a principal are removed.
|
||||
|
||||
The realm may be included when removing a specific principal but
|
||||
it is not required.
|
||||
|
||||
\fBNOTE:\fR removing a principal from the keytab does not affect
|
||||
the Kerberos principal stored in the IPA server. It merely removes
|
||||
the entry from the local keytab.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
\fB\-p principal\-name\fR
|
||||
The non\-realm part of the full principal name.
|
||||
.TP
|
||||
\fB\-k keytab\-file\fR
|
||||
The keytab file where to append the new key (will be
|
||||
created if it does not exist).
|
||||
.TP
|
||||
\fB\-r realm\fR
|
||||
A realm to remove all principals for.
|
||||
.TP
|
||||
\fB\-d\fR
|
||||
Debug mode. Additional information is displayed.
|
||||
.SH "EXAMPLES"
|
||||
Remove the NFS service principal on the host foo.example.com from /tmp/nfs.keytab.
|
||||
|
||||
# ipa\-rmkeytab \-p nfs/foo.example.com \-k /tmp/nfs.keytab
|
||||
|
||||
Remove the ldap service principal onthe host foo.example.com from /etc/krb5.keytab.
|
||||
|
||||
# ipa\-rmkeytab \-p ldap/foo.example.com \-k /tmp/ldap.keytab
|
||||
|
||||
Remove all principals for the realm EXAMPLE.COM.
|
||||
|
||||
# ipa\-rmkeytab \-r EXAMPLE.COM \-k /tmp/ldap.keytab
|
||||
.SH "EXIT STATUS"
|
||||
The exit status is 0 on success, nonzero on error.
|
||||
|
||||
1 Kerberos initialization failed
|
||||
|
||||
2 Memory allocation error
|
||||
|
||||
3 Unable to open keytab
|
||||
|
||||
4 Unable to parse the principal name
|
||||
|
||||
5 Principal name not found in keytab
|
||||
|
||||
6 Unable to remove principal from keytab
|
||||
@@ -425,6 +425,7 @@ fi
|
||||
%doc LICENSE README
|
||||
%{_sbindir}/ipa-client-install
|
||||
%{_sbindir}/ipa-getkeytab
|
||||
%{_sbindir}/ipa-rmkeytab
|
||||
%{_sbindir}/ipa-join
|
||||
%dir %{_usr}/share/ipa
|
||||
%dir %{_usr}/share/ipa/ipaclient
|
||||
@@ -435,6 +436,7 @@ fi
|
||||
%dir %{python_sitelib}/ipaclient
|
||||
%{python_sitelib}/ipaclient/*.py*
|
||||
%{_mandir}/man1/ipa-getkeytab.1.gz
|
||||
%{_mandir}/man1/ipa-rmkeytab.1.gz
|
||||
%{_mandir}/man1/ipa-client-install.1.gz
|
||||
%{_mandir}/man1/ipa-join.1.gz
|
||||
|
||||
@@ -482,6 +484,9 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Dec 4 2009 Rob Crittenden <rcritten@redhat.com> - 1.99-13
|
||||
- Add ipa-rmkeytab tool
|
||||
|
||||
* Tue Dec 1 2009 Rob Crittenden <rcritten@redhat.com> - 1.99-12
|
||||
- Set minimum of python-pyasn1 to 0.0.9a so we have support for the ASN.1
|
||||
Any type
|
||||
|
||||
Reference in New Issue
Block a user