Whamcloud - gitweb
Branch HEAD
authorfanyong <fanyong>
Thu, 28 Feb 2008 07:35:10 +0000 (07:35 +0000)
committerfanyong <fanyong>
Thu, 28 Feb 2008 07:35:10 +0000 (07:35 +0000)
b=14769
i=adilger
i=eric.mei

(1) Fix race condition between identity upcall disabled checking
    and the real identity upcall doing.
(2) Replace "CWARN" and "CERROR" about identity with "CDEBUG".
(3) Test scripts fix for SLES10 system and remote client test.
(4) Code indent related fix.

lustre/include/lustre_ucache.h
lustre/lvfs/upcall_cache.c
lustre/mdt/mdt_identity.c
lustre/mdt/mdt_idmap.c
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_lproc.c
lustre/tests/sanity-sec.sh
lustre/tests/sanity.sh
lustre/tests/test-framework.sh

index ecfdab8..d88e176 100644 (file)
@@ -81,6 +81,7 @@ struct upcall_cache_ops {
 struct upcall_cache {
         struct list_head        uc_hashtable[UC_CACHE_HASH_SIZE];
         spinlock_t              uc_lock;
+        rwlock_t                uc_upcall_rwlock;
 
         char                    uc_name[40];            /* for upcall */
         char                    uc_upcall[UC_CACHE_UPCALL_MAXPATH];
index c2df572..7569176 100644 (file)
@@ -210,6 +210,10 @@ find_again:
                 if (rc < 0) {
                         UC_CACHE_CLEAR_ACQUIRING(entry);
                         UC_CACHE_SET_INVALID(entry);
+                        if (unlikely(rc == -EREMCHG)) {
+                                put_entry(cache, entry);
+                                GOTO(out, entry = ERR_PTR(rc));
+                        }
                 }
                 /* fall through */
         }
@@ -438,6 +442,7 @@ struct upcall_cache *upcall_cache_init(const char *name, const char *upcall,
                 RETURN(ERR_PTR(-ENOMEM));
 
         spin_lock_init(&cache->uc_lock);
+        rwlock_init(&cache->uc_upcall_rwlock);
         for (i = 0; i < UC_CACHE_HASH_SIZE; i++)
                 INIT_LIST_HEAD(&cache->uc_hashtable[i]);
         strncpy(cache->uc_name, name, sizeof(cache->uc_name) - 1);
index 1353df6..fb1f889 100644 (file)
@@ -87,7 +87,7 @@ static void mdt_identity_entry_free(struct upcall_cache *cache,
 static int mdt_identity_do_upcall(struct upcall_cache *cache,
                                   struct upcall_cache_entry *entry)
 {
-        char keystr[16];
+        char *upcall, keystr[16];
         char *argv[] = {
                   [0] = cache->uc_upcall,
                   [1] = cache->uc_name,
@@ -99,12 +99,30 @@ static int mdt_identity_do_upcall(struct upcall_cache *cache,
                   [1] = "PATH=/sbin:/usr/sbin",
                   [2] = NULL
         };
-        int rc;
+        int size, rc;
         ENTRY;
 
+        /* There is race condition:
+         * "uc_upcall" was changed just after "is_identity_get_disabled" check.
+         */
+        size = strlen(cache->uc_upcall) + 1;
+        OBD_ALLOC(upcall, size);
+        if (unlikely(!upcall))
+                RETURN(-ENOMEM);
+
+        read_lock(&cache->uc_upcall_rwlock);
+        memcpy(upcall, cache->uc_upcall, size - 1);
+        read_unlock(&cache->uc_upcall_rwlock);
+        upcall[size - 1] = 0;
+        if (unlikely(!strcmp(upcall, "NONE"))) {
+                CERROR("no upcall set\n");
+                GOTO(out, rc = -EREMCHG);
+        }
+
+        argv[0] = upcall;
+
         snprintf(keystr, sizeof(keystr), LPU64, entry->ue_key);
 
-        LASSERTF(strcmp(cache->uc_upcall, "NONE"), "no upcall set!");
         CDEBUG(D_INFO, "The upcall is: %s \n", cache->uc_upcall);
 
         rc = USERMODEHELPER(argv[0], argv, envp);
@@ -118,7 +136,10 @@ static int mdt_identity_do_upcall(struct upcall_cache *cache,
                        argv[0], argv[1], argv[2]);
                 rc = 0;
         }
-        RETURN(rc);
+        EXIT;
+out:
+        OBD_FREE(upcall, size);
+        return rc;
 }
 
 static int mdt_identity_parse_downcall(struct upcall_cache *cache,
@@ -179,15 +200,15 @@ struct md_identity *mdt_identity_get(struct upcall_cache *cache, __u32 uid)
         struct upcall_cache_entry *entry;
 
         if (!cache)
-                return NULL;
+                return ERR_PTR(-ENOENT);
 
         entry = upcall_cache_get_entry(cache, (__u64)uid, NULL);
-        if (IS_ERR(entry)) {
-                CERROR("upcall_cache_get_entry failed: %ld\n", PTR_ERR(entry));
-                return NULL;
-        }
-
-        return &entry->u.identity;
+        if (IS_ERR(entry))
+                return ERR_PTR(PTR_ERR(entry));
+        else if (unlikely(!entry))
+                return ERR_PTR(-ENOENT);
+        else
+                return &entry->u.identity;
 }
 
 void mdt_identity_put(struct upcall_cache *cache, struct md_identity *identity)
@@ -219,7 +240,7 @@ void mdt_flush_identity(struct upcall_cache *cache, int uid)
  * it must be perm[0].mp_nid, and act as default perm.
  */
 __u32 mdt_identity_get_perm(struct md_identity *identity,
-                                   __u32 is_rmtclient, lnet_nid_t nid)
+                            __u32 is_rmtclient, lnet_nid_t nid)
 {
         struct md_perm *perm;
         int i;
index a84ec9c..5a1f80b 100644 (file)
@@ -86,12 +86,12 @@ int mdt_init_idmap(struct mdt_thread_info *info)
         if (remote) {
                 med->med_rmtclient = 1;
                 if (!req->rq_auth_remote)
-                        CWARN("client (local realm) %s -> target %s asked "
-                              "to be remote!\n", client, obd->obd_name);
+                        CDEBUG(D_SEC, "client (local realm) %s -> target %s "
+                               "asked to be remote!\n", client, obd->obd_name);
         } else if (req->rq_auth_remote) {
                 med->med_rmtclient = 1;
-                CWARN("client (remote realm) %s -> target %s forced "
-                      "to be remote!\n", client, obd->obd_name);
+                CDEBUG(D_SEC, "client (remote realm) %s -> target %s forced "
+                       "to be remote!\n", client, obd->obd_name);
         }
 
         if (med->med_rmtclient) {
@@ -123,7 +123,7 @@ int mdt_init_idmap(struct mdt_thread_info *info)
                 rc = mdt_handle_idmap(info);
         } else {
                 if (req->rq_auth_uid == INVALID_UID) {
-                        CERROR("client %s -> target %s: user is not "
+                        CDEBUG(D_SEC, "client %s -> target %s: user is not "
                                "authenticated!\n", client, obd->obd_name);
                         RETURN(-EACCES);
                 }
@@ -140,7 +140,7 @@ void mdt_cleanup_idmap(struct mdt_export_data *med)
         down(&med->med_idmap_sem);
         if (med->med_idmap != NULL) {
                 lustre_idmap_fini(med->med_idmap);
-        med->med_idmap = NULL;
+                med->med_idmap = NULL;
         }
         up(&med->med_idmap_sem);
 }
@@ -181,42 +181,44 @@ int mdt_handle_idmap(struct mdt_thread_info *info)
         LASSERT(med->med_idmap);
 
         if (unlikely(!pud)) {
-                CERROR("remote client must run with rq_user_desc present\n");
+                CDEBUG(D_SEC, "remote client must run with rq_user_desc "
+                       "present\n");
                 RETURN(-EACCES);
-       }
+        }
 
         if (req->rq_auth_mapped_uid == INVALID_UID) {
-                CERROR("invalid authorized mapped uid, please check "
+                CDEBUG(D_SEC, "invalid authorized mapped uid, please check "
                        "/etc/lustre/idmap.conf!\n");
                 RETURN(-EACCES);
         }
 
         if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
-                CERROR("remote client must run with identity_get enabled!\n");
+                CDEBUG(D_SEC, "remote client must run with identity_get "
+                       "enabled!\n");
                 RETURN(-EACCES);
         }
 
         identity = mdt_identity_get(mdt->mdt_identity_cache,
                                     req->rq_auth_mapped_uid);
-        if (!identity) {
-                CERROR("can't get mdt identity(%u), no mapping added\n",
+        if (IS_ERR(identity)) {
+                CDEBUG(D_SEC, "can't get mdt identity(%u), no mapping added\n",
                        req->rq_auth_mapped_uid);
                 RETURN(-EACCES);
         }
 
         switch (opc) {
-        case SEC_CTX_INIT:
-        case SEC_CTX_INIT_CONT:
-        case MDS_CONNECT:
+                case SEC_CTX_INIT:
+                case SEC_CTX_INIT_CONT:
+                case MDS_CONNECT:
                         rc = lustre_idmap_add(med->med_idmap,
-                                   pud->pud_uid, identity->mi_uid,
-                                   pud->pud_gid, identity->mi_gid);
-                break;
-        case SEC_CTX_FINI:
+                                              pud->pud_uid, identity->mi_uid,
+                                              pud->pud_gid, identity->mi_gid);
+                        break;
+                case SEC_CTX_FINI:
                         rc = lustre_idmap_del(med->med_idmap,
-                                   pud->pud_uid, identity->mi_uid,
-                                   pud->pud_gid, identity->mi_gid);
-                break;
+                                              pud->pud_uid, identity->mi_uid,
+                                              pud->pud_gid, identity->mi_gid);
+                        break;
         }
 
         mdt_identity_put(mdt->mdt_identity_cache, identity);
@@ -225,11 +227,11 @@ int mdt_handle_idmap(struct mdt_thread_info *info)
                 RETURN(rc);
 
         switch (opc) {
-        case SEC_CTX_INIT:
-        case SEC_CTX_INIT_CONT:
-        case SEC_CTX_FINI:
-                mdt_revoke_export_locks(req->rq_export);
-                break;
+                case SEC_CTX_INIT:
+                case SEC_CTX_INIT_CONT:
+                case SEC_CTX_FINI:
+                        mdt_revoke_export_locks(req->rq_export);
+                        break;
         }
 
         RETURN(0);
@@ -238,7 +240,7 @@ int mdt_handle_idmap(struct mdt_thread_info *info)
 int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
                               struct ptlrpc_user_desc *pud)
 {
-        struct mdt_export_data *med = mdt_req2med(req);
+        struct mdt_export_data    *med = mdt_req2med(req);
         struct lustre_idmap_table *idmap = med->med_idmap;
         uid_t uid, fsuid;
         gid_t gid, fsgid;
@@ -249,7 +251,7 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
 
         uid = lustre_idmap_lookup_uid(NULL, idmap, 0, pud->pud_uid);
         if (uid == CFS_IDMAP_NOTFOUND) {
-                CERROR("no mapping for uid %u\n", pud->pud_uid);
+                CDEBUG(D_SEC, "no mapping for uid %u\n", pud->pud_uid);
                 return -EACCES;
         }
 
@@ -258,14 +260,15 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
         } else {
                 fsuid = lustre_idmap_lookup_uid(NULL, idmap, 0, pud->pud_fsuid);
                 if (fsuid == CFS_IDMAP_NOTFOUND) {
-                        CERROR("no mapping for fsuid %u\n", pud->pud_fsuid);
+                        CDEBUG(D_SEC, "no mapping for fsuid %u\n",
+                               pud->pud_fsuid);
                         return -EACCES;
                 }
         }
 
         gid = lustre_idmap_lookup_gid(NULL, idmap, 0, pud->pud_gid);
         if (gid == CFS_IDMAP_NOTFOUND) {
-                CERROR("no mapping for gid %u\n", pud->pud_gid);
+                CDEBUG(D_SEC, "no mapping for gid %u\n", pud->pud_gid);
                 return -EACCES;
         }
 
@@ -274,7 +277,8 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
         } else {
                 fsgid = lustre_idmap_lookup_gid(NULL, idmap, 0, pud->pud_fsgid);
                 if (fsgid == CFS_IDMAP_NOTFOUND) {
-                        CERROR("no mapping for fsgid %u\n", pud->pud_fsgid);
+                        CDEBUG(D_SEC, "no mapping for fsgid %u\n",
+                               pud->pud_fsgid);
                         return -EACCES;
                 }
         }
@@ -292,9 +296,9 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
  */
 void mdt_body_reverse_idmap(struct mdt_thread_info *info, struct mdt_body *body)
 {
-        struct ptlrpc_request   *req = mdt_info_req(info);
-        struct md_ucred         *uc = mdt_ucred(info);
-        struct mdt_export_data  *med = mdt_req2med(req);
+        struct ptlrpc_request     *req = mdt_info_req(info);
+        struct md_ucred           *uc = mdt_ucred(info);
+        struct mdt_export_data    *med = mdt_req2med(req);
         struct lustre_idmap_table *idmap = med->med_idmap;
 
         if (!med->med_rmtclient)
@@ -330,10 +334,10 @@ void mdt_body_reverse_idmap(struct mdt_thread_info *info, struct mdt_body *body)
 /* Do not ignore root_squash for non-setattr case. */
 int mdt_fix_attr_ucred(struct mdt_thread_info *info, __u32 op)
 {
-        struct ptlrpc_request   *req = mdt_info_req(info);
-        struct md_ucred         *uc = mdt_ucred(info);
-        struct lu_attr          *attr = &info->mti_attr.ma_attr;
-        struct mdt_export_data  *med = mdt_req2med(req);
+        struct ptlrpc_request     *req = mdt_info_req(info);
+        struct md_ucred           *uc = mdt_ucred(info);
+        struct lu_attr            *attr = &info->mti_attr.ma_attr;
+        struct mdt_export_data    *med = mdt_req2med(req);
         struct lustre_idmap_table *idmap = med->med_idmap;
 
         if ((uc->mu_valid != UCRED_OLD) && (uc->mu_valid != UCRED_NEW))
@@ -344,16 +348,17 @@ int mdt_fix_attr_ucred(struct mdt_thread_info *info, __u32 op)
                         attr->la_uid = uc->mu_fsuid;
                 /* for S_ISGID, inherit gid from his parent, such work will be
                  * done in cmm/mdd layer, here set all cases as uc->mu_fsgid. */
-                        if ((attr->la_valid & LA_GID) && (attr->la_gid != -1))
-                                attr->la_gid = uc->mu_fsgid;
+                if ((attr->la_valid & LA_GID) && (attr->la_gid != -1))
+                        attr->la_gid = uc->mu_fsgid;
         } else if (med->med_rmtclient) {
                 /* NB: -1 case will be handled by mdt_fix_attr() later. */
                 if ((attr->la_valid & LA_UID) && (attr->la_uid != -1)) {
                         uid_t uid = lustre_idmap_lookup_uid(uc, idmap, 0,
-                                                           attr->la_uid);
+                                                            attr->la_uid);
 
                         if (uid == CFS_IDMAP_NOTFOUND) {
-                                CWARN("Deny chown to uid %u\n", attr->la_uid);
+                                CDEBUG(D_SEC, "Deny chown to uid %u\n",
+                                       attr->la_uid);
                                 return -EPERM;
                         }
 
@@ -361,10 +366,11 @@ int mdt_fix_attr_ucred(struct mdt_thread_info *info, __u32 op)
                 }
                 if ((attr->la_valid & LA_GID) && (attr->la_gid != -1)) {
                         gid_t gid = lustre_idmap_lookup_gid(uc, idmap, 0,
-                                                           attr->la_gid);
+                                                            attr->la_gid);
 
                         if (gid == CFS_IDMAP_NOTFOUND) {
-                                CWARN("Deny chown to gid %u\n", attr->la_gid);
+                                CDEBUG(D_SEC, "Deny chown to gid %u\n",
+                                       attr->la_gid);
                                 return -EPERM;
                         }
 
index 410ad51..0d36467 100644 (file)
@@ -83,11 +83,11 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
         struct mdt_device       *mdt = info->mti_mdt;
         struct ptlrpc_user_desc *pud = req->rq_user_desc;
         struct md_ucred         *ucred = mdt_ucred(info);
-        lnet_nid_t              peernid = req->rq_peer.nid;
+        lnet_nid_t               peernid = req->rq_peer.nid;
         __u32                    perm = 0;
-        int                     setuid;
-        int                     setgid;
-        int                     rc = 0;
+        int                      setuid;
+        int                      setgid;
+        int                      rc = 0;
 
         ENTRY;
 
@@ -112,7 +112,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
         /* sanity check: we expect the uid which client claimed is true */
         if (med->med_rmtclient) {
                 if (req->rq_auth_mapped_uid == INVALID_UID) {
-                        CWARN("remote user not mapped, deny access!\n");
+                        CDEBUG(D_SEC, "remote user not mapped, deny access!\n");
                         RETURN(-EACCES);
                 }
 
@@ -120,9 +120,9 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                         RETURN(-EACCES);
 
                 if (req->rq_auth_mapped_uid != pud->pud_uid) {
-                        CERROR("remote client "LPU64": auth/mapped uid %u/%u "
-                               "while client claim %u:%u/%u:%u\n",
-                               peernid, req->rq_auth_uid,
+                        CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u "
+                               "while client claims %u:%u/%u:%u\n",
+                               libcfs_nid2str(peernid), req->rq_auth_uid,
                                req->rq_auth_mapped_uid,
                                pud->pud_uid, pud->pud_gid,
                                pud->pud_fsuid, pud->pud_fsgid);
@@ -130,17 +130,18 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                 }
         } else {
                 if (req->rq_auth_uid != pud->pud_uid) {
-                        CERROR("local client "LPU64": auth uid %u "
-                               "while client claim %u:%u/%u:%u\n",
-                               peernid, req->rq_auth_uid, pud->pud_uid,
-                               pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid);
+                        CDEBUG(D_SEC, "local client %s: auth uid %u "
+                               "while client claims %u:%u/%u:%u\n",
+                               libcfs_nid2str(peernid), req->rq_auth_uid,
+                               pud->pud_uid, pud->pud_gid,
+                               pud->pud_fsuid, pud->pud_fsgid);
                         RETURN(-EACCES);
                 }
         }
 
         if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
                 if (med->med_rmtclient) {
-                        CERROR("remote client must run with identity_get "
+                        CDEBUG(D_SEC, "remote client must run with identity_get "
                                "enabled!\n");
                         RETURN(-EACCES);
                 } else {
@@ -149,16 +150,26 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                                CFS_SETGRP_PERM;
                 }
         } else {
-                ucred->mu_identity = mdt_identity_get(mdt->mdt_identity_cache,
-                                                      pud->pud_uid);
-                if (!ucred->mu_identity) {
-                        CERROR("Deny access without identity: uid %d\n",
-                               pud->pud_uid);
-                RETURN(-EACCES);
+                struct md_identity *identity;
+
+                identity = mdt_identity_get(mdt->mdt_identity_cache,
+                                            pud->pud_uid);
+                if (IS_ERR(identity)) {
+                        if (unlikely(PTR_ERR(identity) == -EREMCHG &&
+                                     !med->med_rmtclient)) {
+                                ucred->mu_identity = NULL;
+                                perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
+                                       CFS_SETGRP_PERM;
+                        } else {
+                                CDEBUG(D_SEC, "Deny access without identity: uid %u\n",
+                                       pud->pud_uid);
+                                RETURN(-EACCES);
+                        }
                 } else {
+                        ucred->mu_identity = identity;
                         perm = mdt_identity_get_perm(ucred->mu_identity,
-                                                   med->med_rmtclient,
-                                                   peernid);
+                                                     med->med_rmtclient,
+                                                     peernid);
                 }
         }
 
@@ -170,17 +181,17 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
 
         /* check permission of setuid */
         if (setuid && !(perm & CFS_SETUID_PERM)) {
-                CWARN("mdt blocked setuid attempt (%u -> %u) from "
-                      LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid);
+                CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n",
+                       pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid));
                 GOTO(out, rc = -EACCES);
         }
 
         /* check permission of setgid */
         if (setgid && !(perm & CFS_SETGID_PERM)) {
-                CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
-                      "from "LPX64"\n", pud->pud_uid, pud->pud_gid,
-                      pud->pud_fsuid, pud->pud_fsgid,
-                      ucred->mu_identity->mi_gid, peernid);
+                CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
+                       "from %s\n", pud->pud_uid, pud->pud_gid,
+                       pud->pud_fsuid, pud->pud_fsgid,
+                       ucred->mu_identity->mi_gid, libcfs_nid2str(peernid));
                 GOTO(out, rc = -EACCES);
         }
 
