diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h
index 294f992491c527d81df434abf3aa20bde3e13599..5eff04c4b25dfe9736dab6e4d25222bf12b7c369 100644
--- a/lustre/include/dt_object.h
+++ b/lustre/include/dt_object.h
@@ -292,7 +292,7 @@ struct dt_object_operations {
         struct obd_capa *(*do_capa_get)(const struct lu_env *env,
                                         struct dt_object *dt,
                                         struct lustre_capa *old,
-                                        __u32 uid, __u64 opc);
+                                        __u64 opc);
 };
 
 /*
diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h
index e8551cbc6d8f5d77b8631ecc77b456c8a8800443..93cd4b8be8df722722bab9c12479a943e7bc47b6 100644
--- a/lustre/include/lustre/lustre_idl.h
+++ b/lustre/include/lustre/lustre_idl.h
@@ -1976,13 +1976,14 @@ typedef enum {
 /* NB take care when changing the sequence of elements this struct,
  * because the offset info is used in find_capa() */
 struct lustre_capa {
-        struct lu_fid   lc_fid;       /* fid */
-        __u64           lc_opc;       /* operations allowed */
-        __u32           lc_uid;       /* uid, this is legacy and for OSS only */
-        __u32           lc_flags;     /* HMAC algorithm & flags */
-        __u32           lc_keyid;     /* key used for the capability */
-        __u32           lc_timeout;   /* capa timeout value (sec) */
-        __u64           lc_expiry;    /* expiry time (sec) */
+        struct lu_fid   lc_fid;     /* fid */
+        __u64           lc_opc;     /* operations allowed */
+        __u32           lc_uid;     /* uid, it is obsolete, but maybe used in
+                                     * future, reserve it for 64-bits aligned.*/
+        __u32           lc_flags;   /* HMAC algorithm & flags */
+        __u32           lc_keyid;   /* key used for the capability */
+        __u32           lc_timeout; /* capa timeout value (sec) */
+        __u64           lc_expiry;  /* expiry time (sec) */
         __u8            lc_hmac[CAPA_HMAC_MAX_LEN];   /* HMAC */
 } __attribute__((packed));
 
diff --git a/lustre/llite/file.c b/lustre/llite/file.c
index cf82da1373ec4a92f81dc975adfafff3ba167cbd..741bbb6201eb4c10129f40cbb08f1529afde4f6e 100644
--- a/lustre/llite/file.c
+++ b/lustre/llite/file.c
@@ -2411,7 +2411,7 @@ int ll_fsync(struct file *file, struct dentry *dentry, int data)
                                            OBD_MD_FLMTIME | OBD_MD_FLCTIME |
                                            OBD_MD_FLGROUP);
 
-                oc = ll_osscapa_get(inode, 0, CAPA_OPC_OSS_WRITE);
+                oc = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
                 err = obd_sync(ll_i2sbi(inode)->ll_dt_exp, oa, lsm,
                                0, OBD_OBJECT_EOF, oc);
                 capa_put(oc);
diff --git a/lustre/llite/llite_capa.c b/lustre/llite/llite_capa.c
index 536644d94705291cdcdb32e2a5a7d2a315ccaf84..c109778854d40f0de08e15d850a04cf08cb9f7bd 100644
--- a/lustre/llite/llite_capa.c
+++ b/lustre/llite/llite_capa.c
@@ -295,16 +295,13 @@ void ll_capa_thread_stop(void)
                    ll_capa_thread.t_flags & SVC_STOPPED);
 }
 
