int
 check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
 {
-       char *p = svc_gss_principal(rqstp);
+       char *p = rqstp->rq_cred.cr_principal;
 
        if (rqstp->rq_authop->flavour != RPC_AUTH_GSS)
                return 1;
 
        struct rpc_clnt *client;
 
        if (clp->cl_minorversion == 0) {
-               if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
+               if (!clp->cl_cred.cr_principal &&
+                               (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
                        return -EINVAL;
-               args.client_name = clp->cl_principal;
+               args.client_name = clp->cl_cred.cr_principal;
                args.prognumber = conn->cb_prog,
                args.protocol = XPRT_TRANSPORT_TCP;
                args.authflavor = clp->cl_flavor;
 
                list_del(&ses->se_perclnt);
                nfsd4_put_session_locked(ses);
        }
-       if (clp->cl_cred.cr_group_info)
-               put_group_info(clp->cl_cred.cr_group_info);
-       kfree(clp->cl_principal);
+       free_svc_cred(&clp->cl_cred);
        kfree(clp->cl_name.data);
        kfree(clp);
 }
        target->cl_clientid.cl_id = source->cl_clientid.cl_id; 
 }
 
-static void copy_cred(struct svc_cred *target, struct svc_cred *source)
+static int copy_cred(struct svc_cred *target, struct svc_cred *source)
 {
+       if (source->cr_principal) {
+               target->cr_principal =
+                               kstrdup(source->cr_principal, GFP_KERNEL);
+               if (target->cr_principal == NULL)
+                       return -ENOMEM;
+       } else
+               target->cr_principal = NULL;
        target->cr_uid = source->cr_uid;
        target->cr_gid = source->cr_gid;
        target->cr_group_info = source->cr_group_info;
        get_group_info(target->cr_group_info);
+       return 0;
 }
 
 static int same_name(const char *n1, const char *n2)
 {
        struct nfs4_client *clp;
        struct sockaddr *sa = svc_addr(rqstp);
-       char *princ;
+       int ret;
 
        clp = alloc_client(name);
        if (clp == NULL)
                return NULL;
 
        INIT_LIST_HEAD(&clp->cl_sessions);
-
-       princ = svc_gss_principal(rqstp);
-       if (princ) {
-               clp->cl_principal = kstrdup(princ, GFP_KERNEL);
-               if (clp->cl_principal == NULL) {
-                       spin_lock(&client_lock);
-                       free_client(clp);
-                       spin_unlock(&client_lock);
-                       return NULL;
-               }
+       ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
+       if (ret) {
+               spin_lock(&client_lock);
+               free_client(clp);
+               spin_unlock(&client_lock);
+               return NULL;
        }
-
        idr_init(&clp->cl_stateids);
        memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
        atomic_set(&clp->cl_refcount, 0);
        copy_verf(clp, verf);
        rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
        clp->cl_flavor = rqstp->rq_flavor;
-       copy_cred(&clp->cl_cred, &rqstp->rq_cred);
        gen_confirm(clp);
        clp->cl_cb_session = NULL;
        return clp;
 
        time_t                  cl_time;        /* time of last lease renewal */
        struct sockaddr_storage cl_addr;        /* client ipaddress */
        u32                     cl_flavor;      /* setclientid pseudoflavor */
-       char                    *cl_principal;  /* setclientid principal name */
        struct svc_cred         cl_cred;        /* setclientid principal */
        clientid_t              cl_clientid;    /* generated by server */
        nfs4_verifier           cl_confirm;     /* generated by server */
 
 #include <linux/sunrpc/msg_prot.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/hash.h>
+#include <linux/cred.h>
 
 struct svc_cred {
        uid_t                   cr_uid;
        gid_t                   cr_gid;
        struct group_info       *cr_group_info;
+       char                    *cr_principal; /* for gss */
 };
 
+static inline void free_svc_cred(struct svc_cred *cred)
+{
+       if (cred->cr_group_info)
+               put_group_info(cred->cr_group_info);
+       kfree(cred->cr_principal);
+}
+
 struct svc_rqst;               /* forward decl */
 struct in6_addr;
 
 
 void gss_svc_shutdown_net(struct net *net);
 int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
 u32 svcauth_gss_flavor(struct auth_domain *dom);
-char *svc_gss_principal(struct svc_rqst *);
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
 
        struct svc_cred         cred;
        struct gss_svc_seq_data seqdata;
        struct gss_ctx          *mechctx;
-       char                    *client_name;
 };
 
 static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
        kfree(rsci->handle.data);
        if (rsci->mechctx)
                gss_delete_sec_context(&rsci->mechctx);
-       if (rsci->cred.cr_group_info)
-               put_group_info(rsci->cred.cr_group_info);
-       kfree(rsci->client_name);
+       free_svc_cred(&rsci->cred);
 }
 
 static void rsc_put(struct kref *ref)
        tmp->handle.data = NULL;
        new->mechctx = NULL;
        new->cred.cr_group_info = NULL;
-       new->client_name = NULL;
+       new->cred.cr_principal = NULL;
 }
 
 static void
        spin_lock_init(&new->seqdata.sd_lock);
        new->cred = tmp->cred;
        tmp->cred.cr_group_info = NULL;
-       new->client_name = tmp->client_name;
-       tmp->client_name = NULL;
+       new->cred.cr_principal = tmp->cred.cr_principal;
+       tmp->cred.cr_principal = NULL;
 }
 
 static struct cache_head *
                /* get client name */
                len = qword_get(&mesg, buf, mlen);
                if (len > 0) {
-                       rsci.client_name = kstrdup(buf, GFP_KERNEL);
-                       if (!rsci.client_name)
+                       rsci.cred.cr_principal = kstrdup(buf, GFP_KERNEL);
+                       if (!rsci.cred.cr_principal)
                                goto out;
                }
 
        struct rsc                      *rsci;
 };
 
-char *svc_gss_principal(struct svc_rqst *rqstp)
-{
-       struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data;
-
-       if (gd && gd->rsci)
-               return gd->rsci->client_name;
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(svc_gss_principal);
-
 static int
 svcauth_gss_set_client(struct svc_rqst *rqstp)
 {
 
        struct svc_cred *cred = &rqstp->rq_cred;
 
        cred->cr_group_info = NULL;
+       cred->cr_principal = NULL;
        rqstp->rq_client = NULL;
 
        if (argv->iov_len < 3*4)
        int             len   = argv->iov_len;
 
        cred->cr_group_info = NULL;
+       cred->cr_principal = NULL;
        rqstp->rq_client = NULL;
 
        if ((len -= 3*4) < 0)