@@ -189,20 +200,20 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
          */
         if (!med->med_rmtclient && perm & CFS_SETGRP_PERM) {
                 if (pud->pud_ngroups) {
-                /* setgroups for local client */
+                        /* setgroups for local client */
                         ucred->mu_ginfo = groups_alloc(pud->pud_ngroups);
                         if (!ucred->mu_ginfo) {
-                        CERROR("failed to alloc %d groups\n",
-                               pud->pud_ngroups);
-                        GOTO(out, rc = -ENOMEM);
-                }
+                                CERROR("failed to alloc %d groups\n",
+                                       pud->pud_ngroups);
+                                GOTO(out, rc = -ENOMEM);
+                        }
 
                         lustre_groups_from_list(ucred->mu_ginfo,
                                                 pud->pud_groups);
                         lustre_groups_sort(ucred->mu_ginfo);
-        } else {
-                ucred->mu_ginfo = NULL;
-        }
+                } else {
+                        ucred->mu_ginfo = NULL;
+                }
         } else {
                 ucred->mu_suppgids[0] = -1;
                 ucred->mu_suppgids[1] = -1;
@@ -250,7 +261,7 @@ int mdt_check_ucred(struct mdt_thread_info *info)
         struct ptlrpc_user_desc *pud = req->rq_user_desc;
         struct md_ucred         *ucred = mdt_ucred(info);
         struct md_identity      *identity = NULL;
-        lnet_nid_t              peernid = req->rq_peer.nid;
+        lnet_nid_t               peernid = req->rq_peer.nid;
         __u32                    perm = 0;
         int                      setuid;
         int                      setgid;
@@ -266,38 +277,38 @@ int mdt_check_ucred(struct mdt_thread_info *info)
 
         /* sanity check: if we use strong authentication, we expect the
          * uid which client claimed is true */
-                if (med->med_rmtclient) {
-                        if (req->rq_auth_mapped_uid == INVALID_UID) {
-                                CWARN("remote user not mapped, deny access!\n");
-                                RETURN(-EACCES);
-                        }
+        if (med->med_rmtclient) {
+                if (req->rq_auth_mapped_uid == INVALID_UID) {
+                        CDEBUG(D_SEC, "remote user not mapped, deny access!\n");
+                        RETURN(-EACCES);
+                }
 
-                        if (ptlrpc_user_desc_do_idmap(req, pud))
-                                RETURN(-EACCES);
+                if (ptlrpc_user_desc_do_idmap(req, pud))
+                        RETURN(-EACCES);
 
-                        if (req->rq_auth_mapped_uid != pud->pud_uid) {
-                        CERROR("remote client "LPU64": auth/mapped uid %u/%u "
-                                       "while client claim %u:%u/%u:%u\n",
-                               peernid, req->rq_auth_uid,
+                if (req->rq_auth_mapped_uid != pud->pud_uid) {
+                        CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u "
+                               "while client claims %u:%u/%u:%u\n",
+                               libcfs_nid2str(peernid), req->rq_auth_uid,
                                req->rq_auth_mapped_uid,
                                pud->pud_uid, pud->pud_gid,
                                pud->pud_fsuid, pud->pud_fsgid);
-                                RETURN(-EACCES);
-                        }
-                } else {
-                        if (req->rq_auth_uid != pud->pud_uid) {
-                                CERROR("local client "LPU64": auth uid %u "
-                                       "while client claim %u:%u/%u:%u\n",
-                                       peernid, req->rq_auth_uid, pud->pud_uid,
-                                       pud->pud_gid, pud->pud_fsuid,
-                                       pud->pud_fsgid);
-                                RETURN(-EACCES);
-                        }
+                        RETURN(-EACCES);
+                }
+        } else {
+                if (req->rq_auth_uid != pud->pud_uid) {
+                        CDEBUG(D_SEC, "local client %s: auth uid %u "
+                               "while client claims %u:%u/%u:%u\n",
+                               libcfs_nid2str(peernid), req->rq_auth_uid,
+                               pud->pud_uid, pud->pud_gid,
+                               pud->pud_fsuid, pud->pud_fsgid);
+                        RETURN(-EACCES);
                 }
+        }
 
         if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
                 if (med->med_rmtclient) {
-                        CERROR("remote client must run with identity_get "
+                        CDEBUG(D_SEC, "remote client must run with identity_get "
                                "enabled!\n");
                         RETURN(-EACCES);
                 }
@@ -305,9 +316,15 @@ int mdt_check_ucred(struct mdt_thread_info *info)
         }
 
         identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
-        if (!identity) {
-                CERROR("Deny access without identity: uid %d\n", pud->pud_uid);
-                RETURN(-EACCES);
+        if (IS_ERR(identity)) {
+                if (unlikely(PTR_ERR(identity) == -EREMCHG &&
+                             !med->med_rmtclient)) {
+                        RETURN(0);
+                } else {
+                        CDEBUG(D_SEC, "Deny access without identity: uid %u\n",
+                               pud->pud_uid);
+                        RETURN(-EACCES);
+               }
         }
 
         perm = mdt_identity_get_perm(identity, med->med_rmtclient, peernid);
@@ -318,17 +335,17 @@ int mdt_check_ucred(struct mdt_thread_info *info)
 
         /* check permission of setuid */
         if (setuid && !(perm & CFS_SETUID_PERM)) {
-                CWARN("mdt blocked setuid attempt (%u -> %u) from "
-                      LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid);
+                CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n",
+                       pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid));
                 GOTO(out, rc = -EACCES);
         }
 
         /* check permission of setgid */
         if (setgid && !(perm & CFS_SETGID_PERM)) {
-                CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
-                      "from "LPX64"\n", pud->pud_uid, pud->pud_gid,
-                      pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid,
-                      peernid);
+                CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
+                       "from %s\n", pud->pud_uid, pud->pud_gid,
+                       pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid,
+                       libcfs_nid2str(peernid));
                 GOTO(out, rc = -EACCES);
         }
 
