f50ceacadf
Switch to upstream's ksu path patch
467 lines
16 KiB
Diff
467 lines
16 KiB
Diff
From 43c7d037b5e6bac3345c069af70f3cd6fd947f3f Mon Sep 17 00:00:00 2001
|
|
From: Robbie Harwood <rharwood@redhat.com>
|
|
Date: Thu, 4 Apr 2019 16:14:46 -0400
|
|
Subject: [PATCH] Remove kadmin RPC support for setting v4 key
|
|
|
|
ticket: 8794 (new)
|
|
(cherry picked from commit 752187a441ed0f301f1a8adb1fea843080ac8c97)
|
|
---
|
|
src/kadmin/server/kadm_rpc_svc.c | 7 --
|
|
src/kadmin/server/ovsec_kadmd.c | 2 +-
|
|
src/kadmin/server/server_stubs.c | 50 ---------
|
|
src/lib/kadm5/admin.h | 3 -
|
|
src/lib/kadm5/admin_xdr.h | 1 -
|
|
src/lib/kadm5/clnt/Makefile.in | 2 +-
|
|
src/lib/kadm5/clnt/client_principal.c | 22 ----
|
|
src/lib/kadm5/clnt/client_rpc.c | 8 --
|
|
src/lib/kadm5/clnt/libkadm5clnt_mit.exports | 2 -
|
|
src/lib/kadm5/kadm_rpc.h | 16 +--
|
|
src/lib/kadm5/kadm_rpc_xdr.c | 19 ----
|
|
src/lib/kadm5/srv/Makefile.in | 2 +-
|
|
src/lib/kadm5/srv/libkadm5srv_mit.exports | 2 -
|
|
src/lib/kadm5/srv/svr_principal.c | 118 --------------------
|
|
14 files changed, 6 insertions(+), 248 deletions(-)
|
|
|
|
diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c
|
|
index 41fc88ac8..d343e2c25 100644
|
|
--- a/src/kadmin/server/kadm_rpc_svc.c
|
|
+++ b/src/kadmin/server/kadm_rpc_svc.c
|
|
@@ -53,7 +53,6 @@ void kadm_1(rqstp, transp)
|
|
mpol_arg modify_policy_2_arg;
|
|
gpol_arg get_policy_2_arg;
|
|
setkey_arg setkey_principal_2_arg;
|
|
- setv4key_arg setv4key_principal_2_arg;
|
|
cprinc3_arg create_principal3_2_arg;
|
|
chpass3_arg chpass_principal3_2_arg;
|
|
chrand3_arg chrand_principal3_2_arg;
|
|
@@ -134,12 +133,6 @@ void kadm_1(rqstp, transp)
|
|
local = (bool_t (*)()) chpass_principal_2_svc;
|
|
break;
|
|
|
|
- case SETV4KEY_PRINCIPAL:
|
|
- xdr_argument = xdr_setv4key_arg;
|
|
- xdr_result = xdr_generic_ret;
|
|
- local = (bool_t (*)()) setv4key_principal_2_svc;
|
|
- break;
|
|
-
|
|
case SETKEY_PRINCIPAL:
|
|
xdr_argument = xdr_setkey_arg;
|
|
xdr_result = xdr_generic_ret;
|
|
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
|
|
index 6a6b21401..3737791b6 100644
|
|
--- a/src/kadmin/server/ovsec_kadmd.c
|
|
+++ b/src/kadmin/server/ovsec_kadmd.c
|
|
@@ -227,7 +227,7 @@ log_badverf(gss_name_t client_name, gss_name_t server_name,
|
|
{14, "GET_PRINCS"},
|
|
{15, "GET_POLS"},
|
|
{16, "SETKEY_PRINCIPAL"},
|
|
- {17, "SETV4KEY_PRINCIPAL"},
|
|
+ /* 17 was "SETV4KEY_PRINCIPAL" */
|
|
{18, "CREATE_PRINCIPAL3"},
|
|
{19, "CHPASS_PRINCIPAL3"},
|
|
{20, "CHRAND_PRINCIPAL3"},
|
|
diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c
|
|
index cfef97fec..d5a25e502 100644
|
|
--- a/src/kadmin/server/server_stubs.c
|
|
+++ b/src/kadmin/server/server_stubs.c
|
|
@@ -893,56 +893,6 @@ exit_func:
|
|
return TRUE;
|
|
}
|
|
|
|
-bool_t
|
|
-setv4key_principal_2_svc(setv4key_arg *arg, generic_ret *ret,
|
|
- struct svc_req *rqstp)
|
|
-{
|
|
- char *prime_arg = NULL;
|
|
- gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER;
|
|
- gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER;
|
|
- kadm5_server_handle_t handle;
|
|
- const char *errmsg = NULL;
|
|
-
|
|
- ret->code = stub_setup(arg->api_version, rqstp, arg->princ, &handle,
|
|
- &ret->api_version, &client_name, &service_name,
|
|
- &prime_arg);
|
|
- if (ret->code)
|
|
- goto exit_func;
|
|
-
|
|
- ret->code = check_lockdown_keys(handle, arg->princ);
|
|
- if (ret->code != KADM5_OK) {
|
|
- if (ret->code == KADM5_PROTECT_KEYS) {
|
|
- log_unauth("kadm5_setv4key_principal", prime_arg, &client_name,
|
|
- &service_name, rqstp);
|
|
- ret->code = KADM5_AUTH_SETKEY;
|
|
- }
|
|
- } else if (!(CHANGEPW_SERVICE(rqstp)) &&
|
|
- stub_auth(handle, OP_SETKEY, arg->princ, NULL, NULL, NULL)) {
|
|
- ret->code = kadm5_setv4key_principal(handle, arg->princ,
|
|
- arg->keyblock);
|
|
- } else {
|
|
- log_unauth("kadm5_setv4key_principal", prime_arg,
|
|
- &client_name, &service_name, rqstp);
|
|
- ret->code = KADM5_AUTH_SETKEY;
|
|
- }
|
|
-
|
|
- if (ret->code != KADM5_AUTH_SETKEY) {
|
|
- if (ret->code != 0)
|
|
- errmsg = krb5_get_error_message(handle->context, ret->code);
|
|
-
|
|
- log_done("kadm5_setv4key_principal", prime_arg, errmsg,
|
|
- &client_name, &service_name, rqstp);
|
|
-
|
|
- if (errmsg != NULL)
|
|
- krb5_free_error_message(handle->context, errmsg);
|
|
- }
|
|
-
|
|
-exit_func:
|
|
- stub_cleanup(handle, prime_arg, &client_name, &service_name);
|
|
- return TRUE;
|
|
-}
|
|
-
|
|
-
|
|
bool_t
|
|
setkey_principal_2_svc(setkey_arg *arg, generic_ret *ret,
|
|
struct svc_req *rqstp)
|
|
diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h
|
|
index b765148b3..7268be44e 100644
|
|
--- a/src/lib/kadm5/admin.h
|
|
+++ b/src/lib/kadm5/admin.h
|
|
@@ -394,9 +394,6 @@ kadm5_ret_t kadm5_randkey_principal_3(void *server_handle,
|
|
krb5_key_salt_tuple *ks_tuple,
|
|
krb5_keyblock **keyblocks,
|
|
int *n_keys);
|
|
-kadm5_ret_t kadm5_setv4key_principal(void *server_handle,
|
|
- krb5_principal principal,
|
|
- krb5_keyblock *keyblock);
|
|
|
|
kadm5_ret_t kadm5_setkey_principal(void *server_handle,
|
|
krb5_principal principal,
|
|
diff --git a/src/lib/kadm5/admin_xdr.h b/src/lib/kadm5/admin_xdr.h
|
|
index 2d22611e7..9da98451e 100644
|
|
--- a/src/lib/kadm5/admin_xdr.h
|
|
+++ b/src/lib/kadm5/admin_xdr.h
|
|
@@ -37,7 +37,6 @@ bool_t xdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp);
|
|
bool_t xdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp);
|
|
bool_t xdr_chpass_arg(XDR *xdrs, chpass_arg *objp);
|
|
bool_t xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp);
|
|
-bool_t xdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp);
|
|
bool_t xdr_setkey_arg(XDR *xdrs, setkey_arg *objp);
|
|
bool_t xdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp);
|
|
bool_t xdr_setkey4_arg(XDR *xdrs, setkey4_arg *objp);
|
|
diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in
|
|
index a180e85cd..2bc385afe 100644
|
|
--- a/src/lib/kadm5/clnt/Makefile.in
|
|
+++ b/src/lib/kadm5/clnt/Makefile.in
|
|
@@ -3,7 +3,7 @@ BUILDTOP=$(REL)..$(S)..$(S)..
|
|
LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5
|
|
|
|
LIBBASE=kadm5clnt_mit
|
|
-LIBMAJOR=11
|
|
+LIBMAJOR=12
|
|
LIBMINOR=0
|
|
STOBJLISTS=../OBJS.ST OBJS.ST
|
|
SHLIB_EXPDEPS=\
|
|
diff --git a/src/lib/kadm5/clnt/client_principal.c b/src/lib/kadm5/clnt/client_principal.c
|
|
index 18714bf37..96d9d1932 100644
|
|
--- a/src/lib/kadm5/clnt/client_principal.c
|
|
+++ b/src/lib/kadm5/clnt/client_principal.c
|
|
@@ -273,28 +273,6 @@ kadm5_chpass_principal_3(void *server_handle,
|
|
return r.code;
|
|
}
|
|
|
|
-kadm5_ret_t
|
|
-kadm5_setv4key_principal(void *server_handle,
|
|
- krb5_principal princ,
|
|
- krb5_keyblock *keyblock)
|
|
-{
|
|
- setv4key_arg arg;
|
|
- generic_ret r = { 0, 0 };
|
|
- kadm5_server_handle_t handle = server_handle;
|
|
-
|
|
- CHECK_HANDLE(server_handle);
|
|
-
|
|
- arg.princ = princ;
|
|
- arg.keyblock = keyblock;
|
|
- arg.api_version = handle->api_version;
|
|
-
|
|
- if(princ == NULL || keyblock == NULL)
|
|
- return EINVAL;
|
|
- if (setv4key_principal_2(&arg, &r, handle->clnt))
|
|
- eret();
|
|
- return r.code;
|
|
-}
|
|
-
|
|
kadm5_ret_t
|
|
kadm5_setkey_principal(void *server_handle,
|
|
krb5_principal princ,
|
|
diff --git a/src/lib/kadm5/clnt/client_rpc.c b/src/lib/kadm5/clnt/client_rpc.c
|
|
index df5455fd8..d84d158b4 100644
|
|
--- a/src/lib/kadm5/clnt/client_rpc.c
|
|
+++ b/src/lib/kadm5/clnt/client_rpc.c
|
|
@@ -84,14 +84,6 @@ chpass_principal3_2(chpass3_arg *argp, generic_ret *res, CLIENT *clnt)
|
|
(xdrproc_t)xdr_generic_ret, (caddr_t)res, TIMEOUT);
|
|
}
|
|
|
|
-enum clnt_stat
|
|
-setv4key_principal_2(setv4key_arg *argp, generic_ret *res, CLIENT *clnt)
|
|
-{
|
|
- return clnt_call(clnt, SETV4KEY_PRINCIPAL,
|
|
- (xdrproc_t)xdr_setv4key_arg, (caddr_t)argp,
|
|
- (xdrproc_t)xdr_generic_ret, (caddr_t)res, TIMEOUT);
|
|
-}
|
|
-
|
|
enum clnt_stat
|
|
setkey_principal_2(setkey_arg *argp, generic_ret *res, CLIENT *clnt)
|
|
{
|
|
diff --git a/src/lib/kadm5/clnt/libkadm5clnt_mit.exports b/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
|
|
index f122b31ab..e41c8e4f7 100644
|
|
--- a/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
|
|
+++ b/src/lib/kadm5/clnt/libkadm5clnt_mit.exports
|
|
@@ -44,7 +44,6 @@ kadm5_set_string
|
|
kadm5_setkey_principal
|
|
kadm5_setkey_principal_3
|
|
kadm5_setkey_principal_4
|
|
-kadm5_setv4key_principal
|
|
kadm5_unlock
|
|
krb5_aprof_finish
|
|
krb5_aprof_get_boolean
|
|
@@ -114,6 +113,5 @@ xdr_rprinc_arg
|
|
xdr_setkey3_arg
|
|
xdr_setkey4_arg
|
|
xdr_setkey_arg
|
|
-xdr_setv4key_arg
|
|
xdr_ui_4
|
|
kadm5_init_iprop
|
|
diff --git a/src/lib/kadm5/kadm_rpc.h b/src/lib/kadm5/kadm_rpc.h
|
|
index 8d7cf3b36..5099c6c14 100644
|
|
--- a/src/lib/kadm5/kadm_rpc.h
|
|
+++ b/src/lib/kadm5/kadm_rpc.h
|
|
@@ -82,13 +82,6 @@ struct chpass3_arg {
|
|
};
|
|
typedef struct chpass3_arg chpass3_arg;
|
|
|
|
-struct setv4key_arg {
|
|
- krb5_ui_4 api_version;
|
|
- krb5_principal princ;
|
|
- krb5_keyblock *keyblock;
|
|
-};
|
|
-typedef struct setv4key_arg setv4key_arg;
|
|
-
|
|
struct setkey_arg {
|
|
krb5_ui_4 api_version;
|
|
krb5_principal princ;
|
|
@@ -322,11 +315,9 @@ extern enum clnt_stat setkey_principal_2(setkey_arg *, generic_ret *,
|
|
CLIENT *);
|
|
extern bool_t setkey_principal_2_svc(setkey_arg *, generic_ret *,
|
|
struct svc_req *);
|
|
-#define SETV4KEY_PRINCIPAL 17
|
|
-extern enum clnt_stat setv4key_principal_2(setv4key_arg *, generic_ret *,
|
|
- CLIENT *);
|
|
-extern bool_t setv4key_principal_2_svc(setv4key_arg *, generic_ret *,
|
|
- struct svc_req *);
|
|
+
|
|
+/* 17 was SETV4KEY_PRINCIPAL (removed in 1.18). */
|
|
+
|
|
#define CREATE_PRINCIPAL3 18
|
|
extern enum clnt_stat create_principal3_2(cprinc3_arg *, generic_ret *,
|
|
CLIENT *);
|
|
@@ -380,7 +371,6 @@ extern bool_t xdr_gprincs_arg ();
|
|
extern bool_t xdr_gprincs_ret ();
|
|
extern bool_t xdr_chpass_arg ();
|
|
extern bool_t xdr_chpass3_arg ();
|
|
-extern bool_t xdr_setv4key_arg ();
|
|
extern bool_t xdr_setkey_arg ();
|
|
extern bool_t xdr_setkey3_arg ();
|
|
extern bool_t xdr_setkey4_arg ();
|
|
diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
|
|
index 2892d4147..745ee857e 100644
|
|
--- a/src/lib/kadm5/kadm_rpc_xdr.c
|
|
+++ b/src/lib/kadm5/kadm_rpc_xdr.c
|
|
@@ -710,25 +710,6 @@ xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp)
|
|
return (TRUE);
|
|
}
|
|
|
|
-bool_t
|
|
-xdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp)
|
|
-{
|
|
- unsigned int n_keys = 1;
|
|
-
|
|
- if (!xdr_ui_4(xdrs, &objp->api_version)) {
|
|
- return (FALSE);
|
|
- }
|
|
- if (!xdr_krb5_principal(xdrs, &objp->princ)) {
|
|
- return (FALSE);
|
|
- }
|
|
- if (!xdr_array(xdrs, (caddr_t *) &objp->keyblock,
|
|
- &n_keys, ~0,
|
|
- sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
|
|
- return (FALSE);
|
|
- }
|
|
- return (TRUE);
|
|
-}
|
|
-
|
|
bool_t
|
|
xdr_setkey_arg(XDR *xdrs, setkey_arg *objp)
|
|
{
|
|
diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in
|
|
index 617d65666..89e6097cf 100644
|
|
--- a/src/lib/kadm5/srv/Makefile.in
|
|
+++ b/src/lib/kadm5/srv/Makefile.in
|
|
@@ -9,7 +9,7 @@ DEFINES = @HESIOD_DEFS@
|
|
##DOSLIBNAME = libkadm5srv.lib
|
|
|
|
LIBBASE=kadm5srv_mit
|
|
-LIBMAJOR=11
|
|
+LIBMAJOR=12
|
|
LIBMINOR=0
|
|
STOBJLISTS=../OBJS.ST OBJS.ST
|
|
|
|
diff --git a/src/lib/kadm5/srv/libkadm5srv_mit.exports b/src/lib/kadm5/srv/libkadm5srv_mit.exports
|
|
index 64ad5dd69..e3c04e690 100644
|
|
--- a/src/lib/kadm5/srv/libkadm5srv_mit.exports
|
|
+++ b/src/lib/kadm5/srv/libkadm5srv_mit.exports
|
|
@@ -45,7 +45,6 @@ kadm5_set_string
|
|
kadm5_setkey_principal
|
|
kadm5_setkey_principal_3
|
|
kadm5_setkey_principal_4
|
|
-kadm5_setv4key_principal
|
|
kadm5_unlock
|
|
kdb_delete_entry
|
|
kdb_free_entry
|
|
@@ -133,7 +132,6 @@ xdr_rprinc_arg
|
|
xdr_setkey3_arg
|
|
xdr_setkey4_arg
|
|
xdr_setkey_arg
|
|
-xdr_setv4key_arg
|
|
xdr_sstring_arg
|
|
xdr_ui_4
|
|
kadm5_init_iprop
|
|
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
|
|
index 9ab2c5a74..48cac0c11 100644
|
|
--- a/src/lib/kadm5/srv/svr_principal.c
|
|
+++ b/src/lib/kadm5/srv/svr_principal.c
|
|
@@ -1645,124 +1645,6 @@ done:
|
|
return ret;
|
|
}
|
|
|
|
-/*
|
|
- * kadm5_setv4key_principal:
|
|
- *
|
|
- * Set only ONE key of the principal, removing all others. This key
|
|
- * must have the DES_CBC_CRC enctype and is entered as having the
|
|
- * krb4 salttype. This is to enable things like kadmind4 to work.
|
|
- */
|
|
-kadm5_ret_t
|
|
-kadm5_setv4key_principal(void *server_handle,
|
|
- krb5_principal principal,
|
|
- krb5_keyblock *keyblock)
|
|
-{
|
|
- krb5_db_entry *kdb;
|
|
- osa_princ_ent_rec adb;
|
|
- krb5_timestamp now;
|
|
- kadm5_policy_ent_rec pol;
|
|
- krb5_keysalt keysalt;
|
|
- int i, kvno, ret;
|
|
- krb5_boolean have_pol = FALSE;
|
|
- kadm5_server_handle_t handle = server_handle;
|
|
- krb5_key_data tmp_key_data;
|
|
- krb5_keyblock *act_mkey;
|
|
-
|
|
- memset( &tmp_key_data, 0, sizeof(tmp_key_data));
|
|
-
|
|
- CHECK_HANDLE(server_handle);
|
|
-
|
|
- krb5_clear_error_message(handle->context);
|
|
-
|
|
- if (principal == NULL || keyblock == NULL)
|
|
- return EINVAL;
|
|
- if (hist_princ && /* this will be NULL when initializing the databse */
|
|
- ((krb5_principal_compare(handle->context,
|
|
- principal, hist_princ)) == TRUE))
|
|
- return KADM5_PROTECT_PRINCIPAL;
|
|
-
|
|
- if (keyblock->enctype != ENCTYPE_DES_CBC_CRC)
|
|
- return KADM5_SETV4KEY_INVAL_ENCTYPE;
|
|
-
|
|
- if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
|
|
- return(ret);
|
|
-
|
|
- for (kvno = 0, i=0; i<kdb->n_key_data; i++)
|
|
- if (kdb->key_data[i].key_data_kvno > kvno)
|
|
- kvno = kdb->key_data[i].key_data_kvno;
|
|
-
|
|
- if (kdb->key_data != NULL)
|
|
- cleanup_key_data(handle->context, kdb->n_key_data, kdb->key_data);
|
|
-
|
|
- kdb->key_data = calloc(1, sizeof(krb5_key_data));
|
|
- if (kdb->key_data == NULL)
|
|
- return ENOMEM;
|
|
- kdb->n_key_data = 1;
|
|
- keysalt.type = KRB5_KDB_SALTTYPE_V4;
|
|
- /* XXX data.magic? */
|
|
- keysalt.data.length = 0;
|
|
- keysalt.data.data = NULL;
|
|
-
|
|
- ret = kdb_get_active_mkey(handle, NULL, &act_mkey);
|
|
- if (ret)
|
|
- goto done;
|
|
-
|
|
- /* use tmp_key_data as temporary location and reallocate later */
|
|
- ret = krb5_dbe_encrypt_key_data(handle->context, act_mkey, keyblock,
|
|
- &keysalt, kvno + 1, kdb->key_data);
|
|
- if (ret) {
|
|
- goto done;
|
|
- }
|
|
-
|
|
- kdb->attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
|
|
-
|
|
- ret = krb5_timeofday(handle->context, &now);
|
|
- if (ret)
|
|
- goto done;
|
|
-
|
|
- if ((adb.aux_attributes & KADM5_POLICY)) {
|
|
- ret = get_policy(handle, adb.policy, &pol, &have_pol);
|
|
- if (ret)
|
|
- goto done;
|
|
- }
|
|
- if (have_pol) {
|
|
- if (pol.pw_max_life)
|
|
- kdb->pw_expiration = ts_incr(now, pol.pw_max_life);
|
|
- else
|
|
- kdb->pw_expiration = 0;
|
|
- } else {
|
|
- kdb->pw_expiration = 0;
|
|
- }
|
|
-
|
|
- ret = krb5_dbe_update_last_pwd_change(handle->context, kdb, now);
|
|
- if (ret)
|
|
- goto done;
|
|
-
|
|
- /* unlock principal on this KDC */
|
|
- kdb->fail_auth_count = 0;
|
|
-
|
|
- /* key data changed, let the database provider know */
|
|
- kdb->mask = KADM5_KEY_DATA | KADM5_FAIL_AUTH_COUNT;
|
|
-
|
|
- if ((ret = kdb_put_entry(handle, kdb, &adb)))
|
|
- goto done;
|
|
-
|
|
- ret = KADM5_OK;
|
|
-done:
|
|
- for (i = 0; i < tmp_key_data.key_data_ver; i++) {
|
|
- if (tmp_key_data.key_data_contents[i]) {
|
|
- memset (tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]);
|
|
- free (tmp_key_data.key_data_contents[i]);
|
|
- }
|
|
- }
|
|
-
|
|
- kdb_free_entry(handle, kdb, &adb);
|
|
- if (have_pol)
|
|
- kadm5_free_policy_ent(handle->lhandle, &pol);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
kadm5_ret_t
|
|
kadm5_setkey_principal(void *server_handle,
|
|
krb5_principal principal,
|