#include <linux/mutex.h>
 #include <linux/lockd/bind.h>
 #include <linux/module.h>
+#include <linux/sunrpc/svcauth_gss.h>
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
        shutdown_callback_client(clp);
        if (clp->cl_cred.cr_group_info)
                put_group_info(clp->cl_cred.cr_group_info);
+       kfree(clp->cl_principal);
        kfree(clp->cl_name.data);
        kfree(clp);
 }
        unsigned int            strhashval;
        struct nfs4_client      *conf, *unconf, *new;
        __be32                  status;
+       char                    *princ;
        char                    dname[HEXDIR_LEN];
        
        if (!check_name(clname))
        }
        copy_verf(new, &clverifier);
        new->cl_addr = sin->sin_addr.s_addr;
+       princ = svc_gss_principal(rqstp);
+       if (princ) {
+               new->cl_principal = kstrdup(princ, GFP_KERNEL);
+               if (new->cl_principal == NULL) {
+                       free_client(new);
+                       goto out;
+               }
+       }
        copy_cred(&new->cl_cred, &rqstp->rq_cred);
        gen_confirm(new);
        gen_callback(new, setclid);
 
        nfs4_verifier           cl_verifier;    /* generated by client */
        time_t                  cl_time;        /* time of last lease renewal */
        __be32                  cl_addr;        /* client ipaddress */
+       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 */
 
 void gss_svc_shutdown(void);
 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 cache_head *rsc_table[RSC_HASHMAX];
                gss_delete_sec_context(&rsci->mechctx);
        if (rsci->cred.cr_group_info)
                put_group_info(rsci->cred.cr_group_info);
+       kfree(rsci->client_name);
 }
 
 static void rsc_put(struct kref *ref)
        tmp->handle.data = NULL;
        new->mechctx = NULL;
        new->cred.cr_group_info = NULL;
+       new->client_name = 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;
 }
 
 static struct cache_head *
                status = gss_import_sec_context(buf, len, gm, &rsci.mechctx);
                if (status)
                        goto out;
+
+               /* get client name */
+               len = qword_get(&mesg, buf, mlen);
+               if (len > 0) {
+                       rsci.client_name = kstrdup(buf, GFP_KERNEL);
+                       if (!rsci.client_name)
+                               goto out;
+               }
+
        }
        rsci.h.expiry_time = expiry;
        rscp = rsc_update(&rsci, rscp);
        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;
+}
+
 static int
 svcauth_gss_set_client(struct svc_rqst *rqstp)
 {