@@ -359,10 +376,14 @@ static int old_init_ucred(struct mdt_thread_info *info,
         if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
                 identity = mdt_identity_get(mdt->mdt_identity_cache,
                                             uc->mu_fsuid);
-                if (!identity) {
-                        CERROR("Deny access without identity: uid %d\n",
-                               uc->mu_fsuid);
-                        RETURN(-EACCES);
+                if (IS_ERR(identity)) {
+                        if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
+                                identity = NULL;
+                        } else {
+                                CDEBUG(D_SEC, "Deny access without identity: "
+                                       "uid %u\n", uc->mu_fsuid);
+                                RETURN(-EACCES);
+                        }
                 }
         }
         uc->mu_identity = identity;
@@ -395,11 +416,15 @@ static int old_init_ucred_reint(struct mdt_thread_info *info)
         if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
                 identity = mdt_identity_get(mdt->mdt_identity_cache,
                                             uc->mu_fsuid);
-                if (!identity) {
-                        CERROR("Deny access without identity: uid %d\n",
-                               uc->mu_fsuid);
-                        RETURN(-EACCES);
-        }
+                if (IS_ERR(identity)) {
+                        if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
+                                identity = NULL;
+                        } else {
+                                CDEBUG(D_SEC, "Deny access without identity: "
+                                       "uid %u\n", uc->mu_fsuid);
+                                RETURN(-EACCES);
+                        }
+                }
         }
         uc->mu_identity = identity;
 