-static struct obd_capa *do_lookup_oss_capa(struct inode *inode, uid_t uid,
-                                           int opc)
+static struct obd_capa *do_lookup_oss_capa(struct inode *inode, int opc)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
         struct obd_capa *ocapa;
 
         /* inside capa_lock */
         list_for_each_entry(ocapa, &lli->lli_oss_capas, u.cli.lli_list) {
-                if (uid != capa_uid(&ocapa->c_capa))
-                        continue;
                 if ((capa_opc(&ocapa->c_capa) & opc) != opc)
                         continue;
 
@@ -319,8 +316,7 @@ static struct obd_capa *do_lookup_oss_capa(struct inode *inode, uid_t uid,
         return NULL;
 }
 
-/* FIXME: once uid is 0, this is mmaped IO, or fsync, truncate. */
-struct obd_capa *ll_osscapa_get(struct inode *inode, uid_t uid, __u64 opc)
+struct obd_capa *ll_osscapa_get(struct inode *inode, __u64 opc)
 {
         struct ll_inode_info *lli = ll_i2info(inode);
         struct obd_capa *ocapa;
@@ -337,8 +333,6 @@ struct obd_capa *ll_osscapa_get(struct inode *inode, uid_t uid, __u64 opc)
         list_for_each_entry(ocapa, &lli->lli_oss_capas, u.cli.lli_list) {
                 if (capa_is_expired(ocapa))
                         continue;
-                if (uid != 0 && uid != capa_uid(&ocapa->c_capa))
-                        continue;
                 if ((opc & CAPA_OPC_OSS_WRITE) &&
                     capa_opc_supported(&ocapa->c_capa, CAPA_OPC_OSS_WRITE)) {
                         found = 1; break;
@@ -452,8 +446,7 @@ static struct obd_capa *do_add_oss_capa(struct inode *inode,
                  inode->i_mode);
 
         /* FIXME: can't replace it so easily with fine-grained opc */
-        old = do_lookup_oss_capa(inode, capa_uid(capa),
-                                 capa_opc(capa) & CAPA_OPC_OSS_ONLY);
+        old = do_lookup_oss_capa(inode, capa_opc(capa) & CAPA_OPC_OSS_ONLY);
         if (!old) {
                 ocapa->u.cli.inode = inode;
                 INIT_LIST_HEAD(&ocapa->u.cli.lli_list);
diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h
index b61b3db64be7029d26804c7c671e1a97f089084e..835ab91fe734d58682772a9a6dea06a2dd3a8a60 100644
--- a/lustre/llite/llite_internal.h
+++ b/lustre/llite/llite_internal.h
@@ -419,8 +419,6 @@ struct ll_async_page {
         struct list_head llap_pglist_item;
         /* checksum for paranoid I/O debugging */
         __u32            llap_checksum;
-        /* uid who operate on this page, used to lookup fid capability only */
-        uid_t            llap_fsuid;
 };
 
 /*
@@ -777,7 +775,7 @@ void ll_capa_open(struct inode *inode);
 void ll_capa_close(struct inode *inode);
 
 struct obd_capa *ll_mdscapa_get(struct inode *inode);
-struct obd_capa *ll_osscapa_get(struct inode *inode, uid_t fsuid, __u64 opc);
+struct obd_capa *ll_osscapa_get(struct inode *inode, __u64 opc);
 
 void ll_truncate_free_capa(struct obd_capa *ocapa);
 void ll_clear_inode_capas(struct inode *inode);
diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c
index 25c4179bbd2e25aee36af8d96ceebfe515957bf5..8587902e19ec97185e279e513c2af93295a5403c 100644
--- a/lustre/llite/rw.c
+++ b/lustre/llite/rw.c
@@ -100,7 +100,7 @@ static int ll_brw(int cmd, struct inode *inode, struct obdo *oa,
         oinfo.oi_md = lsm;
         /* NB partial write, so we might not have CAPA_OPC_OSS_READ capa */
         opc = cmd & OBD_BRW_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_RW;
-        oinfo.oi_capa = ll_osscapa_get(inode, current->fsuid, opc);
+        oinfo.oi_capa = ll_osscapa_get(inode, opc);
         rc = obd_brw(cmd, ll_i2dtexp(inode), &oinfo, 1, &pg, NULL);
         capa_put(oinfo.oi_capa);
         if (rc == 0)
@@ -193,7 +193,7 @@ void ll_truncate(struct inode *inode)
 
         ll_inode_size_unlock(inode, 0);
 
-        oinfo.oi_capa = ll_osscapa_get(inode, 0, CAPA_OPC_OSS_TRUNC);
+        oinfo.oi_capa = ll_osscapa_get(inode, CAPA_OPC_OSS_TRUNC);
         rc = obd_punch_rqset(ll_i2dtexp(inode), &oinfo, NULL);
         ll_truncate_free_capa(oinfo.oi_capa);
         if (rc)
@@ -433,8 +433,7 @@ static struct obd_capa *ll_ap_lookup_capa(void *data, int cmd)
         struct ll_async_page *llap = LLAP_FROM_COOKIE(data);
         int opc = cmd & OBD_BRW_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_RW;
 
-        return ll_osscapa_get(llap->llap_page->mapping->host, llap->llap_fsuid,
-                              opc);
+        return ll_osscapa_get(llap->llap_page->mapping->host, opc);
 }
 
 static struct obd_async_page_ops ll_async_page_ops = {
@@ -1497,8 +1496,6 @@ int ll_readpage(struct file *filp, struct page *page)
         if (IS_ERR(llap))
                 GOTO(out, rc = PTR_ERR(llap));
 
-        llap->llap_fsuid = current->fsuid;
-
         if (ll_i2sbi(inode)->ll_ra_info.ra_max_pages)
                 ras_update(ll_i2sbi(inode), inode, &fd->fd_ras, page->index,
                            llap->llap_defer_uptodate);
diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c
index f972a44e6cbb42a40bbeb89ae8a26932a7a7b6fa..3cfc77d33e543991dee0d92285dd6716182482a9 100644
--- a/lustre/llite/rw26.c
+++ b/lustre/llite/rw26.c
@@ -189,7 +189,7 @@ static ssize_t ll_direct_IO_26_seg(int rw, struct inode *inode,
                                     LPROC_LL_DIRECT_READ, size);
                 opc = CAPA_OPC_OSS_RW;
         }
-        ocapa = ll_osscapa_get(inode, current->fsuid, opc);
+        ocapa = ll_osscapa_get(inode, opc);
         rc = obd_brw_rqset(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ,
                            ll_i2dtexp(inode), &oa, lsm, page_count, pga, NULL,
                            ocapa);
diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h
index 8e2f8d3beb816ded43ddae4961f3a2f09cbd3399..3cbe6d0c8fec7666e5ff5e13a226721681180dfe 100644
--- a/lustre/mdd/mdd_internal.h
+++ b/lustre/mdd/mdd_internal.h
@@ -565,11 +565,11 @@ int mdo_create_obj(const struct lu_env *env, struct mdd_object *o,
 static inline struct obd_capa *mdo_capa_get(const struct lu_env *env,
                                             struct mdd_object *obj, 
                                             struct lustre_capa *old,
-                                            __u32 uid, __u64 opc)
+                                            __u64 opc)
 {
         struct dt_object *next = mdd_object_child(obj);
         LASSERT(mdd_object_exists(obj));
-        return next->do_ops->do_capa_get(env, next, old, uid, opc);
+        return next->do_ops->do_capa_get(env, next, old, opc);
 }
 
 #endif
diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c
index eef4fa54f8682572e7c0ca6570a2610ce0a18f41..98e9018bcd9773b0b6d8ba8519cadfbac63cf356 100644
--- a/lustre/mdd/mdd_lov.c
+++ b/lustre/mdd/mdd_lov.c
@@ -518,7 +518,7 @@ int mdd_lov_create(const struct lu_env *env, struct mdd_device *mdd,
                 oa->o_valid |= OBD_MD_FLFID | OBD_MD_FLGENER;
                 oinfo->oi_oa = oa;
                 oinfo->oi_md = lsm;
-                oinfo->oi_capa = mdo_capa_get(env, child, NULL, 0,
+                oinfo->oi_capa = mdo_capa_get(env, child, NULL,
                                               CAPA_OPC_MDS_DEFAULT);
                 if (IS_ERR(oinfo->oi_capa))
                         oinfo->oi_capa = NULL;
@@ -712,7 +712,7 @@ int mdd_lov_setattr_async(const struct lu_env *env, struct mdd_object *obj,
         if (rc)
                 RETURN(rc);
 
-        oc = mdo_capa_get(env, obj, NULL, 0, CAPA_OPC_MDS_DEFAULT);
+        oc = mdo_capa_get(env, obj, NULL, CAPA_OPC_MDS_DEFAULT);
         if (IS_ERR(oc))
                 oc = NULL;
 
diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c
index 1195593afc785b829f2eaf4805d9cdfdc06905b8..a6357f062b94d3df058395f77bd12817ddb09c1f 100644
--- a/lustre/mdd/mdd_permission.c
+++ b/lustre/mdd/mdd_permission.c
@@ -641,7 +641,7 @@ int mdd_capa_get(const struct lu_env *env, struct md_object *obj,
         int rc = 0;
         ENTRY;
 
-        oc = mdo_capa_get(env, mdd_obj, renewal ? capa : NULL, capa->lc_uid,
+        oc = mdo_capa_get(env, mdd_obj, renewal ? capa : NULL,
                           capa->lc_opc);
         if (IS_ERR(oc)) {
                 rc = PTR_ERR(oc);
diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c
index 856c7c7459a7c18305d8604c0bd85892104c67fd..9fe52e2774ca613e6fe8d3f32001809d00f80258 100644
--- a/lustre/mdt/mdt_lib.c
+++ b/lustre/mdt/mdt_lib.c
@@ -597,10 +597,20 @@ void mdt_shrink_reply(struct mdt_thread_info *info)
                 adjust += req_capsule_shrink(pill, &RMF_LOGCOOKIES,
                                             acl_size, adjust, 1);
 
-        if ((req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER) &&
-               !(body->valid & OBD_MD_FLMDSCAPA)))
-                adjust += req_capsule_shrink(pill, &RMF_CAPA1, 0, adjust, 1);
+        /* RMF_CAPA1 on server-side maybe for OBD_MD_FLMDSCAPA or
+         * OBD_MD_FLOSSCAPA. If RMF_CAPA2 exist also, RMF_CAPA1 is
+         * for OBD_MD_FLMDSCAPA only. */
+        if (req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER)) {
+                if ((req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
+                    !(body->valid & OBD_MD_FLMDSCAPA)) ||
+                    (!req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
+                    !(body->valid & OBD_MD_FLMDSCAPA) &&
+                    !(body->valid & OBD_MD_FLOSSCAPA)))
+                        adjust += req_capsule_shrink(pill, &RMF_CAPA1,
+                                                     0, adjust, 1);
+        }
 
+        /* RMF_CAPA2 on server-side is for OBD_MD_FLOSSCAPA only. */
         if ((req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
                 !(body->valid & OBD_MD_FLOSSCAPA)))
                 adjust += req_capsule_shrink(pill, &RMF_CAPA2, 0, adjust, 0);
diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c
index e83eede51da0c0fdb59ba6eac03467546e2f8734..0507d97cb397065fbf33d477e87fc4158eb3482b 100644
--- a/lustre/mdt/mdt_open.c
+++ b/lustre/mdt/mdt_open.c
@@ -566,12 +566,11 @@ static int mdt_finish_open(struct mdt_thread_info *info,
         if (mdt->mdt_opts.mo_oss_capa &&
             S_ISREG(lu_object_attr(&o->mot_obj.mo_lu))) {
                 struct lustre_capa *capa;
-                struct md_ucred *ucred = mdt_ucred(info);
 
                 capa = req_capsule_server_get(&info->mti_pill, &RMF_CAPA2);
                 LASSERT(capa);
                 capa->lc_opc = CAPA_OPC_OSS_DEFAULT | capa_open_opc(flags);
-                capa->lc_uid = ucred->mu_o_fsuid;
+                capa->lc_uid = 0;
                 rc = mo_capa_get(info->mti_env, mdt_object_child(o), capa, 0);
                 if (rc)
                         RETURN(rc);
diff --git a/lustre/obdfilter/filter_capa.c b/lustre/obdfilter/filter_capa.c
index 83ccbed05d899d789e0082071cec833fee85947e..c7d3ea29fb89e1907b79a049fcbcbbbcecb8b0f0 100644
--- a/lustre/obdfilter/filter_capa.c
+++ b/lustre/obdfilter/filter_capa.c
@@ -34,93 +34,6 @@
 
 #include "filter_internal.h"
 
-/*
- * FIXME
- * keep this as simple as possible. we suppose the blacklist usually
- * be empry or very short (<5), since long term blacklist should be
- * done on MDS side. A more sophisticated blacklist will be implemented
- * later.
- *
- * note blacklist didn't take effect when OSS capability disabled. this
- * looks reasonable to me.
- */
-#define BLACKLIST_MAX   (32)
-static int nblacklist = 0;
-static uid_t blacklist[BLACKLIST_MAX];
-static spinlock_t blacklist_lock = SPIN_LOCK_UNLOCKED;
-
-int blacklist_display(char *buf, int bufsize)
-{
-        char one[16];
-        int i;
-        LASSERT(buf);
-
-        buf[0] = '\0';
-        spin_lock(&blacklist_lock);
-        for (i = 0; i < nblacklist; i++) {
-                snprintf(one, 16, "%u\n", blacklist[i]);
-                strncat(buf, one, bufsize);
-        }
-        spin_unlock(&blacklist_lock);
-        return strnlen(buf, bufsize);
-}
-
-void blacklist_add(uid_t uid)
-{
-        int i;
-
-        spin_lock(&blacklist_lock);
-        if (nblacklist == BLACKLIST_MAX) {
-                CERROR("can't add more in blacklist\n");
-                spin_unlock(&blacklist_lock);
-                return;
-        }
-
-        for (i = 0; i < nblacklist; i++) {
-                if (blacklist[i] == uid) {
-                        spin_unlock(&blacklist_lock);
-                        return;
-                }
-        }
-
-        blacklist[nblacklist++] = uid;
-        spin_unlock(&blacklist_lock);
-}
-
-void blacklist_del(uid_t uid)
-{
-        int i;
-
-        spin_lock(&blacklist_lock);
-        for (i = 0; i < nblacklist; i++) {
-                if (blacklist[i] == uid) {
-                        nblacklist--;
-                        while (i < nblacklist) {
-                                blacklist[i] = blacklist[i+1];
-                                i++;
-                        }
-                        spin_unlock(&blacklist_lock);
-                        return;
-                }
-        }
-        spin_unlock(&blacklist_lock);
-}
-
-static int blacklist_check(uid_t uid)
-{
-        int i, rc = 0;
-
-        spin_lock(&blacklist_lock);
-        for (i = 0; i < nblacklist; i++) {
-                if (blacklist[i] == uid) {
-                        rc = 1;
-                        break;
-                }
-        }
-        spin_unlock(&blacklist_lock);
-        return rc;
-}
-
 static inline __u32 filter_ck_keyid(struct filter_capa_key *key)
 {
         return key->k_key.lk_keyid;
@@ -210,12 +123,6 @@ int filter_auth_capa(struct obd_export *exp, struct lu_fid *fid, __u64 mdsid,
                 RETURN(-EACCES);
         }
 
-        if (blacklist_check(capa->lc_uid)) {
-                DEBUG_CAPA(D_ERROR, capa, "uid %u found in blacklist,",
-                           capa->lc_uid);
-                RETURN(-EACCES);
-        }
-
 #warning "enable fid check in filter_auth_capa() when fid stored in OSS object"
 
         if (opc == CAPA_OPC_OSS_READ) {
diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c
index 123c1ed304971ad6d0b9d603d66cb2d875cb9838..9f9c953f1640bc7802e565df638e37ea6ad5d6a7 100644
--- a/lustre/obdfilter/lproc_obdfilter.c
+++ b/lustre/obdfilter/lproc_obdfilter.c
@@ -231,41 +231,6 @@ static int lprocfs_filter_rd_capa_count(char *page, char **start, off_t off,
                         capa_count[CAPA_SITE_SERVER]);
 }
 
-static
-int lprocfs_filter_rd_blacklist(char *page, char **start, off_t off, int count,
-                                int *eof, void *data)
-{
-        int rc;
-
-        rc = blacklist_display(page, count);
-        *eof = 1;
-        return rc;
-}
-
-static
-int lprocfs_filter_wr_blacklist(struct file *file, const char *buffer,
-                                unsigned long count, void *data)
-{
-        int add;
-        uid_t uid = -1;
-
-        if (count < 2)
-                return count;
-        if (buffer[0] == '+')
-                add = 1;
-        else if (buffer[0] == '-')
-                add = 0;
-        else
-                return count;
-
-        sscanf(buffer + 1, "%u", &uid);
-        if (add)
-                blacklist_add(uid);
-        else
-                blacklist_del(uid);
-        return count;
-}
-
 static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "uuid",         lprocfs_rd_uuid,          0, 0 },
         { "blocksize",    lprocfs_rd_blksize,       0, 0 },
@@ -302,8 +267,6 @@ static struct lprocfs_vars lprocfs_obd_vars[] = {
         { "capa",         lprocfs_filter_rd_capa,
                           lprocfs_filter_wr_capa, 0 },
         { "capa_count",   lprocfs_filter_rd_capa_count, 0, 0 },
-        { "blacklist",    lprocfs_filter_rd_blacklist,
-                          lprocfs_filter_wr_blacklist, 0 },
         { 0 }
 };
 
diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c
index 37efb19836cfc67d90ab82ae1c3d3c1b73e9f14d..ea283e220d27f7fadb172e312d4a0cdc6671c5b1 100644
--- a/lustre/osd/osd_handler.c
+++ b/lustre/osd/osd_handler.c
@@ -1492,7 +1492,7 @@ static int osd_xattr_del(const struct lu_env *env,
 static struct obd_capa *osd_capa_get(const struct lu_env *env,
                                      struct dt_object *dt,
                                      struct lustre_capa *old,
-                                     __u32 uid, __u64 opc)
+                                     __u64 opc)
 {
         struct osd_thread_info *info = osd_oti_get(env);
         const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
@@ -1516,7 +1516,7 @@ static struct obd_capa *osd_capa_get(const struct lu_env *env,
 
         capa->lc_fid = *fid;
         capa->lc_opc = opc;
-        capa->lc_uid = uid;
+        capa->lc_uid = 0;
         capa->lc_flags = dev->od_capa_alg << 24;
         capa->lc_timeout = dev->od_capa_timeout;
         capa->lc_expiry = 0;
diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am
index 234c50cca992d642418444dba73bc638d0a5be0e..780f37edd91473c7bcdf86bc27444bc42a50f782 100644
--- a/lustre/tests/Makefile.am
+++ b/lustre/tests/Makefile.am
@@ -34,7 +34,7 @@ noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify cmknod
 noinst_PROGRAMS += ll_sparseness_write mrename ll_dirstripe_verify mkdirmany rmdirmany
 noinst_PROGRAMS += openfilleddirunlink rename_many memhog iopentest1 iopentest2
 noinst_PROGRAMS += mmap_sanity flock_test writemany random-reads flocks_test
-noinst_PROGRAMS += ll_getstripe_info
+noinst_PROGRAMS += ll_getstripe_info write_time_limit
 if MPITESTS
 noinst_PROGRAMS += parallel_grouplock write_append_truncate createmany_mpi
 noinst_PROGRAMS += iam_ut
diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh
index b2f195051f9369390990312cbb2739fd165dba1b..d68531d5b243c417aa992b4d49534acae95ed684 100644
--- a/lustre/tests/sanity-sec.sh
+++ b/lustre/tests/sanity-sec.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 #
 # Run select tests by setting SEC_ONLY, or as arguments to the script.
-# Skip specific tests by setting EXCEPT.
+# Skip specific tests by setting SEC_EXCEPT.
 #
 
 set -e
@@ -10,28 +10,35 @@ SRCDIR=`dirname $0`
 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
 
 SEC_ONLY=${SEC_ONLY:-"$*"}
-ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-""}
-# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
-
-[ "$ALWAYS_EXCEPT$EXCEPT" ] && \
-	echo "Skipping tests: `echo $ALWAYS_EXCEPT $EXCEPT`"
+[ "$SEC_EXCEPT" ] && echo "Skipping tests: `echo $SEC_EXCEPT`"
 
 TMP=${TMP:-/tmp}
 LFS=${LFS:-lfs}
 LCTL=${LCTL:-lctl}
 RUNAS=${RUNAS:-runas}
+WTL=${WTL:-write_time_limit}
 
-log() {
+LPROC=/proc/fs/lustre
+ENABLE_IDENTITY=/usr/sbin/l_getidentity
+DISABLE_IDENTITY=NONE
+LUSTRE_CONF_DIR=/etc/lustre
+PERM_CONF=$LUSTRE_CONF_DIR/perm.conf
+LDLM_LPROC=$LPROC/ldlm
+LLITE_LPROC=$LPROC/llite
+MDC_LPROC=$LPROC/mdc
+MDT_LPROC=$LPROC/mdt
+OST_LPROC=$LPROC/obdfilter
+
+sec_log() {
 	echo "$*"
 	$LCTL mark "$*" 2> /dev/null || true
 }
 
 SANITYSECLOG=${SANITYSECLOG:-/tmp/sanity-sec.log}
-
 [ "$SANITYSECLOG" ] && rm -f $SANITYSECLOG || true
 
 sec_error() { 
-	log "FAIL: $TESTNAME $@"
+	sec_log "FAIL: $TESTNAME $@"
 	if [ "$SANITYSECLOG" ]; then
 		echo "FAIL: $TESTNAME $@" >> $SANITYSECLOG
 	else
@@ -39,23 +46,28 @@ sec_error() {
 	fi
 }
 
-pass() { 
+sec_pass() { 
 	echo PASS $@
 }
 
+sec_skip () {
+	sec_log "$0: SKIP: $TESTNAME $@"
+	[ "$SANITYSECLOG" ] && echo "$0: SKIP: $TESTNAME $@" >> $SANITYSECLOG
+}
+
 ID1=500
 ID2=501
 
 USER1=`cat /etc/passwd|grep :$ID1:$ID1:|cut -d: -f1`
 USER2=`cat /etc/passwd|grep :$ID2:$ID2:|cut -d: -f1`
 
-if [ ! "$USER1" ]; then
+if [ -z "$USER1" ]; then
 	echo "===== Please add user1 (uid=$ID1 gid=$ID1)! Skip sanity-sec ====="
 	sec_error "===== Please add user1 (uid=$ID1 gid=$ID1)! ====="
 	exit 0
 fi
 
-if [ ! "$USER2" ]; then
+if [ -z "$USER2" ]; then
 	echo "===== Please add user2 (uid=$ID2 gid=$ID2)! Skip sanity-sec ====="
 	sec_error "===== Please add user2 (uid=$ID2 gid=$ID2)! ====="
 	exit 0
@@ -68,26 +80,88 @@ LUSTRE=${LUSTRE:-`dirname $0`/..}
 init_test_env $@
 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
 
-if $GSS_KRB5; then
-    $RUNAS -u $ID1 krb5_login.sh || exit 1
-    $RUNAS -u $ID2 krb5_login.sh || exit 1
+mounted_lustre_filesystems() {
+	awk '($3 ~ "lustre" && $1 ~ ":") { print $2 }' /proc/mounts
+}
+
+MOUNTED="`mounted_lustre_filesystems`"
+if [ -z "$MOUNTED" ]; then
+        formatall
+        setupall
+	MOUNTED="`mounted_lustre_filesystems`"
+	[ -z "$MOUNTED" ] && sec_error "NAME=$NAME not mounted"
+	S_MOUNTED=yes
 fi
 
+[ `echo $MOUNT | wc -w` -gt 1 ] && sec_error "NAME=$NAME mounted more than once"
+
+DIR=${DIR:-$MOUNT}
+[ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && \
+	sec_cleanup && exit 99
+
+[ `ls -l $LDLM_LPROC/namespaces 2>/dev/null | grep *-mdc-* | wc -l` -gt 1 ] \
+	&& echo "skip multi-MDS test" && sec_cleanup && exit 0
+
+OST_COUNT=$(ls -l $LDLM_LPROC/namespaces 2>/dev/null | grep osc | grep -v MDT | wc -l)
+
+# for GSS_SUP
+GSS_REF=$(lsmod | grep ^ptlrpc_gss | awk '{print $3}')
+if [ ! -z "$GSS_REF" -a "$GSS_REF" != "0" ]; then
+	GSS_SUP=1
+	echo "with GSS support"
+else
+	GSS_SUP=0
+	echo "without GSS support"
+fi
+
+# for MDT_TYPE
+MDT_REF=$(lsmod | grep ^mdt | awk '{print $3}')
+if [ ! -z "$MDT_REF" -a "$MDT_REF" != "0" ]; then
+        MDT_TYPE="local"
+        echo "local mdt"
+else
+        MDT_TYPE="remote"
+        echo "remote mdt"
+fi
+
+MDT="`do_facet $SINGLEMDS ls -l $MDT_LPROC/ | grep MDT | awk '{print $9}'`"
+if [ ! -z "$MDT" ]; then
+	IDENTITY_UPCALL=$MDT_LPROC/$MDT/identity_upcall
+	IDENTITY_UPCALL_BAK="`more $IDENTITY_UPCALL`"
+	IDENTITY_FLUSH=$MDT_LPROC/$MDT/identity_flush
+	ROOTSQUASH_UID=$MDT_LPROC/$MDT/rootsquash_uid
+	ROOTSQUASH_GID=$MDT_LPROC/$MDT/rootsquash_gid
+	NOSQUASH_NIDS=$MDT_LPROC/$MDT/nosquash_nids
+	MDSCAPA=$MDT_LPROC/$MDT/capa
+	CAPA_TIMEOUT=$MDT_LPROC/$MDT/capa_timeout
+fi
+
+# for CLIENT_TYPE
+if [ -z "$(grep remote $LLITE_LPROC/*/client_type 2>/dev/null)" ]; then
+	CLIENT_TYPE="local"
+	echo "local client"
+else
+	CLIENT_TYPE="remote"
+	echo "remote client"
+fi
+
+SAVE_PWD=$PWD
+
 sec_run_one() {
 	BEFORE=`date +%s`
-	log "== test $1 $2= `date +%H:%M:%S` ($BEFORE)"
+	sec_log "== test $1 $2= `date +%H:%M:%S` ($BEFORE)"
 	export TESTNAME=test_$1
 	test_$1 || sec_error "exit with rc=$?"
 	unset TESTNAME
-	pass "($((`date +%s` - $BEFORE))s)"
+	sec_pass "($((`date +%s` - $BEFORE))s)"
 }
 
 build_test_filter() {
         for O in $SEC_ONLY; do
             eval SEC_ONLY_${O}=true
         done
-        for E in $EXCEPT $ALWAYS_EXCEPT; do
-            eval EXCEPT_${E}=true
+        for E in $SEC_EXCEPT; do
+            eval SEC_EXCEPT_${E}=true
         done
 }
 
@@ -115,12 +189,12 @@ sec_run_test() {
                  echo -n "."
                  return 0
  	fi
-        testname=EXCEPT_$1
+        testname=SEC_EXCEPT_$1
         if [ ${!testname}x != x ]; then
                  echo "skipping excluded test $1"
                  return 0
         fi
-        testname=EXCEPT_$base
+        testname=SEC_EXCEPT_$base
         if [ ${!testname}x != x ]; then
                  echo "skipping excluded test $1 (base $base)"
                  return 0
@@ -129,75 +203,40 @@ sec_run_test() {
  	return $?
 }
 
-mounted_lustre_filesystems() {
-	awk '($3 ~ "lustre" && $1 ~ ":") { print $2 }' /proc/mounts
-}
-
-MOUNTED="`mounted_lustre_filesystems`"
-if [ -z "$MOUNTED" ]; then
-        formatall
-        setupall
-	MOUNTED="`mounted_lustre_filesystems`"
-	[ -z "$MOUNTED" ] && sec_error "NAME=$NAME not mounted"
-	S_MOUNTED=yes
-fi
-
-[ `echo $MOUNT | wc -w` -gt 1 ] && sec_error "NAME=$NAME mounted more than once"
-
-DIR=${DIR:-$MOUNT}
-[ -z "`echo $DIR | grep $MOUNT`" ] && echo "$DIR not in $MOUNT" && \
-	sec_cleanup && exit 99
-
-[ `ls -l $LPROC/ldlm 2> /dev/null | grep lustre-MDT | wc -l` -gt 1 ] \
-	&& echo "skip multi-MDS test" && sec_cleanup && exit 0
+build_test_filter
 
-if [ -z "`lsmod | grep mdt`" ]; then
-	LOCAL_MDT=0
-	echo "remote mdt"
-	EXCEPT="$EXCEPT 1 3"
-else
-	LOCAL_MDT=1
-	echo "local mdt"
-	EXCEPT="$EXCEPT 1 2 3"
-fi
+sec_login() {
+	local user=$1
+	local group=$2
 
-LPROC=/proc/fs/lustre
-ENABLE_IDENTITY=/usr/sbin/l_getidentity
-DISABLE_IDENTITY=NONE
-LUSTRE_CONF_DIR=/etc/lustre
-SETXID_CONF=$LUSTRE_CONF_DIR/setxid.conf
-SETXID_CONF_BAK=$LUSTRE_CONF_DIR/setxid.conf.bak
-
-if [ $LOCAL_MDT -eq 1 ]; then
-	MDT=$(\ls $LPROC/mdt 2> /dev/null | grep -v num_refs | tail -n 1)
-	IDENTITY_UPCALL=$LPROC/mdt/$MDT/identity_upcall
-	IDENTITY_UPCALL_BAK=`more $IDENTITY_UPCALL`
-	IDENTITY_FLUSH=$LPROC/mdt/$MDT/identity_flush
-	ROOTSQUASH_UID=$LPROC/mdt/$MDT/rootsquash_uid
-	ROOTSQUASH_GID=$LPROC/mdt/$MDT/rootsquash_gid
-	NOSQUASH_NIDS=$LPROC/mdt/$MDT/nosquash_nids
-fi
-
-CLIENT_TYPE=$LPROC/llite/*/client_type
-grep "local client" $CLIENT_TYPE > /dev/null 2>&1 && EXCEPT="$EXCEPT 2"
-grep "remote client" $CLIENT_TYPE > /dev/null 2>&1 && EXCEPT="$EXCEPT 1 3"
+	if ! $RUNAS -u $user krb5_login.sh; then
+		echo "$user login kerberos failed."
+		exit 1
+	fi
 
-build_test_filter
+	if ! $RUNAS -u $user -g $group ls $DIR > /dev/null; then
+		$RUNAS -u $user lfs flushctx -k
+		$RUNAS -u $user krb5_login.sh
+                if ! $RUNAS -u $user -g $group ls $DIR > /dev/null; then
+                        echo "init $user $group failed."
+                        exit 2
+                fi
+	fi
+}
 
 setup() {
-	if [ -f "$SETXID_CONF" ]; then
-		mv -f $SETXID_CONF $SETXID_CONF_BAK
-	else
-		rm -f $SETXID_CONF_BAK
+	if [ ! -z "$MDT" ]; then
+		do_facet $SINGLEMDS echo $ENABLE_IDENTITY > $IDENTITY_UPCALL
+		do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
 	fi
 
-	if [ $LOCAL_MDT -eq 1 ]; then
-		echo $ENABLE_IDENTITY > $IDENTITY_UPCALL
-		echo -1 > $IDENTITY_FLUSH
+	if ! $RUNAS -u $ID1 ls $DIR > /dev/null 2>&1; then
+		sec_login $USER1 $USER1
 	fi
 
-	$RUNAS -u $ID1 ls $DIR
-	$RUNAS -u $ID2 ls $DIR
+	if ! $RUNAS -u $ID2 ls $DIR > /dev/null 2>&1; then
+		sec_login $USER2 $USER2
+	fi
 }
 setup
 
@@ -225,34 +264,51 @@ sec_run_test 0 "uid permission ============================="
 
 # setuid/gid
 test_1() {
+	[ $GSS_SUP = 0 ] && sec_skip "without GSS support." && return
+	[ -z "$MDT" ] && sec_skip "do not support do_facet operations." && return
+
+	do_facet $SINGLEMDS rm -f $PERM_CONF
+	do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
+
 	rm -rf $DIR/d1
 	mkdir $DIR/d1
 
 	chown $USER1 $DIR/d1 || sec_error
 	$RUNAS -u $ID2 -v $ID1 touch $DIR/d1/f0 && sec_error
-	echo "* $ID2 setuid" > $SETXID_CONF
+	do_facet $SINGLEMDS echo "\* $ID2 setuid" > $PERM_CONF
 	echo "enable uid $ID2 setuid"
-	echo -1 > $IDENTITY_FLUSH
+	do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
 	$RUNAS -u $ID2 -v $ID1 touch $DIR/d1/f1 || sec_error
 
 	chown root $DIR/d1
 	chgrp $USER1 $DIR/d1
 	chmod 770 $DIR/d1
 	$RUNAS -u $ID2 -g $ID2 touch $DIR/d1/f2 && sec_error
-	echo "* $ID2 setuid,setgid" > $SETXID_CONF
+	$RUNAS -u $ID2 -g $ID2 -j $ID1 touch $DIR/d1/f3 && sec_error
+	do_facet $SINGLEMDS echo "\* $ID2 setuid,setgid" > $PERM_CONF
 	echo "enable uid $ID2 setuid,setgid"
-	echo -1 > $IDENTITY_FLUSH
-	$RUNAS -u $ID2 -g $ID2 -j $ID1 touch $DIR/d1/f3 || sec_error
-	$RUNAS -u $ID2 -v $ID1 -g $ID2 -j $ID1 touch $DIR/d1/f4 || sec_error
+	do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
+	$RUNAS -u $ID2 -g $ID2 -j $ID1 touch $DIR/d1/f4 || sec_error
+	$RUNAS -u $ID2 -v $ID1 -g $ID2 -j $ID1 touch $DIR/d1/f5 || sec_error
 
-	rm -f $SETXID_CONF
 	rm -rf $DIR/d1
-	echo -1 > $IDENTITY_FLUSH
+
+	do_facet $SINGLEMDS rm -f $PERM_CONF
+	do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
 }
 sec_run_test 1 "setuid/gid ============================="
 
-# lfs getfacl/setfacl
-test_2() {
+# remote_acl
+# for remote client only
+test_2 () {
+	[ "$CLIENT_TYPE" = "local" ] && \
+		sec_skip "remote_acl for remote client only" && return
+    	[ -z "$(grep ^acl $MDC_LPROC/*-mdc-*/connect_flags)" ] && \
+		sec_skip "must have acl enabled" && return
+    	[ -z "$(which setfacl 2>/dev/null)" ] && \
+		sec_skip "could not find setfacl" && return
+	[ "$UID" != 0 ] && sec_skip "must run as root" && return
+
 	rm -rf $DIR/d2
 	mkdir $DIR/d2
 	chmod 755 $DIR/d2
@@ -265,93 +321,237 @@ test_2() {
 
 	$LFS setfacl -m u:$USER1:w $DIR/d2/f0 || sec_error
 	$LFS getfacl $DIR/d2/f0 || sec_error
-	echo "set user $USER1 write permission on file $DIR/d2/fo"
+	echo "set user $USER1 write permission on file $DIR/d2/f0"
 	$RUNAS -u $ID1 touch $DIR/d2/f0 || sec_error
 	$RUNAS -u $ID1 cat $DIR/d2/f0 && sec_error
 
 	rm -rf $DIR/d2
 }
-sec_run_test 2 "lfs getfacl/setfacl ============================="
+sec_run_test 2 "rmtacl ============================="
 
 # rootsquash
+# for remote mdt only
 test_3() {
-	$LCTL conf_param $MDT.mdt.nosquash_nids=none
-	while grep LNET_NID_ANY $NOSQUASH_NIDS > /dev/null; do sleep 1; done
-	$LCTL conf_param $MDT.mdt.rootsquash_uid=0
-	while [ "`cat $ROOTSQUASH_UID`" -ne 0 ]; do sleep 1; done
-	$LCTL conf_param $MDT.mdt.rootsquash_gid=0
-	while [ "`cat $ROOTSQUASH_GID`" -ne 0 ]; do sleep 1; done
+	[ $GSS_SUP = 0 ] && sec_skip "without GSS support." && return
+	[ -z "$MDT" ] && sec_skip "do not support do_facet operations." && return
+        [ "$MDT_TYPE" = "local" ] && sec_skip "rootsquash for remote mdt only" && return
+
+	do_facet $SINGLEMDS echo "-\*" > $NOSQUASH_NIDS 
+	do_facet $SINGLEMDS echo 0 > $ROOTSQUASH_UID
+	do_facet $SINGLEMDS echo 0 > $ROOTSQUASH_GID
 
 	rm -rf $DIR/d3
 	mkdir $DIR/d3
 	chown $USER1 $DIR/d3
 	chmod 700 $DIR/d3
-	$LCTL conf_param $MDT.mdt.rootsquash_uid=$ID1
+	do_facet $SINGLEMDS echo $ID1 > $ROOTSQUASH_UID
 	echo "set rootsquash uid = $ID1"
-	while [ "`cat $ROOTSQUASH_UID`" -ne $ID1 ]; do sleep 1; done
 	touch $DIR/f3_0 && sec_error
 	touch $DIR/d3/f3_1 || sec_error
 
-	$LCTL conf_param $MDT.mdt.rootsquash_uid=0
+	do_facet $SINGLEMDS echo 0 > $ROOTSQUASH_UID
 	echo "disable rootsquash"
-	while [ "`cat $ROOTSQUASH_UID`" -ne 0 ]; do sleep 1; done
 	chown root $DIR/d3
 	chgrp $USER2 $DIR/d3
 	chmod 770 $DIR/d3
 
-	$LCTL conf_param $MDT.mdt.rootsquash_uid=$ID1
+	do_facet $SINGLEMDS echo $ID1 > $ROOTSQUASH_UID
 	echo "set rootsquash uid = $ID1"
-	while [ "`cat $ROOTSQUASH_UID`" -ne $ID1 ]; do sleep 1; done
 	touch $DIR/d3/f3_2 && sec_error
-	$LCTL conf_param $MDT.mdt.rootsquash_gid=$ID2
+	do_facet $SINGLEMDS echo $ID2 > $ROOTSQUASH_GID
 	echo "set rootsquash gid = $ID2"
-	while [ "`cat $ROOTSQUASH_GID`" -ne $ID2 ]; do sleep 1; done
 	touch $DIR/d3/f3_3 || sec_error
 
-	$LCTL conf_param $MDT.mdt.nosquash_nids=*
+	do_facet $SINGLEMDS echo "+\*" > $NOSQUASH_NIDS
 	echo "add host in rootsquash skip list"
-	while ! grep LNET_NID_ANY $NOSQUASH_NIDS > /dev/null;
-		do sleep 1;
-	done
 	touch $DIR/f3_4 || sec_error
 
-	$LCTL conf_param $MDT.mdt.rootsquash_uid=0
-	while [ "`cat $ROOTSQUASH_UID`" -ne 0 ]; do sleep 1; done
-	$LCTL conf_param $MDT.mdt.rootsquash_gid=0
-	while [ "`cat $ROOTSQUASH_GID`" -ne 0 ]; do sleep 1; done
-	$LCTL conf_param $MDT.mdt.nosquash_nids=none
+	do_facet $SINGLEMDS echo 0 > $ROOTSQUASH_UID
+	do_facet $SINGLEMDS echo 0 > $ROOTSQUASH_GID
+	do_facet $SINGLEMDS echo "-\*" > $NOSQUASH_NIDS
 	rm -rf $DIR/d3
 	rm -f $DIR/f3_?
 }
 sec_run_test 3 "rootsquash ============================="
 
-# bug 3285 - supplementary group should always succeed (see do_init_ucred),
-# NB: the supplementary groups are set for local client only, as for remote
-# client, the groups of the specified uid on MDT will be obtained by
-# upcall /sbin/l_getidentity and used.
+# bug 3285 - supplementary group should always succeed.
+# NB: the supplementary groups are set for local client only,
+# as for remote client, the groups of the specified uid on MDT
+# will be obtained by upcall /sbin/l_getidentity and used.
 test_4() {
+	rm -rf $DIR/d4
         mkdir $DIR/d4
         chmod 771 $DIR/d4
         chgrp $ID1 $DIR/d4
 	$RUNAS -u $ID1 ls $DIR/d4 || sec_error "setgroups(1) failed"
-	grep "local client" $CLIENT_TYPE > /dev/null 2>&1 && \
-		($RUNAS -u $ID2 -G1,2,$ID1 ls $DIR/d4 || \
-			sec_error "setgroups(2) failed")
+	if [ "$CLIENT_TYPE" != "remote" ]; then
+		if [ ! -z "$MDT" ]; then
+			do_facet $SINGLEMDS echo "\* $ID2 setgrp" > $PERM_CONF
+			do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
+		fi
+		$RUNAS -u $ID2 -G1,2,$ID1 ls $DIR/d4 || sec_error "setgroups(2) failed"
+		if [ ! -z "$MDT" ]; then
+			do_facet $SINGLEMDS rm -f $PERM_CONF
+			do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
+		fi
+	fi
 	$RUNAS -u $ID2 -G1,2 ls $DIR/d4 && sec_error "setgroups(3) failed"
 	rm -rf $DIR/d4
 }
 sec_run_test 4 "set supplementary group ==============="
 
-log "cleanup: ======================================================"
+mds_capability_timeout() {
+        [ $# -lt 1 ] && echo "Miss mds capability timeout value" && return 1
 
-unsetup() {
-	if [ -f "$SETXID_CONF_BAK" ]; then
-		mv -f $SETXID_CONF_BAK $SETXID_CONF
+        echo "Set mds capability timeout as $1 seconds"
+	do_facet $SINGLEMDS echo $1 > $CAPA_TIMEOUT
+        return 0
+}
+
+mds_capability_switch() {
+        [ $# -lt 1 ] && echo "Miss mds capability switch value" && return 1
+
+        case $1 in
+                0) echo "Turn off mds capability";;
+                3) echo "Turn on mds capability";;
+                *) echo "Invalid mds capability switch value" && return 2;;
+        esac
+
+	do_facet $SINGLEMDS echo $1 > $MDSCAPA
+        return 0
+}
+
+oss_capability_switch() {
+        [ $# -lt 1 ] && echo "Miss oss capability switch value" && return 1
+
+        case $1 in
+                0) echo "Turn off oss capability";;
+                1) echo "Turn on oss capability";;
+                *) echo "Invalid oss capability switch value" && return 2;;
+        esac
+
+	i=0;
+	while [ $i -lt $OST_COUNT ]; do
+		j=$i;
+		i=`expr $i + 1`
+		OST="`do_facet ost$i ls -l $OST_LPROC/ | grep OST | awk '{print $9}' | grep $j$`"
+		do_facet ost$i echo $1 > $OST_LPROC/$OST/capa
+	done
+        return 0
+}
+
+turn_capability_on() {
+        local capa_timeout=${1:-"1800"}
+
+        # To turn on fid capability for the system,
+        # there is a requirement that fid capability
+        # is turned on on all MDS/OSS servers before
+        # client mount.
+
+        umount $MOUNT || return 1
+
+        mds_capability_switch 3 || return 2
+        oss_capability_switch 1 || return 3
+        mds_capability_timeout $capa_timeout || return 4
+
+        mount_client $MOUNT || return 5
+        return 0
+}
+
+turn_capability_off() {
+        # to turn off fid capability, you can just do
+        # it in a live system. But, please turn off
+        # capability of all OSS servers before MDS servers.
+
+        oss_capability_switch 0 || return 1
+        mds_capability_switch 0 || return 2
+        return 0
+}
+
+# We demonstrate that access to the objects in the filesystem are not
+# accessible without supplying secrets from the MDS by disabling a
+# proc variable on the mds so that it does not supply secrets. We then
+# try and access objects which result in failure.
+test_5() {
+        local file=$DIR/f5
+
+	[ -z "$MDT" ] && sec_skip "do not support do_facet operations." && return
+	turn_capability_off
+	rm -f $file
+
+        # Disable proc variable
+        mds_capability_switch 0 || return 1
+        oss_capability_switch 1 || return 2
+
+        # proc variable disabled -- access to the objects in the filesystem
+        # is not allowed 
+        echo "Should get Write error here : (proc variable are disabled "\
+	     "-- access to the objects in the filesystem is denied."
+	$WTL $file 30
+	if [ $? == 0 ]; then
+        	echo "Write worked well even though secrets not supplied."
+		return 3
+        fi
+
+        turn_capability_on || return 4
+        sleep 5
+
+        # proc variable enabled, secrets supplied -- write should work now
+        echo "Should not fail here : (proc variable enabled, secrets supplied "\
+	     "-- write should work now)."
+	$WTL $file 30
+	if [ $? != 0 ]; then
+        	echo "Write failed even though secrets supplied."
+		return 5
+        fi
+
+	turn_capability_off
+	rm -f $file
+}
+sec_run_test 5 "capa secrets ========================="
+
+# Expiry: A test program is performing I/O on a file. It has credential
+# with an expiry half a minute later. While the program is running the
+# credentials expire and no automatic extensions or renewals are
+# enabled. The program will demonstrate an I/O failure.
+test_6() {
+        local file=$DIR/f6
+
+	[ -z "$MDT" ] && sec_skip "do not support do_facet operations." && return
+	turn_capability_off
+	rm -f $file
+
+        turn_capability_on 30 || return 1
+        # Token expiry
+	$WTL $file 60 || return 2
+
+	# Reset MDS capability timeout
+	mds_capability_timeout 30 || exit 3
+	$WTL $file 60 &
+	local PID=$!
+	sleep 5
+
+        # To disable automatic renew, only need turn capa off on MDS.
+        mds_capability_switch 0 || return 4
+
+	echo "We expect I/O failure."
+        wait $PID
+	if [ $? == 0 ]; then
+		echo "no I/O failure got."
+		return 5
 	fi
 
-	if [ $LOCAL_MDT -eq 1 ]; then
-		echo $IDENTITY_UPCALL_BAK > $IDENTITY_UPCALL
-		echo -1 > $IDENTITY_FLUSH
+	turn_capability_off
+	rm -f $file
+}
+sec_run_test 6 "capa expiry ========================="
+
+log "cleanup: ======================================================"
+
+unsetup() {
+	if [ ! -z "$MDT"  ]; then
+		do_facet $SINGLEMDS echo $IDENTITY_UPCALL_BAK > $IDENTITY_UPCALL
+		do_facet $SINGLEMDS echo -1 > $IDENTITY_FLUSH
 	fi
 
 	$RUNAS -u $ID1 ls $DIR
@@ -367,4 +567,6 @@ sec_cleanup() {
 sec_cleanup
 
 echo '=========================== finished ==============================='
-[ -f "$SANITYSECLOG" ] && cat $SANITYSECLOG && exit 1 || true
+[ -f "$SANITYSECLOG" ] && \
+	cat $SANITYSECLOG && grep -q FAIL $SANITYSECLOG && exit 1 || true
+echo "$0 completed"
diff --git a/lustre/tests/write_time_limit.c b/lustre/tests/write_time_limit.c
new file mode 100644
index 0000000000000000000000000000000000000000..445b62329551c997eb41568958e70474d4b07f68
--- /dev/null
+++ b/lustre/tests/write_time_limit.c
@@ -0,0 +1,87 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
+/* for O_DIRECT */
+#define _GNU_SOURCE
+
+#include<stdio.h>
+#include<errno.h>
+#include<fcntl.h>
+#include<sys/types.h>
+#include<sys/stat.h>
+#include<unistd.h>
+#include<signal.h>
+#include<stdlib.h>
+#include<string.h>
+
+#define BUFFERSIZE 4096
+
+/* This flag controls termination of the main loop. */
+volatile sig_atomic_t keep_going = 1;
+
+/* The signal handler just clears the flag and re-enables itself. */
+void catch_alarm(int sig)
+{
+	keep_going = 0;
+	signal(sig, catch_alarm);
+}
+
+int main(int argc, char **argv)
+{
+        char *file;
+        unsigned char buf[BUFFERSIZE];
+        int fd, i, rc;
+	unsigned int test_time;
+        mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+
+        if (argc != 3) {
+                printf("Invalid number of arguments.\n");
+                printf("Usage %s <file> <test_time_in_seconds>\n", argv[0]);
+                return -1;
+        }
+
+        file = argv[1];
+        test_time = atoi(argv[2]);
+
+	/* Establish a handler for SIGALRM signals. */
+	signal(SIGALRM, catch_alarm);
+
+       	/* Set an alarm to go off in a little while. */
+       	alarm(test_time);
+
+        fd = open(file, O_RDWR|O_TRUNC|O_CREAT|O_SYNC|O_LARGEFILE, mode);
+        if (fd < 0) {
+                fprintf(stderr, "Error: Cannot open file named ");
+                perror(file);
+                return -1;
+        }
+
+        memset(buf, 1, BUFFERSIZE);
+	while (keep_going) {
+                for (i = 0; i < 1024; i++) {
+		        rc = write(fd, buf, BUFFERSIZE);
+			if (rc < 0) {
+                                fprintf(stderr, "Error: Write error ");
+                                perror(file);
+				exit(-1);
+                        } else if (rc != BUFFERSIZE) {
+                                fprintf(stderr, "Error: Ddidn't write all data \n");
+			}
+                }
+
+                if (ftruncate(fd, 0) < 0) {
+                        fprintf(stderr, "Error: Truncate error ");
+                        perror(file);
+			exit(-1);
+                }
+        }
+
+        if (close(fd) < 0) {
+                fprintf(stderr, "Error: Cannot close ");
+                perror(file);
+                return -1;
+        }
+
+        return 0;
+}
diff --git a/lustre/utils/gss/context_mit.c b/lustre/utils/gss/context_mit.c
index 1d734f8bca3653102ee1a1c024fb2392c60796ca..3edd60f3305666a9cdb2c9d3f5751993496c9fbd 100644
--- a/lustre/utils/gss/context_mit.c
+++ b/lustre/utils/gss/context_mit.c
@@ -42,6 +42,7 @@
 
 #ifdef _NEW_BUILD_
 # include "lgss_utils.h"
+# include "write_bytes.h"
 #else
 # include "gss_util.h"
 # include "gss_oids.h"