| File: | client/ipa-rmkeytab.c |
| Warning: | line 114, column 5 Value stored to 'krberr' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* Authors: Rob Crittenden <rcritten@redhat.com> |
| 2 | * |
| 3 | * Copyright (C) 2009 Red Hat |
| 4 | * see file 'COPYING' for use and warranty information |
| 5 | * |
| 6 | * This program is free software you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation, either version 3 of the License, or |
| 9 | * (at your option) any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ |
| 19 | |
| 20 | #define _GNU_SOURCE |
| 21 | #include <stdlib.h> |
| 22 | #include <stdbool.h> |
| 23 | #include <stdio.h> |
| 24 | #include <string.h> |
| 25 | #include <krb5.h> |
| 26 | #include <popt.h> |
| 27 | #include <errno(*__errno_location ()).h> |
| 28 | |
| 29 | #include "ipa-client-common.h" |
| 30 | #include "config.h" |
| 31 | |
| 32 | int |
| 33 | remove_principal(krb5_context context, krb5_keytab ktid, const char *principal, int debug) |
| 34 | { |
| 35 | krb5_error_code krberr; |
| 36 | krb5_keytab_entry entry, entry2; |
| 37 | int rval = 0; |
| 38 | int removed = 0; |
| 39 | |
| 40 | memset(&entry, 0, sizeof(entry)); |
| 41 | krberr = krb5_parse_name(context, principal, &entry.principal); |
| 42 | if (krberr) { |
| 43 | fprintf(stderrstderr, _("Unable to parse principal name\n")gettext("Unable to parse principal name\n")); |
| 44 | if (debug) |
| 45 | fprintf(stderrstderr, _("krb5_parse_name %1$d: %2$s\n")gettext("krb5_parse_name %1$d: %2$s\n"), |
| 46 | krberr, error_message(krberr)); |
| 47 | rval = 4; |
| 48 | goto done; |
| 49 | } |
| 50 | |
| 51 | /* Loop through the keytab and remove all entries with this principal name |
| 52 | * irrespective of the encryption type. A failure to find one after the |
| 53 | * first means we're done. |
| 54 | */ |
| 55 | fprintf(stderrstderr, _("Removing principal %s\n")gettext("Removing principal %s\n"), principal); |
| 56 | while (1) { |
| 57 | memset(&entry2, 0, sizeof(entry2)); |
| 58 | krberr = krb5_kt_get_entry(context, ktid, |
| 59 | entry.principal, |
| 60 | 0, |
| 61 | 0, |
| 62 | &entry2); |
| 63 | if (krberr) { |
| 64 | if (removed > 0) |
| 65 | /* not found but we've removed some, we're done */ |
| 66 | break; |
| 67 | if (krberr == ENOENT2) { |
| 68 | fprintf(stderrstderr, _("Failed to open keytab\n")gettext("Failed to open keytab\n")); |
| 69 | rval = 3; |
| 70 | goto done; |
| 71 | } |
| 72 | fprintf(stderrstderr, _("principal not found\n")gettext("principal not found\n")); |
| 73 | if (debug) |
| 74 | fprintf(stderrstderr, _("krb5_kt_get_entry %1$d: %2$s\n")gettext("krb5_kt_get_entry %1$d: %2$s\n"), |
| 75 | krberr, error_message(krberr)); |
| 76 | rval = 5; |
| 77 | break; |
| 78 | } |
| 79 | |
| 80 | krberr = krb5_kt_remove_entry(context, ktid, &entry2); |
| 81 | if (krberr) { |
| 82 | fprintf(stderrstderr, _("Unable to remove entry\n")gettext("Unable to remove entry\n")); |
| 83 | if (debug) { |
| 84 | fprintf(stdoutstdout, _("kvno %d\n")gettext("kvno %d\n"), entry2.vno); |
| 85 | fprintf(stderrstderr, _("krb5_kt_remove_entry %1$d: %2$s\n")gettext("krb5_kt_remove_entry %1$d: %2$s\n"), |
| 86 | krberr, error_message(krberr)); |
| 87 | } |
| 88 | rval = 6; |
| 89 | break; |
| 90 | } |
| 91 | |
| 92 | krb5_free_keytab_entry_contents(context, &entry2); |
| 93 | removed++; |
| 94 | } |
| 95 | |
| 96 | if (entry2.principal) |
| 97 | krb5_free_keytab_entry_contents(context, &entry2); |
| 98 | |
| 99 | done: |
| 100 | |
| 101 | return rval; |
| 102 | } |
| 103 | |
| 104 | int |
| 105 | remove_realm(krb5_context context, krb5_keytab ktid, const char *realm, int debug) |
| 106 | { |
| 107 | krb5_error_code krberr; |
| 108 | krb5_keytab_entry entry; |
| 109 | krb5_kt_cursor kt_cursor; |
| 110 | char * entry_princ_s = NULL((void*)0); |
| 111 | int rval = 0; |
| 112 | bool_Bool realm_found = false0; |
| 113 | |
| 114 | krberr = krb5_kt_start_seq_get(context, ktid, &kt_cursor); |
Value stored to 'krberr' is never read | |
| 115 | memset(&entry, 0, sizeof(entry)); |
| 116 | while (krb5_kt_next_entry(context, ktid, &entry, &kt_cursor) == 0) { |
| 117 | krberr = krb5_unparse_name(context, entry.principal, &entry_princ_s); |
| 118 | if (krberr) { |
| 119 | fprintf(stderrstderr, _("Unable to parse principal\n")gettext("Unable to parse principal\n")); |
| 120 | if (debug) { |
| 121 | fprintf(stderrstderr, _("krb5_unparse_name %1$d: %2$s\n")gettext("krb5_unparse_name %1$d: %2$s\n"), |
| 122 | krberr, error_message(krberr)); |
| 123 | } |
| 124 | rval = 4; |
| 125 | goto done; |
| 126 | } |
| 127 | |
| 128 | /* keytab entries are locked when looping. Temporarily suspend |
| 129 | * the looping. */ |
| 130 | krb5_kt_end_seq_get(context, ktid, &kt_cursor); |
| 131 | |
| 132 | if (strstr(entry_princ_s, realm) != NULL((void*)0)) { |
| 133 | realm_found = true1; |
| 134 | rval = remove_principal(context, ktid, entry_princ_s, debug); |
| 135 | if (rval != 0) |
| 136 | goto done; |
| 137 | /* Have to reset the cursor */ |
| 138 | krberr = krb5_kt_start_seq_get(context, ktid, &kt_cursor); |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | if (!realm_found) { |
| 143 | fprintf(stderrstderr, _("realm not found\n")gettext("realm not found\n")); |
| 144 | return 5; |
| 145 | } |
| 146 | |
| 147 | done: |
| 148 | |
| 149 | return rval; |
| 150 | } |
| 151 | |
| 152 | int |
| 153 | main(int argc, const char **argv) |
| 154 | { |
| 155 | krb5_context context; |
| 156 | krb5_error_code krberr; |
| 157 | krb5_keytab ktid; |
| 158 | krb5_kt_cursor cursor; |
| 159 | char * ktname = NULL((void*)0); |
| 160 | char * atrealm = NULL((void*)0); |
| 161 | poptContext pc; |
| 162 | static const char *keytab = NULL((void*)0); |
| 163 | static const char *principal = NULL((void*)0); |
| 164 | static const char *realm = NULL((void*)0); |
| 165 | int debug = 0; |
| 166 | int ret, rval = 0; |
| 167 | struct poptOption options[] = { |
| 168 | { "debug", 'd', POPT_ARG_NONE0U, &debug, 0, |
| 169 | _("Print debugging information")gettext("Print debugging information"), _("Debugging output")gettext("Debugging output") }, |
| 170 | { "principal", 'p', POPT_ARG_STRING1U, &principal, 0, |
| 171 | _("The principal to remove from the keytab (ex: ftp/ftp.example.com@EXAMPLE.COM)")gettext("The principal to remove from the keytab (ex: ftp/ftp.example.com@EXAMPLE.COM)" ), |
| 172 | _("Kerberos Service Principal Name")gettext("Kerberos Service Principal Name") }, |
| 173 | { "keytab", 'k', POPT_ARG_STRING1U, &keytab, 0, |
| 174 | _("The keytab file to remove the principcal(s) from")gettext("The keytab file to remove the principcal(s) from"), _("Keytab File Name")gettext("Keytab File Name") }, |
| 175 | { "realm", 'r', POPT_ARG_STRING1U, &realm, 0, |
| 176 | _("Remove all principals in this realm")gettext("Remove all principals in this realm"), _("Realm name")gettext("Realm name") }, |
| 177 | POPT_AUTOHELP{ ((void*)0), '\0', 4U, poptHelpOptions, 0, "Help options:", ( (void*)0) }, |
| 178 | POPT_TABLEEND{ ((void*)0), '\0', 0, ((void*)0), 0, ((void*)0), ((void*)0) } |
| 179 | }; |
| 180 | |
| 181 | ret = init_gettext(); |
| 182 | if (ret) { |
| 183 | fprintf(stderrstderr, "Failed to load translations\n"); |
| 184 | } |
| 185 | |
| 186 | memset(&ktid, 0, sizeof(ktid)); |
| 187 | |
| 188 | krberr = krb5_init_context(&context); |
| 189 | if (krberr) { |
| 190 | fprintf(stderrstderr, _("Kerberos context initialization failed\n")gettext("Kerberos context initialization failed\n")); |
| 191 | exit(1); |
| 192 | } |
| 193 | |
| 194 | pc = poptGetContext("ipa-rmkeytab", argc, (const char **)argv, options, 0); |
| 195 | ret = poptGetNextOpt(pc); |
| 196 | if (ret != -1 || (!principal && !realm) || !keytab) { |
| 197 | poptPrintUsage(pc, stderrstderr, 0); |
| 198 | rval = 1; |
| 199 | goto cleanup; |
| 200 | } |
| 201 | |
| 202 | ret = asprintf(&ktname, "WRFILE:%s", keytab); |
| 203 | if (ret == -1) { |
| 204 | rval = 2; |
| 205 | goto cleanup; |
| 206 | } |
| 207 | |
| 208 | /* The remove_realm function just does a substring match. Ensure that |
| 209 | * the string we pass in looks like a realm. |
| 210 | */ |
| 211 | if (realm) { |
| 212 | if (realm[0] != '@') { |
| 213 | ret = asprintf(&atrealm, "@%s", realm); |
| 214 | if (ret == -1) { |
| 215 | rval = 2; |
| 216 | goto cleanup; |
| 217 | } |
| 218 | } else { |
| 219 | atrealm = strdup(realm); |
| 220 | |
| 221 | if (NULL((void*)0) == atrealm) { |
| 222 | rval = 2; |
| 223 | goto cleanup; |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | krberr = krb5_kt_resolve(context, ktname, &ktid); |
| 229 | if (krberr) { |
| 230 | fprintf(stderrstderr, _("Failed to open keytab '%1$s': %2$s\n")gettext("Failed to open keytab '%1$s': %2$s\n"), keytab, |
| 231 | error_message(krberr)); |
| 232 | rval = 3; |
| 233 | goto cleanup; |
| 234 | } |
| 235 | krberr = krb5_kt_start_seq_get(context, ktid, &cursor); |
| 236 | if (krberr) { |
| 237 | fprintf(stderrstderr, _("Failed to open keytab '%1$s': %2$s\n")gettext("Failed to open keytab '%1$s': %2$s\n"), keytab, |
| 238 | error_message(krberr)); |
| 239 | rval = 3; |
| 240 | goto cleanup; |
| 241 | } |
| 242 | krb5_kt_end_seq_get(context, ktid, &cursor); |
| 243 | |
| 244 | if (principal) |
| 245 | rval = remove_principal(context, ktid, principal, debug); |
| 246 | else if (realm) |
| 247 | rval = remove_realm(context, ktid, atrealm, debug); |
| 248 | |
| 249 | cleanup: |
| 250 | if (rval == 0 || rval > 3) { |
| 251 | krberr = krb5_kt_close(context, ktid); |
| 252 | if (krberr) { |
| 253 | fprintf(stderrstderr, _("Closing keytab failed\n")gettext("Closing keytab failed\n")); |
| 254 | if (debug) |
| 255 | fprintf(stderrstderr, _("krb5_kt_close %1$d: %2$s\n")gettext("krb5_kt_close %1$d: %2$s\n"), |
| 256 | krberr, error_message(krberr)); |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | krb5_free_context(context); |
| 261 | |
| 262 | poptFreeContext(pc); |
| 263 | |
| 264 | free(atrealm); |
| 265 | free(ktname); |
| 266 | |
| 267 | return rval; |
| 268 | } |