Add new kadmin/ktutil --keep* and --enctypes opts
- Add --keepold/keepallold/pruneall options to various kadmin/ktutil commands. Default behavior to "prune old keys". - When setting keys for a service, we need to specify enctypes for it: - Always use kadm5_randkey_principal_3() instead of the older kadm5_randkey_principal(). - Add krb5_string_to_keysalts2(), like MIT's krb5_string_to_keysalts(), but with a context, and simpler. - Add --enctypes options to various kadmin/ktutil commands. - Add [libdefaults] supported_enctypes param with enctype[:salttype] list. - Add [realms] realm supported_enctypes param with enctype[:salttype] list. Default to aes128-cts-hmac-sha1-96:normal.
This commit is contained in:

committed by
Nico Williams

parent
7b76d6719f
commit
d8394c65b7
82
kadmin/ank.c
82
kadmin/ank.c
@@ -63,18 +63,20 @@ get_default (kadm5_server_context *contextp,
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
add_one_principal (const char *name,
|
||||
int rand_key,
|
||||
int rand_password,
|
||||
int use_defaults,
|
||||
char *password,
|
||||
char *policy,
|
||||
krb5_key_data *key_data,
|
||||
const char *max_ticket_life,
|
||||
const char *max_renewable_life,
|
||||
const char *attributes,
|
||||
const char *expiration,
|
||||
const char *pw_expiration)
|
||||
add_one_principal(const char *name,
|
||||
int rand_key,
|
||||
int rand_password,
|
||||
int use_defaults,
|
||||
char *password,
|
||||
char *policy,
|
||||
size_t nkstuple,
|
||||
krb5_key_salt_tuple *kstuple,
|
||||
krb5_key_data *key_data,
|
||||
const char *max_ticket_life,
|
||||
const char *max_renewable_life,
|
||||
const char *attributes,
|
||||
const char *expiration,
|
||||
const char *pw_expiration)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
kadm5_principal_ent_rec princ, defrec;
|
||||
@@ -157,11 +159,11 @@ add_one_principal (const char *name,
|
||||
}
|
||||
/* Save requested password expiry before it's clobbered */
|
||||
pw_expire = princ.pw_expiration;
|
||||
if(rand_key) {
|
||||
if (rand_key) {
|
||||
krb5_keyblock *new_keys;
|
||||
int n_keys, i;
|
||||
ret = kadm5_randkey_principal(kadm_handle, princ_ent,
|
||||
&new_keys, &n_keys);
|
||||
ret = kadm5_randkey_principal_3(kadm_handle, princ_ent, 0,
|
||||
nkstuple, kstuple, &new_keys, &n_keys);
|
||||
if(ret){
|
||||
krb5_warn(context, ret, "kadm5_randkey_principal");
|
||||
n_keys = 0;
|
||||
@@ -231,10 +233,12 @@ int
|
||||
add_new_key(struct add_options *opt, int argc, char **argv)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
int i;
|
||||
int num;
|
||||
krb5_key_salt_tuple *kstuple = NULL;
|
||||
krb5_key_data key_data[3];
|
||||
krb5_key_data *kdp = NULL;
|
||||
const char *enctypes;
|
||||
size_t i, nkstuple;
|
||||
int num;
|
||||
|
||||
num = 0;
|
||||
if (opt->random_key_flag)
|
||||
@@ -252,30 +256,46 @@ add_new_key(struct add_options *opt, int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
enctypes = opt->enctypes_string;
|
||||
if (enctypes == NULL || enctypes[0] == '\0')
|
||||
enctypes = krb5_config_get_string(context, NULL, "libdefaults",
|
||||
"supported_enctypes", NULL);
|
||||
if (enctypes == NULL || enctypes[0] == '\0')
|
||||
enctypes = "aes128-cts-hmac-sha1-96";
|
||||
ret = krb5_string_to_keysalts2(context, enctypes, &nkstuple, &kstuple);
|
||||
if (ret) {
|
||||
fprintf(stderr, "enctype(s) unknown\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (opt->key_string) {
|
||||
const char *error;
|
||||
|
||||
if (parse_des_key (opt->key_string, key_data, &error)) {
|
||||
fprintf (stderr, "failed parsing key \"%s\": %s\n",
|
||||
opt->key_string, error);
|
||||
fprintf(stderr, "failed parsing key \"%s\": %s\n",
|
||||
opt->key_string, error);
|
||||
free(kstuple);
|
||||
return 1;
|
||||
}
|
||||
kdp = key_data;
|
||||
}
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
ret = add_one_principal (argv[i],
|
||||
opt->random_key_flag,
|
||||
opt->random_password_flag,
|
||||
opt->use_defaults_flag,
|
||||
opt->password_string,
|
||||
opt->policy_string,
|
||||
kdp,
|
||||
opt->max_ticket_life_string,
|
||||
opt->max_renewable_life_string,
|
||||
opt->attributes_string,
|
||||
opt->expiration_time_string,
|
||||
opt->pw_expiration_time_string);
|
||||
ret = add_one_principal(argv[i],
|
||||
opt->random_key_flag,
|
||||
opt->random_password_flag,
|
||||
opt->use_defaults_flag,
|
||||
opt->password_string,
|
||||
opt->policy_string,
|
||||
nkstuple,
|
||||
kstuple,
|
||||
kdp,
|
||||
opt->max_ticket_life_string,
|
||||
opt->max_renewable_life_string,
|
||||
opt->attributes_string,
|
||||
opt->expiration_time_string,
|
||||
opt->pw_expiration_time_string);
|
||||
if (ret) {
|
||||
krb5_warn (context, ret, "adding %s", argv[i]);
|
||||
break;
|
||||
|
24
kadmin/cpw.c
24
kadmin/cpw.c
@@ -148,12 +148,34 @@ cpw_entry(struct passwd_options *opt, int argc, char **argv)
|
||||
int num;
|
||||
krb5_key_data key_data[3];
|
||||
|
||||
data.keepold = opt->keepold_flag;
|
||||
data.random_key = opt->random_key_flag;
|
||||
data.random_password = opt->random_password_flag;
|
||||
data.password = opt->password_string;
|
||||
data.key_data = NULL;
|
||||
|
||||
/*
|
||||
* --keepold is the the default, and it should mean "prune all old keys not
|
||||
* needed to decrypt extant tickets".
|
||||
*/
|
||||
num = 0;
|
||||
data.keepold = 0;
|
||||
if (opt->keepold_flag) {
|
||||
data.keepold = 1;
|
||||
num++;
|
||||
}
|
||||
if (opt->keepallold_flag) {
|
||||
data.keepold = 2;
|
||||
num++;
|
||||
}
|
||||
if (opt->pruneall_flag) {
|
||||
data.keepold = 0;
|
||||
num++;
|
||||
}
|
||||
if (num > 1) {
|
||||
fprintf(stderr, "use only one of --keepold, --keepallold, and --pruneall\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
num = 0;
|
||||
if (data.random_key)
|
||||
++num;
|
||||
|
47
kadmin/ext.c
47
kadmin/ext.c
@@ -36,7 +36,10 @@
|
||||
|
||||
struct ext_keytab_data {
|
||||
krb5_keytab keytab;
|
||||
int keep;
|
||||
int random_key_flag;
|
||||
size_t nkstuple;
|
||||
krb5_key_salt_tuple *kstuple;
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -109,7 +112,8 @@ do_ext_keytab(krb5_principal principal, void *data)
|
||||
n_k++;
|
||||
}
|
||||
} else if (e->random_key_flag) {
|
||||
ret = kadm5_randkey_principal(kadm_handle, principal, &k, &n_k);
|
||||
ret = kadm5_randkey_principal_3(kadm_handle, principal, e->keep,
|
||||
e->nkstuple, e->kstuple, &k, &n_k);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -151,8 +155,30 @@ int
|
||||
ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
int i;
|
||||
struct ext_keytab_data data;
|
||||
const char *enctypes;
|
||||
size_t i;
|
||||
|
||||
data.random_key_flag = opt->random_key_flag;
|
||||
data.keep = 0;
|
||||
i = 0;
|
||||
if (opt->keepallold_flag) {
|
||||
data.keep = 2;
|
||||
i++;
|
||||
}
|
||||
if (opt->keepold_flag) {
|
||||
data.keep = 1;
|
||||
i++;
|
||||
}
|
||||
if (opt->pruneall_flag) {
|
||||
data.keep = 1;
|
||||
i++;
|
||||
}
|
||||
if (i > 1) {
|
||||
fprintf(stderr,
|
||||
"use only one of --keepold, --keepallold, or --pruneall\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (opt->keytab_string == NULL)
|
||||
ret = krb5_kt_default(context, &data.keytab);
|
||||
@@ -163,8 +189,19 @@ ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
|
||||
krb5_warn(context, ret, "krb5_kt_resolve");
|
||||
return 1;
|
||||
}
|
||||
|
||||
data.random_key_flag = opt->random_key_flag;
|
||||
enctypes = opt->enctypes_string;
|
||||
if (enctypes == NULL || enctypes[0] == '\0')
|
||||
enctypes = krb5_config_get_string(context, NULL, "libdefaults",
|
||||
"supported_enctypes", NULL);
|
||||
if (enctypes == NULL || enctypes[0] == '\0')
|
||||
enctypes = "aes128-cts-hmac-sha1-96";
|
||||
ret = krb5_string_to_keysalts2(context, enctypes, &data.nkstuple,
|
||||
&data.kstuple);
|
||||
if (ret) {
|
||||
fprintf(stderr, "enctype(s) unknown\n");
|
||||
krb5_kt_close(context, data.keytab);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
|
||||
@@ -173,6 +210,6 @@ ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
|
||||
}
|
||||
|
||||
krb5_kt_close(context, data.keytab);
|
||||
|
||||
free(data.kstuple);
|
||||
return ret != 0;
|
||||
}
|
||||
|
@@ -534,9 +534,15 @@ get_entry(struct get_options *opt, int argc, char **argv)
|
||||
int
|
||||
list_princs(struct list_options *opt, int argc, char **argv)
|
||||
{
|
||||
struct get_options get_opt;
|
||||
|
||||
if(sizeof(struct get_options) != sizeof(struct list_options)) {
|
||||
krb5_warnx(context, "programmer error: sizeof(struct get_options) != sizeof(struct list_options)");
|
||||
return 0;
|
||||
}
|
||||
return getit((struct get_options*)opt, "list", argc, argv);
|
||||
get_opt.long_flag = opt->long_flag;
|
||||
get_opt.short_flag = opt->short_flag;
|
||||
get_opt.terse_flag = opt->terse_flag;
|
||||
get_opt.column_info_string = opt->column_info_string;
|
||||
return getit(&get_opt, "list", argc, argv);
|
||||
}
|
||||
|
@@ -139,6 +139,12 @@ command = {
|
||||
type = "flag"
|
||||
help = "set random password"
|
||||
}
|
||||
option = {
|
||||
long = "enctypes"
|
||||
short = "e"
|
||||
type = "string"
|
||||
help = "encryption type(s)"
|
||||
}
|
||||
option = {
|
||||
long = "password"
|
||||
short = "p"
|
||||
@@ -225,6 +231,12 @@ command = {
|
||||
type = "flag"
|
||||
help = "set random password"
|
||||
}
|
||||
option = {
|
||||
long = "enctypes"
|
||||
short = "e"
|
||||
type = "string"
|
||||
help = "encryption type(s)"
|
||||
}
|
||||
option = {
|
||||
long = "password"
|
||||
short = "p"
|
||||
@@ -239,7 +251,17 @@ command = {
|
||||
option = {
|
||||
long = "keepold"
|
||||
type = "flag"
|
||||
help = "keep old keys/password"
|
||||
help = "keep old keys/password needed to decrypt extant tickets (default)"
|
||||
}
|
||||
option = {
|
||||
long = "keepallold"
|
||||
type = "flag"
|
||||
help = "keep all old keys/password"
|
||||
}
|
||||
option = {
|
||||
long = "pruneall"
|
||||
type = "flag"
|
||||
help = "delete all old keys"
|
||||
}
|
||||
argument = "principal..."
|
||||
min_args = "1"
|
||||
@@ -286,6 +308,27 @@ command = {
|
||||
type = "flag"
|
||||
help = "set random key"
|
||||
}
|
||||
option = {
|
||||
long = "enctypes"
|
||||
short = "e"
|
||||
type = "string"
|
||||
help = "encryption type(s)"
|
||||
}
|
||||
option = {
|
||||
long = "keepold"
|
||||
type = "flag"
|
||||
help = "keep old keys/password needed to decrypt extant tickets (default)"
|
||||
}
|
||||
option = {
|
||||
long = "keepallold"
|
||||
type = "flag"
|
||||
help = "keep all old keys/password"
|
||||
}
|
||||
option = {
|
||||
long = "pruneall"
|
||||
type = "flag"
|
||||
help = "delete all old keys"
|
||||
}
|
||||
argument = "principal..."
|
||||
min_args = "1"
|
||||
help = "Extracts the keys of all principals matching the expressions, and stores them in a keytab."
|
||||
@@ -294,7 +337,7 @@ command = {
|
||||
name = "get"
|
||||
name = "get_entry"
|
||||
function = "get_entry"
|
||||
/* XXX sync options with "list" */
|
||||
/* Options added to list should be added here; not the reverse */
|
||||
option = {
|
||||
long = "long"
|
||||
short = "l"
|
||||
|
@@ -102,6 +102,7 @@ Commands include:
|
||||
.Pp
|
||||
.Nm add
|
||||
.Op Fl r | Fl Fl random-key
|
||||
.Op Fl Fl enctypes= Ns Ar string
|
||||
.Op Fl Fl random-password
|
||||
.Op Fl p Ar string \*(Ba Fl Fl password= Ns Ar string
|
||||
.Op Fl Fl key= Ns Ar string
|
||||
@@ -115,6 +116,24 @@ Commands include:
|
||||
.Bd -ragged -offset indent
|
||||
Adds a new principal to the database. The options not passed on the
|
||||
command line will be promped for.
|
||||
If enctypes to use are not given, then the
|
||||
.Ar [libdefaults] supported_enctypes
|
||||
configuration parameter will be used on the client side to select
|
||||
enctypes, defaulting to
|
||||
.Ar aes128-cts-hmac-sha1-96.
|
||||
For compatibility with MIT, the enctypes string is a space- or
|
||||
comma-separated list of enctype:salttype.
|
||||
If
|
||||
.Fl Fl keepold
|
||||
is given, then old keys needed to decrypt extant tickets are
|
||||
kept, and all other old keys are deleted.
|
||||
If
|
||||
.Fl Fl keepallold
|
||||
is given then all old keys are kept. If
|
||||
.Fl Fl pruneall is given then all old keys are removed.
|
||||
The
|
||||
.Fl Fl keepold
|
||||
behavior is the default if none of these are given.
|
||||
The only policy supported by Heimdal servers is
|
||||
.Ql default .
|
||||
.Ed
|
||||
@@ -157,6 +176,8 @@ principals, those are not consulted here.
|
||||
.Pp
|
||||
.Nm ext_keytab
|
||||
.Oo Fl k Ar string \*(Ba Xo
|
||||
.Op Fl Fl keepold | Fl Fl keepallold | Fl Fl pruneall
|
||||
.Op Fl Fl enctypes= Ns Ar string
|
||||
.Fl Fl keytab= Ns Ar string
|
||||
.Xc
|
||||
.Oc
|
||||
@@ -165,6 +186,24 @@ principals, those are not consulted here.
|
||||
Creates a keytab with the keys of the specified principals. Requires
|
||||
get-keys rights, otherwise the principal's keys are changed and saved in
|
||||
the keytab.
|
||||
If enctypes to use are not given, then the
|
||||
.Ar [libdefaults] supported_enctypes
|
||||
configuration parameter will be used on the client side to select
|
||||
enctypes, defaulting to
|
||||
.Ar aes128-cts-hmac-sha1-96.
|
||||
For compatibility with MIT, the enctypes string is a space- or
|
||||
comma-separated list of enctype:salttype.
|
||||
If
|
||||
.Fl Fl keepold
|
||||
is given, then old keys needed to decrypt extant tickets are
|
||||
kept, and all other old keys are deleted.
|
||||
If
|
||||
.Fl Fl keepallold
|
||||
is given then all old keys are kept. If
|
||||
.Fl Fl pruneall is given then all old keys are removed.
|
||||
The
|
||||
.Fl Fl keepold
|
||||
behavior is the default if none of these are given.
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm get
|
||||
@@ -250,7 +289,8 @@ kadmin -l modify -a -disallow-proxiable user
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm passwd
|
||||
.Op Fl Fl keepold
|
||||
.Op Fl Fl keepold | Fl Fl keepallold | Fl Fl pruneall
|
||||
.Op Fl Fl enctypes= Ns Ar string
|
||||
.Op Fl r | Fl Fl random-key
|
||||
.Op Fl Fl random-password
|
||||
.Oo Fl p Ar string \*(Ba Xo
|
||||
@@ -261,6 +301,24 @@ kadmin -l modify -a -disallow-proxiable user
|
||||
.Ar principal...
|
||||
.Bd -ragged -offset indent
|
||||
Changes the password of an existing principal.
|
||||
If enctypes to use are not given, then the
|
||||
.Ar [libdefaults] supported_enctypes
|
||||
configuration parameter will be used on the client side to select
|
||||
enctypes, defaulting to
|
||||
.Ar aes128-cts-hmac-sha1-96.
|
||||
For compatibility with MIT, the enctypes string is a space- or
|
||||
comma-separated list of enctype:salttype.
|
||||
If
|
||||
.Fl Fl keepold
|
||||
is given, then old keys needed to decrypt extant tickets are
|
||||
kept, and all other old keys are deleted.
|
||||
If
|
||||
.Fl Fl keepallold
|
||||
is given then all old keys are kept. If
|
||||
.Fl Fl pruneall is given then all old keys are removed.
|
||||
The
|
||||
.Fl Fl keepold
|
||||
behavior is the default if none of these are given.
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm password-quality
|
||||
|
@@ -155,7 +155,23 @@ keytabs).
|
||||
joe/admin@EXAMPLE.COM all
|
||||
mallory/admin@EXAMPLE.COM add,get-keys host/*@EXAMPLE.COM
|
||||
.Ed
|
||||
.\".Sh DIAGNOSTICS
|
||||
.Sh CONFIGURATION FILE
|
||||
kadmind uses the following configuration parameters from the
|
||||
.Ar [kadmin]
|
||||
section of
|
||||
.Ar krb5.conf:
|
||||
.Bl -tag -width Ds -offset indent
|
||||
.It password_lifetime
|
||||
.El
|
||||
.Pp
|
||||
kadmind uses the following configuration parameters from the per-realm entries
|
||||
in the
|
||||
.Ar [realms]
|
||||
section of
|
||||
.Ar krb5.conf:
|
||||
.Bl -tag -width Ds -offset indent
|
||||
.It supported_enctypes
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr kpasswd 1 ,
|
||||
.Xr kadmin 1 ,
|
||||
|
@@ -448,9 +448,11 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
break;
|
||||
}
|
||||
case kadm_randkey:{
|
||||
size_t i;
|
||||
|
||||
op = "RANDKEY";
|
||||
ret = krb5_ret_principal(sp, &princ);
|
||||
if(ret)
|
||||
if (ret)
|
||||
goto fail;
|
||||
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
||||
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
||||
@@ -483,39 +485,49 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
}
|
||||
|
||||
ret = krb5_ret_int32(sp, &n_ks_tuple);
|
||||
if (ret != 0 && ret != HEIM_ERR_EOF) {
|
||||
if (ret == HEIM_ERR_EOF) {
|
||||
const char *enctypes;
|
||||
|
||||
enctypes = krb5_config_get_string(context, NULL, "realms",
|
||||
krb5_principal_get_realm(context,
|
||||
princ),
|
||||
"supported_enctypes", NULL);
|
||||
if (enctypes == NULL || enctypes[0] == '\0')
|
||||
enctypes = "aes128-cts-hmac-sha1-96";
|
||||
ret = krb5_string_to_keysalts2(context, enctypes, &n_ks_tuple,
|
||||
&ks_tuple);
|
||||
}
|
||||
if (ret != 0) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
} else if (ret == 0) {
|
||||
size_t i;
|
||||
|
||||
if (n_ks_tuple < 0) {
|
||||
ret = EOVERFLOW;
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ks_tuple = calloc(n_ks_tuple, sizeof (*ks_tuple))) == NULL) {
|
||||
ret = errno;
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_ks_tuple; i++) {
|
||||
ret = krb5_ret_int32(sp, &ks_tuple[i].ks_enctype);
|
||||
if (ret != 0) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
free(ks_tuple);
|
||||
goto fail;
|
||||
}
|
||||
ret = krb5_ret_int32(sp, &ks_tuple[i].ks_salttype);
|
||||
if (ret != 0) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
free(ks_tuple);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n_ks_tuple < 0) {
|
||||
ret = EOVERFLOW;
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ks_tuple = calloc(n_ks_tuple, sizeof (*ks_tuple))) == NULL) {
|
||||
ret = errno;
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_ks_tuple; i++) {
|
||||
ret = krb5_ret_int32(sp, &ks_tuple[i].ks_enctype);
|
||||
if (ret != 0) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
free(ks_tuple);
|
||||
goto fail;
|
||||
}
|
||||
ret = krb5_ret_int32(sp, &ks_tuple[i].ks_salttype);
|
||||
if (ret != 0) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
free(ks_tuple);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
ret = kadm5_randkey_principal_3(kadm_handlep, princ, keepold,
|
||||
n_ks_tuple, ks_tuple, &new_keys,
|
||||
&n_keys);
|
||||
@@ -525,10 +537,9 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
krb5_storage_free(sp);
|
||||
sp = krb5_storage_emem();
|
||||
krb5_store_int32(sp, ret);
|
||||
if(ret == 0){
|
||||
int i;
|
||||
if (ret == 0){
|
||||
krb5_store_int32(sp, n_keys);
|
||||
for(i = 0; i < n_keys; i++){
|
||||
for (i = 0; i < n_keys; i++){
|
||||
if (ret == 0)
|
||||
ret = krb5_store_keyblock(sp, new_keys[i]);
|
||||
krb5_free_keyblock_contents(contextp->context, &new_keys[i]);
|
||||
|
Reference in New Issue
Block a user