167754Smsmith/*
267754Smsmith * Copyright (c) 2001-2004 Kungliga Tekniska H��gskolan
367754Smsmith * (Royal Institute of Technology, Stockholm, Sweden).
467754Smsmith * All rights reserved.
567754Smsmith *
667754Smsmith * Redistribution and use in source and binary forms, with or without
767754Smsmith * modification, are permitted provided that the following conditions
867754Smsmith * are met:
967754Smsmith *
1067754Smsmith * 1. Redistributions of source code must retain the above copyright
11193267Sjkim *    notice, this list of conditions and the following disclaimer.
1270243Smsmith *
1367754Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1467754Smsmith *    notice, this list of conditions and the following disclaimer in the
1567754Smsmith *    documentation and/or other materials provided with the distribution.
1667754Smsmith *
1767754Smsmith * 3. Neither the name of the Institute nor the names of its contributors
1867754Smsmith *    may be used to endorse or promote products derived from this software
1967754Smsmith *    without specific prior written permission.
2067754Smsmith *
2167754Smsmith * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2267754Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2367754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2467754Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2567754Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2667754Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2767754Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2867754Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2967754Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3067754Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3167754Smsmith * SUCH DAMAGE.
3267754Smsmith */
3367754Smsmith
3467754Smsmith#include "ktutil_locl.h"
3567754Smsmith
3667754SmsmithRCSID("$Id$");
3767754Smsmith
3867754Smsmithint
3967754Smsmithkt_rename(struct rename_options *opt, int argc, char **argv)
4067754Smsmith{
4167754Smsmith    krb5_error_code ret = 0;
4267754Smsmith    krb5_keytab_entry entry;
4367754Smsmith    krb5_keytab keytab;
4467754Smsmith    krb5_kt_cursor cursor;
4567754Smsmith    krb5_principal from_princ, to_princ;
4667754Smsmith
4767754Smsmith    ret = krb5_parse_name(context, argv[0], &from_princ);
4867754Smsmith    if(ret != 0) {
4967754Smsmith	krb5_warn(context, ret, "%s", argv[0]);
5067754Smsmith	return 1;
5167754Smsmith    }
5267754Smsmith
5367754Smsmith    ret = krb5_parse_name(context, argv[1], &to_princ);
5467754Smsmith    if(ret != 0) {
5567754Smsmith	krb5_free_principal(context, from_princ);
5667754Smsmith	krb5_warn(context, ret, "%s", argv[1]);
5767754Smsmith	return 1;
5867754Smsmith    }
5967754Smsmith
6067754Smsmith    if((keytab = ktutil_open_keytab()) == NULL) {
6167754Smsmith	krb5_free_principal(context, from_princ);
6267754Smsmith	krb5_free_principal(context, to_princ);
6367754Smsmith	return 1;
6467754Smsmith    }
6567754Smsmith
6667754Smsmith    ret = krb5_kt_start_seq_get(context, keytab, &cursor);
6767754Smsmith    if(ret) {
6867754Smsmith	krb5_kt_close(context, keytab);
6967754Smsmith	krb5_free_principal(context, from_princ);
7067754Smsmith	krb5_free_principal(context, to_princ);
7167754Smsmith	return 1;
7267754Smsmith    }
7367754Smsmith    while(1) {
7467754Smsmith	ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
7567754Smsmith	if(ret != 0) {
7667754Smsmith	    if(ret != KRB5_CC_END && ret != KRB5_KT_END)
7767754Smsmith		krb5_warn(context, ret, "getting entry from keytab");
7867754Smsmith	    else
7967754Smsmith		ret = 0;
8067754Smsmith	    break;
8167754Smsmith	}
8267754Smsmith	if(krb5_principal_compare(context, entry.principal, from_princ)) {
8367754Smsmith	    krb5_free_principal(context, entry.principal);
8467754Smsmith	    entry.principal = to_princ;
8567754Smsmith	    ret = krb5_kt_add_entry(context, keytab, &entry);
8667754Smsmith	    if(ret) {
8767754Smsmith		entry.principal = NULL;
8867754Smsmith		krb5_kt_free_entry(context, &entry);
8967754Smsmith		krb5_warn(context, ret, "adding entry");
9067754Smsmith		break;
9167754Smsmith	    }
9267754Smsmith	    if (opt->delete_flag) {
9367754Smsmith		entry.principal = from_princ;
9467754Smsmith		ret = krb5_kt_remove_entry(context, keytab, &entry);
9567754Smsmith		if(ret) {
9667754Smsmith		    entry.principal = NULL;
9767754Smsmith		    krb5_kt_free_entry(context, &entry);
9867754Smsmith		    krb5_warn(context, ret, "removing entry");
9967754Smsmith		    break;
10067754Smsmith		}
10167754Smsmith	    }
10267754Smsmith	    entry.principal = NULL;
10367754Smsmith	}
10467754Smsmith	krb5_kt_free_entry(context, &entry);
10567754Smsmith    }
10667754Smsmith    krb5_kt_end_seq_get(context, keytab, &cursor);
10767754Smsmith
10867754Smsmith    krb5_free_principal(context, from_princ);
10967754Smsmith    krb5_free_principal(context, to_princ);
11067754Smsmith
11167754Smsmith    return ret != 0;
11267754Smsmith}
11367754Smsmith
11467754Smsmith