mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
7055827b8f
This makes it clearer that we always want to do heimdal changes via the lorikeet-heimdal repository. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> Autobuild-User(master): Joseph Sutton <jsutton@samba.org> Autobuild-Date(master): Wed Jan 19 21:41:59 UTC 2022 on sn-devel-184
279 lines
8.2 KiB
C
279 lines
8.2 KiB
C
/*
|
|
* Copyright (C) 1998 by the FundsXpress, INC.
|
|
*
|
|
* All rights reserved.
|
|
*
|
|
* Export of this software from the United States of America may require
|
|
* a specific license from the United States Government. It is the
|
|
* responsibility of any person or organization contemplating export to
|
|
* obtain such a license before exporting.
|
|
*
|
|
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
|
* distribute this software and its documentation for any purpose and
|
|
* without fee is hereby granted, provided that the above copyright
|
|
* notice appear in all copies and that both that copyright notice and
|
|
* this permission notice appear in supporting documentation, and that
|
|
* the name of FundsXpress. not be used in advertising or publicity pertaining
|
|
* to distribution of the software without specific, written prior
|
|
* permission. FundsXpress makes no representations about the suitability of
|
|
* this software for any purpose. It is provided "as is" without express
|
|
* or implied warranty.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
|
|
#include "kuser_locl.h"
|
|
|
|
static char *etype_str = NULL;
|
|
static char *ccache_name = NULL;
|
|
static char *keytab_name = NULL;
|
|
static char *sname = NULL;
|
|
|
|
static int version_flag = 0;
|
|
static int help_flag = 0;
|
|
static int quiet_flag = 0;
|
|
|
|
static void do_v5_kvno (int argc, char *argv[],
|
|
char *ccache_name, char *etype_str, char *keytab_name,
|
|
char *sname);
|
|
|
|
struct getargs args[] = {
|
|
{ "enctype", 'e', arg_string, &etype_str,
|
|
NP_("Encryption type to use", ""), "enctype" },
|
|
{ "cache", 'c', arg_string, &ccache_name,
|
|
NP_("Credentials cache", ""), "cachename" },
|
|
{ "keytab", 'k', arg_string, &keytab_name,
|
|
NP_("Keytab to use", ""), "keytabname" },
|
|
{ "server", 'S', arg_string, &sname,
|
|
NP_("Server to get ticket for", ""), "principal" },
|
|
{ "quiet", 'q', arg_flag, &quiet_flag,
|
|
NP_("Quiet", "") },
|
|
{ "version", 0, arg_flag, &version_flag },
|
|
{ "help", 0, arg_flag, &help_flag }
|
|
};
|
|
|
|
static void
|
|
usage(int ret)
|
|
{
|
|
arg_printusage_i18n (args, sizeof(args)/sizeof(*args),
|
|
N_("Usage: ", ""), NULL,
|
|
"principal1 [principal2 ...]",
|
|
getarg_i18n);
|
|
exit (ret);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int optidx = 0;
|
|
|
|
setprogname (argv[0]);
|
|
|
|
setlocale(LC_ALL, "");
|
|
bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR);
|
|
textdomain("heimdal_kuser");
|
|
|
|
if (getarg(args, sizeof(args)/sizeof(args[0]), argc, argv, &optidx))
|
|
usage(1);
|
|
|
|
if (help_flag)
|
|
usage (0);
|
|
|
|
if (version_flag) {
|
|
print_version(NULL);
|
|
exit (0);
|
|
}
|
|
|
|
argc -= optidx;
|
|
argv += optidx;
|
|
|
|
do_v5_kvno(argc, argv, ccache_name, etype_str, keytab_name, sname);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void do_v5_kvno (int count, char *names[],
|
|
char * ccache_name, char *etype_str, char *keytab_name,
|
|
char *sname)
|
|
{
|
|
krb5_error_code ret;
|
|
krb5_context context = 0;
|
|
int i, errors;
|
|
krb5_enctype etype;
|
|
krb5_ccache ccache;
|
|
krb5_principal me;
|
|
krb5_creds in_creds, *out_creds = NULL;
|
|
Ticket ticket;
|
|
size_t len;
|
|
char *princ = NULL;
|
|
krb5_keytab keytab = NULL;
|
|
|
|
ret = krb5_init_context(&context);
|
|
if (ret)
|
|
errx(1, "krb5_init_context failed: %d", ret);
|
|
|
|
if (etype_str) {
|
|
ret = krb5_string_to_enctype(context, etype_str, &etype);
|
|
if (ret)
|
|
krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str);
|
|
} else {
|
|
etype = 0;
|
|
}
|
|
|
|
if (ccache_name)
|
|
ret = krb5_cc_resolve(context, ccache_name, &ccache);
|
|
else
|
|
ret = krb5_cc_default(context, &ccache);
|
|
if (ret)
|
|
krb5_err(context, 1, ret, "Failed to open credentials cache %s",
|
|
(ccache_name) ? ccache_name : "(Default)");
|
|
|
|
if (keytab_name) {
|
|
ret = krb5_kt_resolve(context, keytab_name, &keytab);
|
|
if (ret)
|
|
krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name);
|
|
}
|
|
|
|
ret = krb5_cc_get_principal(context, ccache, &me);
|
|
if (ret)
|
|
krb5_err(context, 1, ret, "krb5_cc_get_principal");
|
|
|
|
errors = 0;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
memset(&in_creds, 0, sizeof(in_creds));
|
|
memset(&ticket, 0, sizeof(ticket));
|
|
|
|
in_creds.client = me;
|
|
|
|
if (sname != NULL) {
|
|
ret = krb5_sname_to_principal(context, names[i],
|
|
sname, KRB5_NT_SRV_HST,
|
|
&in_creds.server);
|
|
} else {
|
|
ret = krb5_parse_name(context, names[i], &in_creds.server);
|
|
}
|
|
if (ret) {
|
|
if (!quiet_flag)
|
|
krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]);
|
|
errors++;
|
|
continue;
|
|
}
|
|
|
|
ret = krb5_unparse_name(context, in_creds.server, &princ);
|
|
if (ret) {
|
|
krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'",
|
|
names[i]);
|
|
errors++;
|
|
goto next;
|
|
}
|
|
|
|
in_creds.session.keytype = etype;
|
|
|
|
ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds);
|
|
|
|
if (ret) {
|
|
krb5_warn(context, ret, "Couldn't get credentials for %s", princ);
|
|
errors++;
|
|
goto next;
|
|
}
|
|
|
|
ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length,
|
|
&ticket, &len);
|
|
if (ret) {
|
|
krb5_err(context, 1, ret, "Can't decode ticket for %s", princ);
|
|
errors++;
|
|
goto next;
|
|
continue;
|
|
}
|
|
|
|
if (keytab) {
|
|
krb5_keytab_entry kte;
|
|
krb5_crypto crypto;
|
|
krb5_data dec_data;
|
|
EncTicketPart decr_part;
|
|
|
|
ret = krb5_kt_get_entry(context, keytab, in_creds.server,
|
|
(ticket.enc_part.kvno != NULL)?
|
|
*ticket.enc_part.kvno : 0,
|
|
ticket.enc_part.etype,
|
|
&kte);
|
|
if (ret) {
|
|
krb5_warn(context, ret, "Can't decrypt ticket for %s", princ);
|
|
if (!quiet_flag)
|
|
printf("%s: kvno = %d, keytab entry invalid", princ,
|
|
(ticket.enc_part.kvno != NULL)?
|
|
*ticket.enc_part.kvno : 0);
|
|
errors ++;
|
|
goto next;
|
|
}
|
|
|
|
ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto);
|
|
if (ret) {
|
|
krb5_warn(context, ret, "krb5_crypto_init");
|
|
errors ++;
|
|
krb5_kt_free_entry(context, &kte);
|
|
goto next;
|
|
}
|
|
|
|
ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
|
|
&ticket.enc_part, &dec_data);
|
|
krb5_crypto_destroy(context, crypto);
|
|
krb5_kt_free_entry(context, &kte);
|
|
|
|
if (ret) {
|
|
krb5_warn(context, ret, "krb5_decrypt_EncryptedData");
|
|
errors ++;
|
|
goto next;
|
|
}
|
|
|
|
ret = decode_EncTicketPart(dec_data.data, dec_data.length,
|
|
&decr_part, &len);
|
|
krb5_data_free(&dec_data);
|
|
if (ret) {
|
|
krb5_warn(context, ret, "decode_EncTicketPart");
|
|
errors ++;
|
|
goto next;
|
|
}
|
|
|
|
if (!quiet_flag)
|
|
printf("%s: kvno = %d, keytab entry valid\n", princ,
|
|
(ticket.enc_part.kvno != NULL)?
|
|
*ticket.enc_part.kvno : 0);
|
|
|
|
free_EncTicketPart(&decr_part);
|
|
} else {
|
|
if (!quiet_flag)
|
|
printf("%s: kvno = %d\n", princ,
|
|
(ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0);
|
|
}
|
|
|
|
next:
|
|
if (out_creds) {
|
|
krb5_free_creds(context, out_creds);
|
|
out_creds = NULL;
|
|
}
|
|
|
|
if (princ) {
|
|
krb5_free_unparsed_name(context, princ);
|
|
princ = NULL;
|
|
}
|
|
|
|
krb5_free_principal(context, in_creds.server);
|
|
|
|
free_Ticket(&ticket);
|
|
}
|
|
|
|
if (keytab)
|
|
krb5_kt_close(context, keytab);
|
|
krb5_free_principal(context, me);
|
|
krb5_cc_close(context, ccache);
|
|
krb5_free_context(context);
|
|
|
|
if (errors)
|
|
exit(1);
|
|
|
|
exit(0);
|
|
}
|