Whamcloud - gitweb
LU-11739 lod: subdir under ROOT should honor default layout
[fs/lustre-release.git] / lustre / utils / gss / lgss_utils.c
index 1a3a941..b87d5d6 100644 (file)
@@ -1,9 +1,10 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * Modifications for Lustre
- * Copyright 2007, Cluster File Systems, Inc.
- * All rights reserved
+ *
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ *
  * Author: Eric Mei <ericm@clusterfs.com>
  */
 
 #include "lgss_krb5_utils.h"
 
 const char *lgss_svc_str[LGSS_SVC_MAX] = {
-        [LGSS_SVC_MDS] = LGSS_SVC_MDS_STR,
-        [LGSS_SVC_OSS] = LGSS_SVC_OST_STR,
         [LGSS_SVC_MGS] = LGSS_SVC_MGS_STR,
+        [LGSS_SVC_MDS] = LGSS_SVC_MDS_STR,
+        [LGSS_SVC_OSS] = LGSS_SVC_OSS_STR,
 };
 
 /****************************************
@@ -115,55 +116,67 @@ static struct lgss_mutex_s {
         key_t           sem_key;
         int             sem_id;
 } lgss_mutexes[LGSS_MUTEX_MAX] = {
-        [LGSS_MUTEX_KRB5]       = { "keyring",  0x4292d473, 0 },
+       [LGSS_MUTEX_KRB5] = { "keyring", 0x4292d473, 0 },
 };
 
-int lgss_mutex_lock(lgss_mutex_id_t mid)
+static int lgss_mutex_get(struct lgss_mutex_s *mutex)
 {
-        struct lgss_mutex_s     *sem = &lgss_mutexes[mid];
-        struct sembuf            sembuf;
-
-        lassert(mid < LGSS_MUTEX_MAX);
+        mutex->sem_id = semget(mutex->sem_key, 1, IPC_CREAT | IPC_EXCL | 0700);
+        if (mutex->sem_id != -1) {
+                if (semctl(mutex->sem_id, 0, SETVAL, 1) == -1) {
+                        logmsg(LL_ERR, "initialize sem %x: %s\n",
+                               mutex->sem_key, strerror(errno));
+                        return -1;
+                }
 
-        logmsg(LL_TRACE, "locking mutex %x for %s\n",
-               sem->sem_key, sem->sem_name);
-again:
-        sem->sem_id = semget(sem->sem_key, 1, IPC_CREAT | IPC_EXCL | 0700);
-        if (sem->sem_id == -1) {
+                logmsg(LL_DEBUG, "created & initialized sem %x id %d for %s\n",
+                       mutex->sem_key, mutex->sem_id, mutex->sem_name);
+        } else {
                 if (errno != EEXIST) {
                         logmsg(LL_ERR, "create sem %x: %s\n",
-                               sem->sem_key, strerror(errno));
+                               mutex->sem_key, strerror(errno));
                         return -1;
                 }
 
-                /* already exist. Note there's still a small window of racing
-                 * with other processes, due to the stupid semaphore semantics.
-                 */
-                sem->sem_id = semget(sem->sem_key, 0, 0700);
-                if (sem->sem_id == -1) {
+                /* already created by someone else, simply get it.
+                 * Note there's still a small window of racing between create
+                 * and initialize, a flaw in semaphore semantics */
+                mutex->sem_id = semget(mutex->sem_key, 0, 0700);
+                if (mutex->sem_id == -1) {
                         if (errno == ENOENT) {
                                 logmsg(LL_WARN, "sem %x just disappeared "
-                                       "under us, try again\n", sem->sem_key);
-                                goto again;
+                                       "under us, try again\n", mutex->sem_key);
+                                return 1;
                         }
 
-                        logmsg(LL_ERR, "get sem %x: %s\n", sem->sem_key,
+                        logmsg(LL_ERR, "get sem %x: %s\n", mutex->sem_key,
                                strerror(errno));
                         return -1;
                 }
-        } else {
-                int val = 1;
 
-                logmsg(LL_DEBUG, "created sem %x for %s, initialize to 1\n",
-                       sem->sem_key, sem->sem_name);
-                if (semctl(sem->sem_id, 0, SETVAL, val) == -1) {
-                        logmsg(LL_ERR, "initialize sem %x: %s\n",
-                               sem->sem_key, strerror(errno));
-                        return -1;
-                }
+                logmsg(LL_TRACE, "got sem %x id %d for %s\n",
+                       mutex->sem_key, mutex->sem_id, mutex->sem_name);
         }
