Exemplo n.º 1
0
static void
add_principal(void *lhandle, char *keytab_str, krb5_keytab keytab,
              krb5_boolean keepold, int n_ks_tuple,
              krb5_key_salt_tuple *ks_tuple, char *princ_str)
{
    kadm5_principal_ent_rec princ_rec;
    krb5_principal princ = NULL;
    krb5_keytab_entry new_entry;
    krb5_keyblock *keys;
    int code, nkeys, i;

    memset(&princ_rec, 0, sizeof(princ_rec));

    princ = NULL;
    keys = NULL;
    nkeys = 0;

    code = krb5_parse_name(context, princ_str, &princ);
    if (code != 0) {
        com_err(whoami, code, "while parsing -add principal name %s",
                princ_str);
        goto cleanup;
    }

#ifdef KADMIN_LOCAL
    if (norandkey)
        code = kadm5_get_principal_keys(handle, princ, &keys, &nkeys);
    else
#endif
        if (keepold || ks_tuple != NULL) {
            code = kadm5_randkey_principal_3(lhandle, princ, keepold,
                                             n_ks_tuple, ks_tuple, &keys, &nkeys);
        } else
            code = kadm5_randkey_principal(lhandle, princ, &keys, &nkeys);
    if (code != 0) {
        if (code == KADM5_UNK_PRINC) {
            fprintf(stderr, "%s: Principal %s does not exist.\n",
                    whoami, princ_str);
        } else
            com_err(whoami, code, "while changing %s's key", princ_str);
        goto cleanup;
    }

    code = kadm5_get_principal(lhandle, princ, &princ_rec,
                               KADM5_PRINCIPAL_NORMAL_MASK);
    if (code != 0) {
        com_err(whoami, code, "while retrieving principal");
        goto cleanup;
    }

    for (i = 0; i < nkeys; i++) {
        memset(&new_entry, 0, sizeof(new_entry));
        new_entry.principal = princ;
        new_entry.key = keys[i];
        new_entry.vno = princ_rec.kvno;

        code = krb5_kt_add_entry(context, keytab, &new_entry);
        if (code != 0) {
            com_err(whoami, code, "while adding key to keytab");
            kadm5_free_principal_ent(lhandle, &princ_rec);
            goto cleanup;
        }

        if (!quiet) {
            printf("Entry for principal %s with kvno %d, "
                   "encryption type %s added to keytab %s.\n",
                   princ_str, princ_rec.kvno,
                   etype_string(keys[i].enctype), keytab_str);
        }
    }

    code = kadm5_free_principal_ent(lhandle, &princ_rec);
    if (code != 0) {
        com_err(whoami, code, "while freeing principal entry");
        goto cleanup;
    }

cleanup:
    for (i = 0; i < nkeys; i++)
        krb5_free_keyblock_contents(context, &keys[i]);
    free(keys);
    krb5_free_principal(context, princ);
}
Exemplo n.º 2
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_keytab kt;
    krb5_keytab_entry ktent;
    krb5_encrypt_block eblock;
    krb5_creds my_creds;
    krb5_get_init_creds_opt *opt;
    kadm5_principal_ent_rec princ_ent;
    krb5_principal princ, server;
    char pw[16];
    char *whoami, *principal, *authprinc, *authpwd;
    krb5_data pwdata;
    void *handle;
    int ret, test, encnum;
    unsigned int i;

    whoami = argv[0];

    if (argc < 2 || argc > 4) {
        fprintf(stderr, "Usage: %s principal [authuser] [authpwd]\n", whoami);
        exit(1);
    }
    principal = argv[1];
    authprinc = (argc > 2) ? argv[2] : argv[0];
    authpwd = (argc > 3) ? argv[3] : NULL;

    /*
     * Setup.  Initialize data structures, open keytab, open connection
     * to kadm5 server.
     */

    memset(&context, 0, sizeof(context));
    kadm5_init_krb5_context(&context);

    ret = krb5_parse_name(context, principal, &princ);
    if (ret) {
        com_err(whoami, ret, "while parsing principal name %s", principal);
        exit(1);
    }

    if((ret = krb5_build_principal_ext(context, &server,
                                       krb5_princ_realm(kcontext, princ)->length,
                                       krb5_princ_realm(kcontext, princ)->data,
                                       tgtname.length, tgtname.data,
                                       krb5_princ_realm(kcontext, princ)->length,
                                       krb5_princ_realm(kcontext, princ)->data,
                                       0))) {
        com_err(whoami, ret, "while building server name");
        exit(1);
    }

    ret = krb5_kt_default(context, &kt);
    if (ret) {
        com_err(whoami, ret, "while opening keytab");
        exit(1);
    }

    ret = kadm5_init(context, authprinc, authpwd, KADM5_ADMIN_SERVICE, NULL,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
                     &handle);
    if (ret) {
        com_err(whoami, ret, "while initializing connection");
        exit(1);
    }

    /* these pw's don't need to be secure, just different every time */
    SRAND((RAND_TYPE)time((void *) NULL));
    pwdata.data = pw;
    pwdata.length = sizeof(pw);

    /*
     * For each test:
     *
     * For each enctype in the test, construct a random password/key.
     * Assign all keys to principal with kadm5_setkey_principal.  Add
     * each key to the keytab, and acquire an initial ticket with the
     * keytab (XXX can I specify the kvno explicitly?).  If
     * krb5_get_init_creds_keytab succeeds, then the keys were set
     * successfully.
     */
    for (test = 0; tests[test] != NULL; test++) {
        krb5_keyblock *testp = tests[test];
        kadm5_key_data *extracted;
        int n_extracted, match;
        printf("+ Test %d:\n", test);

        for (encnum = 0; testp[encnum].magic != -1; encnum++) {
            for (i = 0; i < sizeof(pw); i++)
                pw[i] = (RAND() % 26) + '0'; /* XXX */

            krb5_use_enctype(context, &eblock, testp[encnum].enctype);
            ret = krb5_string_to_key(context, &eblock, &testp[encnum],
                                     &pwdata, NULL);
            if (ret) {
                com_err(whoami, ret, "while converting string to key");
                exit(1);
            }
        }

        /* now, encnum == # of keyblocks in testp */
        ret = kadm5_setkey_principal(handle, princ, testp, encnum);
        if (ret) {
            com_err(whoami, ret, "while setting keys");
            exit(1);
        }

        ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO);
        if (ret) {
            com_err(whoami, ret, "while retrieving principal");
            exit(1);
        }

        ret = kadm5_get_principal_keys(handle, princ, 0, &extracted,
                                       &n_extracted);
        if (ret) {
            com_err(whoami, ret, "while extracting keys");
            exit(1);
        }

        for (encnum = 0; testp[encnum].magic != -1; encnum++) {
            printf("+   enctype %d\n", testp[encnum].enctype);

            for (match = 0; match < n_extracted; match++) {
                if (extracted[match].key.enctype == testp[encnum].enctype)
                    break;
            }
            if (match >= n_extracted) {
                com_err(whoami, KRB5_WRONG_ETYPE, "while matching enctypes");
                exit(1);
            }
            if (extracted[match].key.length != testp[encnum].length ||
                memcmp(extracted[match].key.contents, testp[encnum].contents,
                       testp[encnum].length) != 0) {
                com_err(whoami, KRB5_KDB_NO_MATCHING_KEY, "verifying keys");
                exit(1);
            }

            memset(&ktent, 0, sizeof(ktent));
            ktent.principal = princ;
            ktent.key = testp[encnum];
            ktent.vno = princ_ent.kvno;

            ret = krb5_kt_add_entry(context, kt, &ktent);
            if (ret) {
                com_err(whoami, ret, "while adding keytab entry");
                exit(1);
            }

            memset(&my_creds, 0, sizeof(my_creds));
            my_creds.client = princ;
            my_creds.server = server;

            ktypes[0] = testp[encnum].enctype;
            ret = krb5_get_init_creds_opt_alloc(context, &opt);
            if (ret) {
                com_err(whoami, ret, "while allocating gic opts");
                exit(1);
            }
            krb5_get_init_creds_opt_set_etype_list(opt, ktypes, 1);
            ret = krb5_get_init_creds_keytab(context, &my_creds, princ,
                                             kt, 0, NULL /* in_tkt_service */,
                                             opt);
            krb5_get_init_creds_opt_free(context, opt);
            if (ret) {
                com_err(whoami, ret, "while acquiring initial ticket");
                exit(1);
            }
            krb5_free_cred_contents(context, &my_creds);

            /* since I can't specify enctype explicitly ... */
            ret = krb5_kt_remove_entry(context, kt, &ktent);
            if (ret) {
                com_err(whoami, ret, "while removing keytab entry");
                exit(1);
            }
        }

        (void)kadm5_free_kadm5_key_data(context, n_extracted, extracted);
    }

    ret = krb5_kt_close(context, kt);
    if (ret) {
        com_err(whoami, ret, "while closing keytab");
        exit(1);
    }

    ret = kadm5_destroy(handle);
    if (ret) {
        com_err(whoami, ret, "while closing kadmin connection");
        exit(1);
    }

    krb5_free_principal(context, princ);
    krb5_free_principal(context, server);
    krb5_free_context(context);
    return 0;
}