index 3b2db54..ec7034e 100644 (file)
@@ -155,10 +155,14 @@ static int lprocfs_rd_identity_upcall(char *page, char **start, off_t off,
 {
         struct obd_device *obd = data;
         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+        struct upcall_cache *hash = mdt->mdt_identity_cache;
+        int len;
 
         *eof = 1;
-        return snprintf(page, count, "%s\n",
-                        mdt->mdt_identity_cache->uc_upcall);
+        read_lock(&hash->uc_upcall_rwlock);
+        len = snprintf(page, count, "%s\n", hash->uc_upcall);
+        read_unlock(&hash->uc_upcall_rwlock);
+        return len;
 }
 
 static int lprocfs_wr_identity_upcall(struct file *file, const char *buffer,
@@ -179,13 +183,19 @@ static int lprocfs_wr_identity_upcall(struct file *file, const char *buffer,
                 return -EFAULT;
 
         /* Remove any extraneous bits from the upcall (e.g. linefeeds) */
+        write_lock(&hash->uc_upcall_rwlock);
         sscanf(kernbuf, "%s", hash->uc_upcall);
+        write_unlock(&hash->uc_upcall_rwlock);
 
         if (strcmp(hash->uc_name, obd->obd_name) != 0)
                 CWARN("%s: write to upcall name %s\n",
                       obd->obd_name, hash->uc_upcall);
-        CWARN("%s: identity upcall set to %s\n", obd->obd_name, hash->uc_upcall);
 
+        if (strcmp(hash->uc_upcall, "NONE") == 0 && mdt->mdt_opts.mo_acl)
+                CWARN("%s: disable \"identity_upcall\" with ACL enabled maybe "
+                      "cause unexpected \"EACCESS\"\n", obd->obd_name);
+
+        CWARN("%s: identity upcall set to %s\n", obd->obd_name, hash->uc_upcall);
         return count;
 }
 
index a348768..e2a8d51 100644 (file)
@@ -63,7 +63,7 @@ else
        echo "without GSS support"
 fi
 
-MDT="`do_facet $SINGLEMDS \"ls -l $MDT_LPROC/ 2>/dev/null\" | grep MDT | awk '{print $9}'`"
+MDT="`do_facet $SINGLEMDS find $MDT_LPROC/ -name \*MDT\* -printf %f 2>/dev/null || true`"
 if [ ! -z "$MDT" ]; then
        IDENTITY_FLUSH=$MDT_LPROC/$MDT/identity_flush
        MDSCAPA=$MDT_LPROC/$MDT/capa
@@ -306,7 +306,7 @@ oss_capability_switch() {
 
        for i in `seq $OSTCOUNT`; do
                local j=`expr $i - 1`
-               local OST="`do_facet ost$i \"ls -l $OST_LPROC/\" | grep OST | awk '{print $9}' | grep $j$`"
+               local OST="`do_facet ost$i find $OST_LPROC/ -name \*OST\*$j -printf %f 2>/dev/null || true`"
                do_facet ost$i "echo $1 > $OST_LPROC/$OST/capa"
        done
         return 0
index 0afab4a..83ef56a 100644 (file)
@@ -4846,6 +4846,7 @@ test_124b() {
 run_test 124b "lru resize (performance test) ======================="
 
 test_125() { # 13358
+       [ -z "$(grep local $LPROC/llite/*/client_type)" ] && skip "must run as local client" && return
        [ -z "$(grep acl $LPROC/mdc/*-mdc-*/connect_flags)" ] && skip "must have acl enabled" && return
        mkdir -p $DIR/d125 || error "mkdir failed"
        $SETSTRIPE $DIR/d125 -s 65536 -c -1 || error "setstripe failed"
@@ -4855,6 +4856,7 @@ test_125() { # 13358
 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
 
 test_126() { # bug 12829/13455
+       [ -z "$(grep local $LPROC/llite/*/client_type)" ] && skip "must run as local client" && return
        [ "$UID" != 0 ] && echo "skipping $TESTNAME (must run as root)" && return
        $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
        gid=`ls -n $DIR/$tfile | awk '{print $4}'`
index 0fa6898..1d8e6fb 100644 (file)
@@ -13,7 +13,7 @@ export CATASTROPHE=${CATASTROPHE:-/proc/sys/lnet/catastrophe}
 export GSS=false
 export GSS_KRB5=false
 export GSS_PIPEFS=false
-export IDENTITY_UPCALL=false
+export IDENTITY_UPCALL=default
 #export PDSH="pdsh -S -Rssh -w"
 
 # eg, assert_env LUSTRE MDSNODES OSTNODES CLIENTS
@@ -118,7 +118,7 @@ init_test_env() {
             ;;
     esac
 
-    case "x$ID" in
+    case "x$IDUP" in
         xtrue)
             IDENTITY_UPCALL=true
             ;;
@@ -928,7 +928,7 @@ switch_identity() {
     local num=$1
     local switch=$2
     local j=`expr $num - 1`
-    local MDT="`do_facet mds$num ls -l $LPROC/mdt/ 2>/dev/null | grep MDT | awk '{print $9}' | grep $j$`"
+    local MDT="`do_facet mds$num find $LPROC/mdt/ -name \*MDT\*$j -printf %f 2>/dev/null || true`"
 
     if [ -z "$MDT" ]; then
         return 2
@@ -936,7 +936,7 @@ switch_identity() {
 
     local old="`do_facet mds$num cat $LPROC/mdt/$MDT/identity_upcall`"
 
-    if [ $switch ]; then
+    if $switch; then
         do_facet mds$num "echo \"$L_GETIDENTITY\" > $LPROC/mdt/$MDT/identity_upcall"
     else
         do_facet mds$num "echo \"NONE\" > $LPROC/mdt/$MDT/identity_upcall"
@@ -961,7 +961,9 @@ setupall() {
             echo $REFORMAT | grep -q "reformat" \
             || do_facet mds$num "$TUNEFS --writeconf $DEVNAME"
             start mds$num $DEVNAME $MDS_MOUNT_OPTS
-            switch_identity $num $IDENTITY_UPCALL
+           if [ $IDENTITY_UPCALL != "default" ]; then
+                switch_identity $num $IDENTITY_UPCALL
+           fi
         done
         for num in `seq $OSTCOUNT`; do
             DEVNAME=$(ostdevname $num)