Merge pull request #12 from nicowilliams/krb5_admin_patches_2nd
Krb5 admin patches 2nd This has all the patches needed for krb5_admind to build and pass most tests, that includes: - more kadm5 API compatibility (including very basic profile functionality) - multi-kvno support (useful for key rollovers) (a test for this is included in tests/db/check-kdc) Unfinished: - password history (currently uses key history, needs to be separated and use digests) - policies (only default policy allowed) - mit kdb changes not tested yet Signed-off-by: Love Hörnquist Åstrand <lha@h5l.org>
This commit is contained in:
@@ -78,8 +78,9 @@ add_enctype(struct add_enctype_options*opt, int argc, char **argv)
|
||||
goto out2;
|
||||
}
|
||||
|
||||
/* The principal might have zero keys, but it will still have a kvno! */
|
||||
ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
|
||||
KADM5_PRINCIPAL | KADM5_KEY_DATA);
|
||||
KADM5_KVNO | KADM5_PRINCIPAL | KADM5_KEY_DATA);
|
||||
if (ret) {
|
||||
krb5_free_principal (context, princ_ent);
|
||||
krb5_warnx (context, "no such principal: %s", princ_name);
|
||||
@@ -98,6 +99,7 @@ add_enctype(struct add_enctype_options*opt, int argc, char **argv)
|
||||
|
||||
for (j = 0; j < n_etypes; ++j) {
|
||||
if (etypes[j] == key->key_data_type[0]) {
|
||||
/* XXX Should this be an error? The admin can del_enctype... */
|
||||
krb5_warnx(context, "enctype %d already exists",
|
||||
(int)etypes[j]);
|
||||
free(new_key_data);
|
||||
@@ -113,7 +115,7 @@ add_enctype(struct add_enctype_options*opt, int argc, char **argv)
|
||||
|
||||
memset(&new_key_data[n], 0, sizeof(new_key_data[n]));
|
||||
new_key_data[n].key_data_ver = 2;
|
||||
new_key_data[n].key_data_kvno = 0;
|
||||
new_key_data[n].key_data_kvno = princ.kvno;
|
||||
|
||||
ret = krb5_generate_random_keyblock (context, etypes[i], &keyblock);
|
||||
if (ret) {
|
||||
|
||||
15
kadmin/ank.c
15
kadmin/ank.c
@@ -68,6 +68,7 @@ add_one_principal (const char *name,
|
||||
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,
|
||||
@@ -94,7 +95,7 @@ add_one_principal (const char *name,
|
||||
|
||||
ret = set_entry(context, &princ, &mask,
|
||||
max_ticket_life, max_renewable_life,
|
||||
expiration, pw_expiration, attributes);
|
||||
expiration, pw_expiration, attributes, policy);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -159,10 +160,15 @@ add_one_principal (const char *name,
|
||||
kadm5_get_principal(kadm_handle, princ_ent, &princ,
|
||||
KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
|
||||
princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
|
||||
/*
|
||||
* Updating kvno w/o key data and vice-versa gives _kadm5_setup_entry()
|
||||
* and _kadm5_set_keys2() headaches. But we used to, so we handle
|
||||
* this in in those two functions. Might as well leave this code as
|
||||
* it was then.
|
||||
*/
|
||||
princ.kvno = 1;
|
||||
kadm5_modify_principal(kadm_handle, &princ,
|
||||
KADM5_ATTRIBUTES | KADM5_KVNO);
|
||||
kadm5_free_principal_ent(kadm_handle, &princ);
|
||||
} else if (key_data) {
|
||||
ret = kadm5_chpass_principal_with_key (kadm_handle, princ_ent,
|
||||
3, key_data);
|
||||
@@ -173,7 +179,6 @@ add_one_principal (const char *name,
|
||||
KADM5_PRINCIPAL | KADM5_ATTRIBUTES);
|
||||
princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
|
||||
kadm5_modify_principal(kadm_handle, &princ, KADM5_ATTRIBUTES);
|
||||
kadm5_free_principal_ent(kadm_handle, &princ);
|
||||
} else if (rand_password) {
|
||||
char *princ_name;
|
||||
|
||||
@@ -182,8 +187,7 @@ add_one_principal (const char *name,
|
||||
free (princ_name);
|
||||
}
|
||||
out:
|
||||
if (princ_ent)
|
||||
krb5_free_principal (context, princ_ent);
|
||||
kadm5_free_principal_ent(kadm_handle, &princ); /* frees princ_ent */
|
||||
if(default_ent)
|
||||
kadm5_free_principal_ent (kadm_handle, default_ent);
|
||||
if (password != NULL)
|
||||
@@ -245,6 +249,7 @@ add_new_key(struct add_options *opt, int argc, char **argv)
|
||||
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,
|
||||
|
||||
30
kadmin/cpw.c
30
kadmin/cpw.c
@@ -35,6 +35,7 @@
|
||||
#include "kadmin-commands.h"
|
||||
|
||||
struct cpw_entry_data {
|
||||
int keepold;
|
||||
int random_key;
|
||||
int random_password;
|
||||
char *password;
|
||||
@@ -42,14 +43,15 @@ struct cpw_entry_data {
|
||||
};
|
||||
|
||||
static int
|
||||
set_random_key (krb5_principal principal)
|
||||
set_random_key (krb5_principal principal, int keepold)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
int i;
|
||||
krb5_keyblock *keys;
|
||||
int num_keys;
|
||||
|
||||
ret = kadm5_randkey_principal(kadm_handle, principal, &keys, &num_keys);
|
||||
ret = kadm5_randkey_principal_3(kadm_handle, principal, keepold, 0, NULL,
|
||||
&keys, &num_keys);
|
||||
if(ret)
|
||||
return ret;
|
||||
for(i = 0; i < num_keys; i++)
|
||||
@@ -59,13 +61,13 @@ set_random_key (krb5_principal principal)
|
||||
}
|
||||
|
||||
static int
|
||||
set_random_password (krb5_principal principal)
|
||||
set_random_password (krb5_principal principal, int keepold)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
char pw[128];
|
||||
|
||||
random_password (pw, sizeof(pw));
|
||||
ret = kadm5_chpass_principal(kadm_handle, principal, pw);
|
||||
ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL, pw);
|
||||
if (ret == 0) {
|
||||
char *princ_name;
|
||||
|
||||
@@ -79,7 +81,7 @@ set_random_password (krb5_principal principal)
|
||||
}
|
||||
|
||||
static int
|
||||
set_password (krb5_principal principal, char *password)
|
||||
set_password (krb5_principal principal, char *password, int keepold)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
char pwbuf[128];
|
||||
@@ -99,18 +101,19 @@ set_password (krb5_principal principal, char *password)
|
||||
password = pwbuf;
|
||||
}
|
||||
if(ret == 0)
|
||||
ret = kadm5_chpass_principal(kadm_handle, principal, password);
|
||||
ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL,
|
||||
password);
|
||||
memset(pwbuf, 0, sizeof(pwbuf));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
set_key_data (krb5_principal principal, krb5_key_data *key_data)
|
||||
set_key_data (krb5_principal principal, krb5_key_data *key_data, int keepold)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = kadm5_chpass_principal_with_key (kadm_handle, principal,
|
||||
3, key_data);
|
||||
ret = kadm5_chpass_principal_with_key_3(kadm_handle, principal, keepold,
|
||||
3, key_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -120,13 +123,13 @@ do_cpw_entry(krb5_principal principal, void *data)
|
||||
struct cpw_entry_data *e = data;
|
||||
|
||||
if (e->random_key)
|
||||
return set_random_key (principal);
|
||||
return set_random_key (principal, e->keepold);
|
||||
else if (e->random_password)
|
||||
return set_random_password (principal);
|
||||
return set_random_password (principal, e->keepold);
|
||||
else if (e->key_data)
|
||||
return set_key_data (principal, e->key_data);
|
||||
return set_key_data (principal, e->key_data, e->keepold);
|
||||
else
|
||||
return set_password (principal, e->password);
|
||||
return set_password (principal, e->password, e->keepold);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -138,6 +141,7 @@ 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;
|
||||
|
||||
@@ -106,6 +106,10 @@ del_enctype(void *opt, int argc, char **argv)
|
||||
}
|
||||
|
||||
free (princ.key_data);
|
||||
if (j == 0) {
|
||||
free(new_key_data);
|
||||
new_key_data = NULL;
|
||||
}
|
||||
princ.n_key_data = j;
|
||||
princ.key_data = new_key_data;
|
||||
|
||||
|
||||
@@ -60,10 +60,12 @@ static struct field_name {
|
||||
{ "last_failed", KADM5_LAST_FAILED, 0, 0, "Last fail", "Last failed login", 0 },
|
||||
{ "fail_auth_count", KADM5_FAIL_AUTH_COUNT, 0, 0, "Fail count", "Failed login count", RTBL_ALIGN_RIGHT },
|
||||
{ "policy", KADM5_POLICY, 0, 0, "Policy", "Policy", 0 },
|
||||
{ "keytypes", KADM5_KEY_DATA, 0, KADM5_PRINCIPAL, "Keytypes", "Keytypes", 0 },
|
||||
{ "keytypes", KADM5_KEY_DATA, 0, KADM5_PRINCIPAL | KADM5_KVNO, "Keytypes", "Keytypes", 0 },
|
||||
{ "password", KADM5_TL_DATA, KRB5_TL_PASSWORD, KADM5_KEY_DATA, "Password", "Password", 0 },
|
||||
{ "pkinit-acl", KADM5_TL_DATA, KRB5_TL_PKINIT_ACL, 0, "PK-INIT ACL", "PK-INIT ACL", 0 },
|
||||
{ "aliases", KADM5_TL_DATA, KRB5_TL_ALIASES, 0, "Aliases", "Aliases", 0 },
|
||||
{ "hist-kvno-diff-clnt", KADM5_TL_DATA, KRB5_TL_HIST_KVNO_DIFF_CLNT, 0, "Clnt hist keys", "Historic keys allowed for client", 0 },
|
||||
{ "hist-kvno-diff-svc", KADM5_TL_DATA, KRB5_TL_HIST_KVNO_DIFF_SVC, 0, "Svc hist keys", "Historic keys allowed for service", 0 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -174,11 +174,31 @@ command = {
|
||||
argument = "time"
|
||||
help = "password expiration time"
|
||||
}
|
||||
option = {
|
||||
long = "hist-kvno-diff-clnt"
|
||||
type = "integer"
|
||||
argument = "kvno diff"
|
||||
help = "historic keys allowed for client"
|
||||
default = "-1"
|
||||
}
|
||||
option = {
|
||||
long = "hist-kvno-diff-svc"
|
||||
type = "integer"
|
||||
argument = "kvno diff"
|
||||
help = "historic keys allowed for service"
|
||||
default = "-1"
|
||||
}
|
||||
option = {
|
||||
long = "use-defaults"
|
||||
type = "flag"
|
||||
help = "use default values"
|
||||
}
|
||||
option = {
|
||||
long = "policy"
|
||||
type = "string"
|
||||
argument = "policy"
|
||||
help = "policy name"
|
||||
}
|
||||
argument = "principal..."
|
||||
min_args = "1"
|
||||
help = "Adds a principal to the database."
|
||||
@@ -210,6 +230,11 @@ command = {
|
||||
type = "string"
|
||||
help = "DES key in hex"
|
||||
}
|
||||
option = {
|
||||
long = "keepold"
|
||||
type = "flag"
|
||||
help = "keep old keys/password"
|
||||
}
|
||||
argument = "principal..."
|
||||
min_args = "1"
|
||||
help = "Changes the password of one or more principals matching the expressions."
|
||||
@@ -353,6 +378,26 @@ command = {
|
||||
argument = "subject dn"
|
||||
help = "aliases"
|
||||
}
|
||||
option = {
|
||||
long = "policy"
|
||||
type = "string"
|
||||
argument = "policy"
|
||||
help = "policy name"
|
||||
}
|
||||
option = {
|
||||
long = "hist-kvno-diff-clnt"
|
||||
type = "integer"
|
||||
argument = "kvno diff"
|
||||
help = "historic keys allowed for client"
|
||||
default = "-1"
|
||||
}
|
||||
option = {
|
||||
long = "hist-kvno-diff-svc"
|
||||
type = "integer"
|
||||
argument = "kvno diff"
|
||||
help = "historic keys allowed for service"
|
||||
default = "-1"
|
||||
}
|
||||
argument = "principal"
|
||||
min_args = "1"
|
||||
max_args = "1"
|
||||
@@ -414,6 +459,22 @@ command = {
|
||||
max_args = "1"
|
||||
help = "Check the realm (if not given, the default realm) for configuration errors."
|
||||
}
|
||||
command = {
|
||||
name = "lock"
|
||||
function = "lock"
|
||||
argument = ""
|
||||
min_args = "0"
|
||||
max_args = "0"
|
||||
help = "Lock the database for writing (use with care)."
|
||||
}
|
||||
command = {
|
||||
name = "unlock"
|
||||
function = "unlock"
|
||||
argument = ""
|
||||
min_args = "0"
|
||||
max_args = "0"
|
||||
help = "Unlock the database."
|
||||
}
|
||||
command = {
|
||||
name = "help"
|
||||
name = "?"
|
||||
|
||||
@@ -146,7 +146,8 @@ enctypes.
|
||||
.Oc
|
||||
.Ar principal...
|
||||
.Bd -ragged -offset indent
|
||||
Creates a keytab with the keys of the specified principals.
|
||||
Creates a keytab with the keys of the specified principals. Requires
|
||||
get-keys rights.
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm get
|
||||
@@ -228,6 +229,7 @@ kadmin -l modify -a -disallow-proxiable user
|
||||
.Ed
|
||||
.Pp
|
||||
.Nm passwd
|
||||
.Op Fl Fl keepold
|
||||
.Op Fl r | Fl Fl random-key
|
||||
.Op Fl Fl random-password
|
||||
.Oo Fl p Ar string \*(Ba Xo
|
||||
@@ -260,6 +262,7 @@ Lists the operations you are allowed to perform. These include
|
||||
.Li delete ,
|
||||
.Li del_enctype ,
|
||||
.Li get ,
|
||||
.Li get-keys ,
|
||||
.Li list ,
|
||||
and
|
||||
.Li modify .
|
||||
|
||||
@@ -112,6 +112,18 @@ exit_kadmin (void *opt, int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
lock(void *opt, int argc, char **argv)
|
||||
{
|
||||
return kadm5_lock(kadm_handle);
|
||||
}
|
||||
|
||||
int
|
||||
unlock(void *opt, int argc, char **argv)
|
||||
{
|
||||
return kadm5_unlock(kadm_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(int ret)
|
||||
{
|
||||
|
||||
@@ -109,6 +109,9 @@ int str2attributes(const char *, krb5_flags *);
|
||||
int parse_attributes (const char *, krb5_flags *, int *, int);
|
||||
int edit_attributes (const char *, krb5_flags *, int *, int);
|
||||
|
||||
int parse_policy (const char *, char **, int *, int);
|
||||
int edit_policy (const char *, char **, int *, int);
|
||||
|
||||
void time_t2str(time_t, char *, size_t, int);
|
||||
int str2time_t (const char *, time_t *);
|
||||
int parse_timet (const char *, krb5_timestamp *, int *, int);
|
||||
@@ -124,7 +127,7 @@ int edit_entry(kadm5_principal_ent_t, int *, kadm5_principal_ent_t, int);
|
||||
void set_defaults(kadm5_principal_ent_t, int *, kadm5_principal_ent_t, int);
|
||||
int set_entry(krb5_context, kadm5_principal_ent_t, int *,
|
||||
const char *, const char *, const char *,
|
||||
const char *, const char *);
|
||||
const char *, const char *, const char *);
|
||||
int
|
||||
foreach_principal(const char *, int (*)(krb5_principal, void*),
|
||||
const char *, void *);
|
||||
|
||||
@@ -107,6 +107,8 @@ add
|
||||
.It
|
||||
get
|
||||
.It
|
||||
get-keys
|
||||
.It
|
||||
all
|
||||
.El
|
||||
.Pp
|
||||
@@ -147,10 +149,11 @@ compiled in defaults:
|
||||
.D1 Nm Fl Fl ports Ns Li "=\*[q]+ 4711\*[q] &"
|
||||
.Pp
|
||||
This acl file will grant Joe all rights, and allow Mallory to view and
|
||||
add host principals.
|
||||
add host principals, as well as extract host principal keys (e.g., into
|
||||
keytabs).
|
||||
.Bd -literal -offset indent
|
||||
joe/admin@EXAMPLE.COM all
|
||||
mallory/admin@EXAMPLE.COM add,get host/*@EXAMPLE.COM
|
||||
mallory/admin@EXAMPLE.COM add,get-keys host/*@EXAMPLE.COM
|
||||
.Ed
|
||||
.\".Sh DIAGNOSTICS
|
||||
.Sh SEE ALSO
|
||||
|
||||
50
kadmin/mod.c
50
kadmin/mod.c
@@ -41,7 +41,7 @@ add_tl(kadm5_principal_ent_rec *princ, int type, krb5_data *data)
|
||||
|
||||
tl = ecalloc(1, sizeof(*tl));
|
||||
tl->tl_data_next = NULL;
|
||||
tl->tl_data_type = KRB5_TL_EXTENSION;
|
||||
tl->tl_data_type = type;
|
||||
tl->tl_data_length = data->length;
|
||||
tl->tl_data_contents = data->data;
|
||||
|
||||
@@ -185,6 +185,37 @@ add_pkinit_acl(krb5_context contextp, kadm5_principal_ent_rec *princ,
|
||||
add_tl(princ, KRB5_TL_EXTENSION, &buf);
|
||||
}
|
||||
|
||||
static void
|
||||
add_kvno_diff(krb5_context context, kadm5_principal_ent_rec *princ,
|
||||
int is_svc_diff, krb5_kvno kvno_diff)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
HDB_extension ext;
|
||||
krb5_data buf;
|
||||
size_t size = 0;
|
||||
|
||||
if (kvno_diff < 0)
|
||||
return;
|
||||
if (kvno_diff > 2048)
|
||||
kvno_diff = 2048;
|
||||
|
||||
if (is_svc_diff) {
|
||||
ext.data.element = choice_HDB_extension_data_hist_kvno_diff_svc;
|
||||
ext.data.u.hist_kvno_diff_svc = (unsigned int)kvno_diff;
|
||||
} else {
|
||||
ext.data.element = choice_HDB_extension_data_hist_kvno_diff_clnt;
|
||||
ext.data.u.hist_kvno_diff_clnt = (unsigned int)kvno_diff;
|
||||
}
|
||||
ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
|
||||
&ext, &size, ret);
|
||||
if (ret)
|
||||
abort();
|
||||
if (buf.length != size)
|
||||
abort();
|
||||
|
||||
add_tl(princ, KRB5_TL_EXTENSION, &buf);
|
||||
}
|
||||
|
||||
static int
|
||||
do_mod_entry(krb5_principal principal, void *data)
|
||||
{
|
||||
@@ -207,16 +238,20 @@ do_mod_entry(krb5_principal principal, void *data)
|
||||
e->expiration_time_string ||
|
||||
e->pw_expiration_time_string ||
|
||||
e->attributes_string ||
|
||||
e->policy_string ||
|
||||
e->kvno_integer != -1 ||
|
||||
e->constrained_delegation_strings.num_strings ||
|
||||
e->alias_strings.num_strings ||
|
||||
e->pkinit_acl_strings.num_strings) {
|
||||
e->pkinit_acl_strings.num_strings ||
|
||||
e->hist_kvno_diff_clnt_integer != -1 ||
|
||||
e->hist_kvno_diff_svc_integer != -1) {
|
||||
ret = set_entry(context, &princ, &mask,
|
||||
e->max_ticket_life_string,
|
||||
e->max_renewable_life_string,
|
||||
e->expiration_time_string,
|
||||
e->pw_expiration_time_string,
|
||||
e->attributes_string);
|
||||
e->attributes_string,
|
||||
e->policy_string);
|
||||
if(e->kvno_integer != -1) {
|
||||
princ.kvno = e->kvno_integer;
|
||||
mask |= KADM5_KVNO;
|
||||
@@ -234,7 +269,14 @@ do_mod_entry(krb5_principal principal, void *data)
|
||||
add_pkinit_acl(context, &princ, &e->pkinit_acl_strings);
|
||||
mask |= KADM5_TL_DATA;
|
||||
}
|
||||
|
||||
if (e->hist_kvno_diff_clnt_integer != -1) {
|
||||
add_kvno_diff(context, &princ, 0, e->hist_kvno_diff_clnt_integer);
|
||||
mask |= KADM5_TL_DATA;
|
||||
}
|
||||
if (e->hist_kvno_diff_svc_integer != -1) {
|
||||
add_kvno_diff(context, &princ, 1, e->hist_kvno_diff_clnt_integer);
|
||||
mask |= KADM5_TL_DATA;
|
||||
}
|
||||
} else
|
||||
ret = edit_entry(&princ, &mask, NULL, 0);
|
||||
if(ret == 0) {
|
||||
|
||||
@@ -47,9 +47,13 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
kadm5_principal_ent_rec ent;
|
||||
char *password, *expression;
|
||||
krb5_keyblock *new_keys;
|
||||
krb5_key_salt_tuple *ks_tuple = NULL;
|
||||
krb5_boolean keepold = FALSE;
|
||||
int n_ks_tuple = 0;
|
||||
int n_keys;
|
||||
char **princs;
|
||||
int n_princs;
|
||||
int keys_ok = 0;
|
||||
krb5_storage *sp;
|
||||
|
||||
krb5_unparse_name_fixed(contextp->context, contextp->caller,
|
||||
@@ -74,7 +78,11 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
mask |= KADM5_PRINCIPAL;
|
||||
krb5_unparse_name_fixed(contextp->context, princ, name, sizeof(name));
|
||||
krb5_warnx(contextp->context, "%s: %s %s", client, op, name);
|
||||
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ);
|
||||
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET_KEYS, princ);
|
||||
if (ret == 0)
|
||||
keys_ok = 1;
|
||||
else
|
||||
ret = _kadm5_acl_check_permission(contextp, KADM5_PRIV_GET, princ);
|
||||
if(ret){
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
@@ -84,7 +92,10 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
sp = krb5_storage_emem();
|
||||
krb5_store_int32(sp, ret);
|
||||
if(ret == 0){
|
||||
kadm5_store_principal_ent(sp, &ent);
|
||||
if (keys_ok)
|
||||
kadm5_store_principal_ent(sp, &ent);
|
||||
else
|
||||
kadm5_store_principal_ent_nokeys(sp, &ent);
|
||||
kadm5_free_principal_ent(kadm_handlep, &ent);
|
||||
}
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
@@ -207,10 +218,15 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
case kadm_chpass:{
|
||||
op = "CHPASS";
|
||||
ret = krb5_ret_principal(sp, &princ);
|
||||
if(ret)
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = krb5_ret_string(sp, &password);
|
||||
if(ret){
|
||||
if (ret) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
ret = krb5_ret_int32(sp, &keepold);
|
||||
if (ret && ret != HEIM_ERR_EOF) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
@@ -251,7 +267,8 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
free(password);
|
||||
goto fail;
|
||||
}
|
||||
ret = kadm5_chpass_principal(kadm_handlep, princ, password);
|
||||
ret = kadm5_chpass_principal_3(kadm_handlep, princ, keepold, 0, NULL,
|
||||
password);
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
memset(password, 0, strlen(password));
|
||||
free(password);
|
||||
@@ -274,6 +291,11 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
ret = krb5_ret_int32(sp, &keepold);
|
||||
if (ret && ret != HEIM_ERR_EOF) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
/* n_key_data will be squeezed into an int16_t below. */
|
||||
if (n_key_data < 0 || n_key_data >= 1 << 16 ||
|
||||
(size_t)n_key_data > UINT_MAX/sizeof(*key_data)) {
|
||||
@@ -318,8 +340,8 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
ret = kadm5_chpass_principal_with_key(kadm_handlep, princ,
|
||||
n_key_data, key_data);
|
||||
ret = kadm5_chpass_principal_with_key_3(kadm_handlep, princ, keepold,
|
||||
n_key_data, key_data);
|
||||
{
|
||||
int16_t dummy = n_key_data;
|
||||
kadm5_free_key_data (contextp, &dummy, key_data);
|
||||
@@ -355,9 +377,54 @@ kadmind_dispatch(void *kadm_handlep, krb5_boolean initial,
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
ret = kadm5_randkey_principal(kadm_handlep, princ,
|
||||
&new_keys, &n_keys);
|
||||
|
||||
/*
|
||||
* See comments in kadm5_c_randkey_principal() regarding the
|
||||
* protocol.
|
||||
*/
|
||||
ret = krb5_ret_int32(sp, &keepold);
|
||||
if (ret != 0 && ret != HEIM_ERR_EOF) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = krb5_ret_int32(sp, &n_ks_tuple);
|
||||
if (ret != 0 && ret != HEIM_ERR_EOF) {
|
||||
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);
|
||||
goto fail;
|
||||
}
|
||||
ret = krb5_ret_int32(sp, &ks_tuple[i].ks_salttype);
|
||||
if (ret != 0) {
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = kadm5_randkey_principal_3(kadm_handlep, princ, keepold,
|
||||
n_ks_tuple, ks_tuple, &new_keys,
|
||||
&n_keys);
|
||||
krb5_free_principal(contextp->context, princ);
|
||||
|
||||
krb5_storage_free(sp);
|
||||
sp = krb5_storage_emem();
|
||||
krb5_store_int32(sp, ret);
|
||||
|
||||
@@ -145,6 +145,61 @@ edit_attributes (const char *prompt, krb5_flags *attr, int *mask, int bit)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* try to parse the string `resp' into policy in `attr', also
|
||||
* setting the `bit' in `mask' if attributes are given and valid.
|
||||
*/
|
||||
|
||||
#define VALID_POLICY_NAME_CHARS \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
|
||||
|
||||
int
|
||||
parse_policy (const char *resp, char **policy, int *mask, int bit)
|
||||
{
|
||||
if (strspn(resp, VALID_POLICY_NAME_CHARS) == strlen(resp) &&
|
||||
*resp != '\0') {
|
||||
|
||||
*policy = strdup(resp);
|
||||
if (*policy == NULL) {
|
||||
fprintf (stderr, "Out of memory");
|
||||
return -1;
|
||||
}
|
||||
if (mask)
|
||||
*mask |= bit;
|
||||
return 0;
|
||||
} else if(*resp == '?') {
|
||||
print_flags_table (kdb_attrs, stderr);
|
||||
} else {
|
||||
fprintf (stderr, "Unable to parse \"%s\"\n", resp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* allow the user to edit the attributes in `attr', prompting with `prompt'
|
||||
*/
|
||||
|
||||
int
|
||||
edit_policy (const char *prompt, char **policy, int *mask, int bit)
|
||||
{
|
||||
char buf[1024], resp[1024];
|
||||
|
||||
if (mask && (*mask & bit))
|
||||
return 0;
|
||||
|
||||
buf[0] = '\0';
|
||||
strlcpy(buf, "default", sizeof (buf));
|
||||
for (;;) {
|
||||
if(get_response("Policy", buf, resp, sizeof(resp)) != 0)
|
||||
return 1;
|
||||
if (resp[0] == '\0')
|
||||
break;
|
||||
if (parse_policy (resp, policy, mask, bit) == 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* time_t
|
||||
* the special value 0 means ``never''
|
||||
@@ -391,6 +446,14 @@ set_defaults(kadm5_principal_ent_t ent, int *mask,
|
||||
&& (default_mask & KADM5_ATTRIBUTES)
|
||||
&& !(*mask & KADM5_ATTRIBUTES))
|
||||
ent->attributes = default_ent->attributes & ~KRB5_KDB_DISALLOW_ALL_TIX;
|
||||
|
||||
if (default_ent
|
||||
&& (default_mask & KADM5_POLICY)
|
||||
&& !(*mask & KADM5_POLICY)) {
|
||||
ent->policy = strdup(default_ent->policy);
|
||||
if (ent->policy == NULL)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -420,6 +483,10 @@ edit_entry(kadm5_principal_ent_t ent, int *mask,
|
||||
KADM5_ATTRIBUTES) != 0)
|
||||
return 1;
|
||||
|
||||
if(edit_policy ("Policy", &ent->policy, mask,
|
||||
KADM5_POLICY) != 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -437,7 +504,8 @@ set_entry(krb5_context contextp,
|
||||
const char *max_renewable_life,
|
||||
const char *expiration,
|
||||
const char *pw_expiration,
|
||||
const char *attributes)
|
||||
const char *attributes,
|
||||
const char *policy)
|
||||
{
|
||||
if (max_ticket_life != NULL) {
|
||||
if (parse_deltat (max_ticket_life, &ent->max_life,
|
||||
@@ -475,6 +543,13 @@ set_entry(krb5_context contextp,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (policy != NULL) {
|
||||
if (parse_policy (policy, &ent->policy,
|
||||
mask, KADM5_POLICY)) {
|
||||
krb5_warnx (contextp, "unable to parse `%s'", attributes);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user