Whamcloud - gitweb
LU-17023 krb: use a Kerberos realm different from default 14/51914/10
authorSebastien Buisson <sbuisson@ddn.com>
Thu, 10 Aug 2023 11:05:52 +0000 (13:05 +0200)
committerOleg Drokin <green@whamcloud.com>
Wed, 6 Sep 2023 06:21:45 +0000 (06:21 +0000)
It makes sense to give the ability to specify a Kerberos realm that is
different from the default realm as returned by
krb5_get_default_realm().

On client side, the desired realm needs to be specified via the new
'-R' option to lgss_keyring. This can be specified in the config file
/etc/request-key.d/lgssc.conf to replace the default domain, e.g.:
create lgssc * * /usr/sbin/lgss_keyring -R DOMAIN.COM %o %k %t %d %c %u %g %T %P %S

On server side, the desired realm can be specified via the new '-R'
parameter of the lsvcgssd daemon, replacing the default realm.

This patch adds sanity-krb5 test_1b to exercise the new realm options,
by just re-using the same realm as the test system is configured to
use. And former test_1 is renamed test_1a.

Test-Parameters: kerberos=true testlist=sanity-krb5
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I9c91d5cb9904781d546e77b1e46115fed433618f
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51914
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Aurelien Degremont <adegremont@nvidia.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
13 files changed:
lustre/tests/sanity-krb5.sh
lustre/tests/test-framework.sh
lustre/utils/gss/Makefile.am
lustre/utils/gss/gss_util.c
lustre/utils/gss/gss_util.h
lustre/utils/gss/lgss_keyring.c
lustre/utils/gss/lgss_krb5_utils.c
lustre/utils/gss/lgss_krb5_utils.h
lustre/utils/gss/lgss_utils.c
lustre/utils/gss/lgss_utils.h
lustre/utils/gss/lsupport.c
lustre/utils/gss/lsupport.h
lustre/utils/gss/svcgssd.c

index 2cfce7a..017f18a 100755 (executable)
@@ -195,7 +195,7 @@ run_test 0 "start multiple gss daemons"
 
 set_flavor_all krb5p
 
