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:
Love Hörnquist Åstrand
2011-07-24 15:41:36 -07:00
58 changed files with 2136 additions and 404 deletions

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 }
};

View File

@@ -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 = "?"

View File

@@ -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 .

View File

@@ -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)
{

View File

@@ -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 *);

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;
}