-        logmsg(LL_TRACE, "got sem %x id %d for %s\n",
-               sem->sem_key, sem->sem_id, sem->sem_name);
+
+        return 0;
+}
+
+int lgss_mutex_lock(lgss_mutex_id_t mid)
+{
+        struct lgss_mutex_s     *sem = &lgss_mutexes[mid];
+        struct sembuf            sembuf;
+        int                      rc;
+
+        lassert(mid < LGSS_MUTEX_MAX);
+
+        logmsg(LL_TRACE, "locking mutex %x for %s\n",
+               sem->sem_key, sem->sem_name);
+
+        do {
+                rc = lgss_mutex_get(sem);
+                if (rc < 0)
+                        return rc;
+        } while (rc);
 
         sembuf.sem_num = 0;
         sembuf.sem_op = -1;
@@ -186,7 +199,7 @@ int lgss_mutex_unlock(lgss_mutex_id_t mid)
         struct sembuf            sembuf;
 
         lassert(mid < LGSS_MUTEX_MAX);
-        lassert(sem->sem_id != 0);
+        lassert(sem->sem_id >= 0);
 
         logmsg(LL_TRACE, "unlocking mutex %x for %s\n",
                sem->sem_key, sem->sem_name);
@@ -211,17 +224,31 @@ int lgss_mutex_unlock(lgss_mutex_id_t mid)
  ****************************************/
 
 /* from kerberos source, gssapi_krb5.c */
-gss_OID_desc krb5oid =
-        {9, "\052\206\110\206\367\022\001\002\002"};
-
-gss_OID_desc spkm3oid =
-        {7, "\053\006\001\005\005\001\003"};
+gss_OID_desc krb5oid = {
+       .length = 9,
+       .elements = "\052\206\110\206\367\022\001\002\002"
+};
+gss_OID_desc spkm3oid = {
+       .length = 7,
+       .elements = "\053\006\001\005\005\001\003"
+};
+/* null and sk come from IU's oid space */
+gss_OID_desc nulloid = {
+       .length = 12,
+       .elements = "\053\006\001\004\001\311\146\215\126\001\000\000"
+};
+#ifdef HAVE_OPENSSL_SSK
+gss_OID_desc skoid = {
+       .length = 12,
+       .elements = "\053\006\001\004\001\311\146\215\126\001\000\001"
+};
+#endif
 
 /****************************************
  * log facilities                       *
  ****************************************/
 
-loglevel_t g_log_level = LL_INFO;
+loglevel_t g_log_level = LL_WARN;
 
 static const char *log_prefix[] = {
         [LL_ERR]        = "ERROR",
@@ -313,9 +340,15 @@ void __logmsg_gss(loglevel_t level, const char *func, const gss_OID mech,
 
 struct lgss_mech_type *lgss_name2mech(const char *mech_name)
 {
-        if (strcmp(mech_name, "krb5") == 0)
-                return &lgss_mech_krb5;
-        return NULL;
+       if (strcmp(mech_name, "krb5") == 0)
+               return &lgss_mech_krb5;
+       if (strcmp(mech_name, "gssnull") == 0)
+               return &lgss_mech_null;
+#ifdef HAVE_OPENSSL_SSK
+       if (strcmp(mech_name, "sk") == 0)
+               return &lgss_mech_sk;
+#endif
+       return NULL;
 }
 
 int lgss_mech_initialize(struct lgss_mech_type *mech)
@@ -349,7 +382,7 @@ struct lgss_cred * lgss_create_cred(struct lgss_mech_type *mech)
 
 void lgss_destroy_cred(struct lgss_cred *cred)
 {
-        lassert(cred->lc_mech);
+       lassert(cred->lc_mech != NULL);
         lassert(cred->lc_mech_cred == NULL);
 
         logmsg(LL_TRACE, "destroying a %s cred at %p\n",
@@ -361,7 +394,7 @@ int lgss_prepare_cred(struct lgss_cred *cred)
 {
         struct lgss_mech_type   *mech = cred->lc_mech;
 
-        lassert(mech);
+       lassert(mech != NULL);
 
         logmsg(LL_TRACE, "preparing %s cred %p\n", mech->lmt_name, cred);
 
@@ -374,13 +407,13 @@ void lgss_release_cred(struct lgss_cred *cred)
 {
         struct lgss_mech_type   *mech = cred->lc_mech;
 
-        lassert(mech);
+       lassert(mech != NULL);
 
         logmsg(LL_TRACE, "releasing %s cred %p\n", mech->lmt_name, cred);
 
         if (cred->lc_mech_cred) {
                 lassert(cred->lc_mech != NULL);
-                lassert(cred->lc_mech->lmt_release_cred);
+               lassert(cred->lc_mech->lmt_release_cred != NULL);
 
                 cred->lc_mech->lmt_release_cred(cred);
         }
@@ -390,7 +423,7 @@ int lgss_using_cred(struct lgss_cred *cred)
 {
         struct lgss_mech_type   *mech = cred->lc_mech;
 
-        lassert(mech);
+       lassert(mech != NULL);
 
         logmsg(LL_TRACE, "using %s cred %p\n", mech->lmt_name, cred);
 
@@ -399,6 +432,22 @@ int lgss_using_cred(struct lgss_cred *cred)
         return 0;
 }
 
+int lgss_validate_cred(struct lgss_cred *cred, gss_buffer_desc *token,
+                      gss_buffer_desc *ctx_token)
+{
+       struct lgss_mech_type *mech = cred->lc_mech;
+
+       lassert(mech != NULL);
+
+       logmsg(LL_TRACE, "validate %s cred %p with token %p\n", mech->lmt_name,
+              cred, token);
+
+       if (mech->lmt_validate_cred)
+               return mech->lmt_validate_cred(cred, token, ctx_token);
+
+       return 0;
+}
+
 /****************************************
  * helper functions                     *
  ****************************************/
@@ -417,7 +466,8 @@ int lgss_get_service_str(char **string, uint32_t lsvc, uint64_t tgt_nid)
         }
 
         if (lnet_nid2hostname(tgt_nid, namebuf, max_namelen)) {
-                logmsg(LL_ERR, "can't resolve hostname from nid %Lx\n",tgt_nid);
+               logmsg(LL_ERR, "cannot resolve hostname from nid %"PRIx64"\n",
+                      tgt_nid);
                 return -1;
         }