-test_1() {
+test_1a() {
        local file=$DIR/$tdir/$tfile
 
        mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
@@ -211,7 +211,41 @@ test_1() {
        $RUNAS touch $file || error "should not fail"
        [ -f $file ] || error "$file not found"
 }
-run_test 1 "access with or without krb5 credential"
+run_test 1a "access with or without krb5 credential"
+
+test_1b() {
+       local file=$DIR/$tdir/$tfile
+       local lgssconf=/etc/request-key.d/lgssc.conf
+       local clients=$CLIENTS
+       local realm
+
+       [ -z $clients ] && clients=$HOSTNAME
+       zconf_umount_clients $clients $MOUNT || error "umount clients failed"
+
+       echo "stop gss daemons..."
+       stop_gss_daemons
+
+       # get local realm from krb5.conf, assume the same for all nodes
+       realm=$(grep default_realm /etc/krb5.conf | awk '{print $3}')
+
+       # add -R option to lgss_keyring on local client
+       cp $lgssconf $TMP/lgssc.conf
+       stack_trap "yes | cp $TMP/lgssc.conf $lgssconf" EXIT
+       sed -i s+lgss_keyring+\&\ \-R\ $realm+ $lgssconf
+
+       # add -R option to lsvcgssd
+       echo "bring up gss daemons..."
+       start_gss_daemons '' '' "-R $realm"
+       stack_trap "stop_gss_daemons ; start_gss_daemons" EXIT
+
+       zconf_mount_clients $clients $MOUNT || error "mount clients failed"
+
+       mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       chmod 0777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
+       $RUNAS touch $file || error "touch $file failed"
+       [ -f $file ] || error "$file not found"
+}
+run_test 1b "Use specified realm"
 
 test_2() {
        local file1=$DIR/$tdir/$tfile-1
index 46c9d04..7abd208 100755 (executable)
@@ -1000,10 +1000,11 @@ send_sigint() {
 start_gss_daemons() {
        local nodes=$1
        local daemon=$2
+       local options=$3
 
        if [ "$nodes" ] && [ "$daemon" ] ; then
                echo "Starting gss daemon on nodes: $nodes"
-               do_nodes $nodes "$daemon" || return 8
+               do_nodes $nodes "$daemon" "$options" || return 8
                return 0
        fi
 
@@ -1011,18 +1012,20 @@ start_gss_daemons() {
        echo "Starting gss daemon on mds: $nodes"
        if $GSS_SK; then
                # Start all versions, in case of switching
-               do_nodes $nodes "$LSVCGSSD -vvv -s -m -o -z" || return 1
+               do_nodes $nodes "$LSVCGSSD -vvv -s -m -o -z $options" ||
+                       return 1
        else
-               do_nodes $nodes "$LSVCGSSD -vvv" || return 1
+               do_nodes $nodes "$LSVCGSSD -vvv $options" || return 1
        fi
 
        nodes=$(comma_list $(osts_nodes))
        echo "Starting gss daemon on ost: $nodes"
        if $GSS_SK; then
                # Start all versions, in case of switching
-               do_nodes $nodes "$LSVCGSSD -vvv -s -m -o -z" || return 3
+               do_nodes $nodes "$LSVCGSSD -vvv -s -m -o -z $options" ||
+                       return 3
        else
-               do_nodes $nodes "$LSVCGSSD -vvv" || return 3
+               do_nodes $nodes "$LSVCGSSD -vvv $options" || return 3
        fi
        # starting on clients
 
index 78d1296..be33ffe 100644 (file)
@@ -59,7 +59,7 @@ l_idmap_SOURCES = \
        \
        lsupport.h
 
-l_idmap_LDADD = $(top_builddir)/lustre/utils/liblustreapi.la
+l_idmap_LDADD = $(top_builddir)/lustre/utils/liblustreapi.la $(KRBLIBS)
 
 lgss_keyring_SOURCES = \
        lgss_keyring.c \
index df5a8d3..4c983a5 100644 (file)
@@ -207,8 +207,9 @@ int extract_realm_name(gss_buffer_desc *name, char **realm)
 
         c = strchr(sname, '@');
         if (!c) {
-               printerr(2, "no realm found in principal, use default\n");
-               *realm = strdup(this_realm);
+               printerr(2, "no realm in principal, using '%s' instead\n",
+                        krb5_this_realm);
+               *realm = strdup(krb5_this_realm);
                 if (!*realm) {
                         printerr(0, "failed to duplicate default realm\n");
                         rc = -ENOMEM;
@@ -381,36 +382,26 @@ out:
  * FIXME should be in krb5_util.c
  *********************************/
 
-/* realm of this node */
-char *this_realm = NULL;
-
-int gssd_get_local_realm(void)
+void gssd_cleanup_realms(void)
 {
        krb5_context context = NULL;
        krb5_error_code code;
-       int retval = -1;
 
-       if (this_realm != NULL)
-               return 0;
-
-       code = krb5_init_context(&context);
-       if (code) {
-               printerr(0, "ERROR: get default realm: init ctx: %s\n",
-                        error_message(code));
-               goto out;
-       }
-
-       code = krb5_get_default_realm(context, &this_realm);
-       if (code) {
-               printerr(0, "ERROR: get default realm: %s\n",
-                        error_message(code));
-               goto out;
+       if (krb5_this_realm) {
+               code = krb5_init_context(&context);
+               if (code) {
+                       printerr(0, "ERROR: cleanup realms: init ctx: %s\n",
+                                error_message(code));
+               } else {
+                       krb5_free_string(context, krb5_this_realm);
+                       krb5_this_realm = NULL;
+                       krb5_free_context(context);
+               }
        }
-       retval = 0;
-
-       printerr(1, "Local realm: %s\n", this_realm);
-out:
-       krb5_free_context(context);
-       return retval;
+       if (mgs_local_realm)
+               free(mgs_local_realm);
+       if (mds_local_realm)
+               free(mds_local_realm);
+       if (oss_local_realm)
+               free(oss_local_realm);
 }
-
index b53c256..648b347 100644 (file)
 # endif
 #endif
 
-extern char *this_realm;
 extern gss_cred_id_t   gssd_creds;
 
 void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat,
        const gss_OID mech);
 int gssd_check_mechs(void);
-int gssd_get_local_realm(void);
+void gssd_cleanup_realms(void);
 
 #endif /* _GSS_UTIL_H_ */
index 4883e1e..e0bb94b 100644 (file)
 #include <keyutils.h>
 #include <gssapi/gssapi.h>
 #include <sys/wait.h>
+#include <getopt.h>
 
 #include <libcfs/util/param.h>
 #include <libcfs/util/string.h>
 #include <uapi/linux/lustre/lgss.h>
 #include "lsupport.h"
 #include "lgss_utils.h"
+#include "lgss_krb5_utils.h"
 #include "write_bytes.h"
 #include "context.h"
 
@@ -953,23 +955,47 @@ static int prepare_and_instantiate(struct lgss_cred *cred, key_serial_t keyid,
 
 int main(int argc, char *argv[])
 {
-       struct keyring_upcall_param   uparam;
-       key_serial_t                  keyid;
-       key_serial_t                  sring;
-       pid_t                         child;
-       int                           req_fd[2] = { -1, -1 };
-       int                           reply_fd[2] = { -1, -1 };
-       struct lgss_mech_type        *mech;
-       struct lgss_cred             *cred;
-       char                          path[PATH_MAX] = "";
-       int                           other_ns = 0;
-       int                           rc = 0;
-       struct stat                   parent_ns = { .st_ino = 0 };
-       struct stat                   caller_ns = { .st_ino = 0 };
+       struct keyring_upcall_param uparam;
+       key_serial_t keyid;
+       key_serial_t sring;
+       pid_t child;
+       int req_fd[2] = { -1, -1 };
+       int reply_fd[2] = { -1, -1 };
+       struct lgss_mech_type *mech;
+       struct lgss_cred *cred;
+       char path[PATH_MAX] = "";
+       int other_ns = 0;
+       int rc = 0, opt;
+       struct stat parent_ns = { .st_ino = 0 };
+       struct stat caller_ns = { .st_ino = 0 };
+
+       static struct option long_opts[] = {
+               { .name = "realm", .has_arg = required_argument, .val = 'R'},
+               { .name = NULL, } };
 
        set_log_level();
 
        logmsg(LL_TRACE, "start parsing parameters\n");
+
+       /* one possible option before upcall parameters: -R REALM */
+       while ((opt = getopt_long(argc, argv, "R:", long_opts, NULL)) != EOF) {
+               switch (opt) {
+               case 'R':
+                       lgss_client_realm = optarg;
+                       break;
+               default:
+                       logmsg(LL_ERR, "invalid parameter %s\n",
+                              argv[optind - 1]);
+                       return 1;
+               }
+       }
+
+       if (lgss_client_realm) {
+               /* shift args to meet expected upcall parameters */
+               argc -= optind - 1;
+               argv += optind - 1;
+       }
+
        /*
         * parse & sanity check upcall parameters
         * expected to be called with:
@@ -1234,6 +1260,7 @@ out_pipe:
                close(req_fd[1]);
                close(reply_fd[0]);
                close(reply_fd[1]);
+               lgss_fini(cred);
                return rc;
        } else {
                if (uparam.kup_pid)
@@ -1243,7 +1270,7 @@ out_pipe:
 
                rc = prepare_and_instantiate(cred, keyid, uparam.kup_uid);
                if (rc != 0)
-                       return rc;
+                       goto out_reg;
 
                /*
                 * fork a child to do the real gss negotiation
@@ -1252,13 +1279,19 @@ out_pipe:
                if (child == -1) {
                        logmsg(LL_ERR, "key %08x: can't create child: %s\n",
                               keyid, strerror(errno));
-                       return 1;
+                       rc = 1;
+                       goto out_reg;
                } else if (child == 0) {
-                       return lgssc_kr_negotiate(keyid, cred, &uparam,
-                                                 req_fd, reply_fd);
+                       rc = lgssc_kr_negotiate(keyid, cred, &uparam,
+                                               req_fd, reply_fd);
+                       goto out_reg;
+               } else {
+                       logmsg(LL_TRACE, "forked child %d\n", child);
+                       return rc;
                }
 
-               logmsg(LL_TRACE, "forked child %d\n", child);
-               return 0;
+out_reg:
+               lgss_fini(cred);
+               return rc;
        }
 }
index d59e49f..ebe09fb 100644 (file)
 #include "lgss_utils.h"
 #include "lgss_krb5_utils.h"
 
+char *lgss_client_realm;
+
 static void lgss_krb5_mutex_lock(void)
 {
         if (lgss_mutex_lock(LGSS_MUTEX_KRB5)) {
@@ -155,7 +157,6 @@ const char *krb5_cred_root_suffix  = "lustre_root";
 const char *krb5_cred_mds_suffix   = "lustre_mds";
 const char *krb5_cred_oss_suffix   = "lustre_oss";
 
-char    *krb5_this_realm        = NULL;
 char    *krb5_keytab_file       = "/etc/krb5.keytab";
 
 static int lgss_krb5_set_ccache_name(const char *ccname)
@@ -173,35 +174,6 @@ static int lgss_krb5_set_ccache_name(const char *ccname)
 }
 
 static
-int lgss_krb5_get_local_realm(void)
-{
-        krb5_context    context = NULL;
-        krb5_error_code code;
-        int             retval = -1;
-
-        if (krb5_this_realm != NULL)
-                return 0;
-
-        code = krb5_init_context(&context);
-        if (code) {
-                logmsg(LL_ERR, "init ctx: %s\n", krb5_err_msg(code));
-                return -1;
-        }
-
-        code = krb5_get_default_realm(context, &krb5_this_realm);
-        if (code) {
-                logmsg(LL_ERR, "get default realm: %s\n", krb5_err_msg(code));
-                goto out;
-        }
-
-        logmsg(LL_DEBUG, "Local realm: %s\n", krb5_this_realm);
-        retval = 0;
-out:
-        krb5_free_context(context);
-        return retval;
-}
-
-static
 int princ_is_local_realm(krb5_context ctx, krb5_principal princ)
 {
         return (lgss_krb5_strcasecmp(krb5_princ_realm(ctx, princ),
@@ -985,8 +957,13 @@ static int lgss_krb5_prepare_cred(struct lgss_cred *cred)
        cred->lc_mech_cred = NULL;
 
        if (cred->lc_root_flags != 0) {
-               if (lgss_krb5_get_local_realm())
+               rc = gss_get_realm(lgss_client_realm);
+               if (rc) {
+                       logmsg(LL_ERR, "ERROR: no Kerberos realm: %s\n",
+                              error_message(rc));
                        return -1;
+               }
+               logmsg(LL_DEBUG, "Kerberos realm: %s\n", krb5_this_realm);
 
                rc = lkrb5_prepare_root_cred(cred);
        } else {
@@ -1002,10 +979,29 @@ void lgss_krb5_release_cred(struct lgss_cred *cred)
         cred->lc_mech_cred = NULL;
 }
 
-struct lgss_mech_type lgss_mech_krb5 = 
+static void lgss_krb5_fini(void)
+{
+       krb5_context context = NULL;
+       krb5_error_code code;
+
+       if (krb5_this_realm) {
+               code = krb5_init_context(&context);
+               if (code) {
+                       logmsg(LL_ERR, "ERROR: krb5 fini: init ctx: %s\n",
+                                error_message(code));
+               } else {
+                       krb5_free_string(context, krb5_this_realm);
+                       krb5_this_realm = NULL;
+                       krb5_free_context(context);
+               }
+       }
+}
+
+struct lgss_mech_type lgss_mech_krb5 =
 {
-        .lmt_name               = "krb5",
-        .lmt_mech_n             = LGSS_MECH_KRB5,
-        .lmt_prepare_cred       = lgss_krb5_prepare_cred,
-        .lmt_release_cred       = lgss_krb5_release_cred,
+       .lmt_name               = "krb5",
+       .lmt_mech_n             = LGSS_MECH_KRB5,
+       .lmt_prepare_cred       = lgss_krb5_prepare_cred,
+       .lmt_release_cred       = lgss_krb5_release_cred,
+       .lmt_fini               = lgss_krb5_fini,
 };
index 5a136f6..74b10ad 100644 (file)
@@ -25,6 +25,8 @@ extern struct lgss_mech_type lgss_mech_sk;
 #define LGSS_USER_CRED_DIR                     "/run/user/%U"
 #define LGSS_DEFAULT_CRED_PREFIX               "krb5cc"
 
+extern char *lgss_client_realm;
+
 /*
  * convenient macros, these perhaps need further cleanup
  */
index 1a077fe..35641c3 100644 (file)
@@ -449,6 +449,16 @@ int lgss_validate_cred(struct lgss_cred *cred, gss_buffer_desc *token,
        return 0;
 }
 
+void lgss_fini(struct lgss_cred *cred)
+{
+       struct lgss_mech_type *mech = cred->lc_mech;
+
+       logmsg(LL_TRACE, "finishing %s\n", mech->lmt_name);
+
+       if (mech && mech->lmt_fini)
+               mech->lmt_fini();
+}
+
 /****************************************
  * helper functions                     *
  ****************************************/
index c708bd4..bfd7858 100644 (file)
@@ -173,6 +173,7 @@ void lgss_release_cred(struct lgss_cred *cred);
 int lgss_using_cred(struct lgss_cred *cred);
 int lgss_validate_cred(struct lgss_cred *cred, gss_buffer_desc *token,
                       gss_buffer_desc *ctx_token);
+void lgss_fini(struct lgss_cred *cred);
 
 int lgss_get_service_str(char **string, uint32_t lsvc, uint64_t tgt_nid);
 
index eda236f..545afa3 100644 (file)
@@ -555,3 +555,53 @@ int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid)
        printerr(LL_INFO, "no mapping for %s/%#Lx\n", princ, nid);
        return -1;
 }
+
+/* realm of this node */
+char *krb5_this_realm;
+
+static int gss_get_provided_realm(char *realm)
+{
+       if (krb5_this_realm)
+               return 0;
+
+       if (!realm)
+               return -1;
+
+       krb5_this_realm = strdup(realm);
+       return 0;
+}
+
+static int gss_get_local_realm(void)
+{
+       krb5_context context = NULL;
+       krb5_error_code code;
+
+       if (krb5_this_realm != NULL)
+               return 0;
+
+       code = krb5_init_context(&context);
+       if (code)
+               return code;
+
+       code = krb5_get_default_realm(context, &krb5_this_realm);
+       krb5_free_context(context);
+
+       if (code)
+               return code;
+
+       return 0;
+}
+
+int gss_get_realm(char *realm)
+{
+       int rc;
+
+       /* Try to use provided realm first.
+        * If no provided realm, get default local realm.
+        */
+       rc = gss_get_provided_realm(realm);
+       if (rc)
+               rc = gss_get_local_realm();
+
+       return rc;
+}
index 8cdf274..bd60f1e 100644 (file)
@@ -44,6 +44,8 @@
 #include <linux/lnet/lnet-types.h>
 #include <linux/lnet/nidstr.h>
 
+#include <krb5.h>
+
 #define GSSD_CLI        (0)
 #define GSSD_SVC        (1)
 
@@ -63,6 +65,7 @@ void gssd_exit_unique(int type);
 #define LUSTRE_GSS_MECH_SHIFT  16
 
 extern const char * lustre_svc_name[];
+extern char *krb5_this_realm;
 
 enum lgss_mech {
        LGSS_MECH_KRB5  = 0,
@@ -104,5 +107,6 @@ uid_t parse_uid(char *uidstr);
 void load_mapping(void);
 int mapping_empty(void);
 int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid);
+int gss_get_realm(char *realm);
 
 #endif /* __LSUPPORT_H__ */
index ff74036..32ad64c 100644 (file)
@@ -168,6 +168,8 @@ sig_die(int signal)
 {
        /* destroy krb5 machine creds */
        cleanup_mapping();
+       /* cleanup allocated strings for realms */
+       gssd_cleanup_realms();
        printerr(LL_WARN, "exiting on signal %d\n", signal);
        exit(1);
 }
@@ -182,19 +184,20 @@ sig_hup(int signal)
 static void
 usage(FILE *fp, char *progname)
 {
-       fprintf(fp, "usage: %s [ -fnvmogk ]\n",
+       fprintf(fp, "usage: %s [ -fnvmogkRsz ]\n",
                progname);
-       fprintf(stderr, "-f      - Run in foreground\n");
-       fprintf(stderr, "-n      - Don't establish kerberos credentials\n");
-       fprintf(stderr, "-v      - Verbosity\n");
-       fprintf(stderr, "-m      - Service MDS\n");
-       fprintf(stderr, "-o      - Service OSS\n");
-       fprintf(stderr, "-g      - Service MGS\n");
-       fprintf(stderr, "-k      - Enable kerberos support\n");
+       fprintf(stderr, "-f             - Run in foreground\n");
+       fprintf(stderr, "-n             - Don't establish kerberos credentials\n");
+       fprintf(stderr, "-v             - Verbosity\n");
+       fprintf(stderr, "-m             - Service MDS\n");
+       fprintf(stderr, "-o             - Service OSS\n");
+       fprintf(stderr, "-g             - Service MGS\n");
+       fprintf(stderr, "-k             - Enable kerberos support\n");
+       fprintf(stderr, "-R REALM       - Kerberos Realm to use, instead of default\n");
 #ifdef HAVE_OPENSSL_SSK
-       fprintf(stderr, "-s      - Enable shared secret key support\n");
+       fprintf(stderr, "-s             - Enable shared secret key support\n");
 #endif
-       fprintf(stderr, "-z      - Enable gssnull support\n");
+       fprintf(stderr, "-z             - Enable gssnull support\n");
 
        exit(fp == stderr);
 }
@@ -207,36 +210,37 @@ main(int argc, char *argv[])
        int verbosity = 0;
        int opt;
        int must_srv_mds = 0, must_srv_oss = 0, must_srv_mgs = 0;
+       char *realm = NULL;
        char *progname;
 
-       while ((opt = getopt(argc, argv, "fnvmogksz")) != -1) {
+       while ((opt = getopt(argc, argv, "fgkmnoR:svz")) != -1) {
                switch (opt) {
                case 'f':
                        fg = 1;
                        break;
-               case 'n':
-                       get_creds = 0;
+               case 'g':
+                       get_creds = 1;
+                       must_srv_mgs = 1;
                        break;
-               case 'v':
-                       verbosity++;
+               case 'h':
+                       usage(stdout, argv[0]);
+                       break;
+               case 'k':
+                       krb_enabled = 1;
                        break;
                case 'm':
                        get_creds = 1;
                        must_srv_mds = 1;
                        break;
+               case 'n':
+                       get_creds = 0;
+                       break;
                case 'o':
                        get_creds = 1;
                        must_srv_oss = 1;
                        break;
-               case 'g':
-                       get_creds = 1;
-                       must_srv_mgs = 1;
-                       break;
-               case 'k':
-                       krb_enabled = 1;
-                       break;
-               case 'h':
-                       usage(stdout, argv[0]);
+               case 'R':
+                       realm = optarg;
                        break;
                case 's':
 #ifdef HAVE_OPENSSL_SSK
@@ -247,6 +251,9 @@ main(int argc, char *argv[])
                        usage(stderr, argv[0]);
 #endif
                        break;
+               case 'v':
+                       verbosity++;
+                       break;
                case 'z':
                        null_enabled = 1;
                        break;
@@ -272,21 +279,30 @@ main(int argc, char *argv[])
 
 #endif
        }
+
+       if (realm && !krb_enabled) {
+               fprintf(stderr, "error: need -k option if -R is used\n");
+               usage(stderr, argv[0]);
+       }
+
        initerr(progname, verbosity, fg);
 
        /* For kerberos use gss mechanisms but ignore for sk and null */
        if (krb_enabled) {
+               int ret;
+
                if (gssd_check_mechs()) {
                        printerr(LL_ERR,
                                 "ERROR: problem with gssapi library\n");
                        exit(1);
                }
-               if (gssd_get_local_realm()) {
-                       printerr(LL_ERR,
-                                "ERROR: Can't get Local Kerberos realm\n");
+               ret = gss_get_realm(realm);
+               if (ret) {
+                       printerr(LL_ERR, "ERROR: no Kerberos realm: %s\n",
+                                error_message(ret));
                        exit(1);
                }
-
+               printerr(LL_WARN, "Kerberos realm: %s\n", krb5_this_realm);
                if (get_creds &&
                    gssd_prepare_creds(must_srv_mgs, must_srv_mds,
                                       must_srv_oss)) {
@@ -316,6 +332,7 @@ main(int argc, char *argv[])
 
        svcgssd_run();
        cleanup_mapping();
+       gssd_cleanup_realms();
        printerr(LL_ERR, "svcgssd_run returned!\n");
        abort();
 }