Remove support for Solaris pre-8
[openafs.git] / src / afs / afs_user.c
index bad9926..79d9faa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
@@ -26,7 +26,7 @@
 #ifdef AFS_SGI62_ENV
 #include "h/hashing.h"
 #endif
-#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN60_ENV)
+#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV)
 #include <netinet/in_var.h>
 #endif /* ! AFS_HPUX110_ENV */
 #endif /* !defined(UKERNEL) */
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs/afs_stats.h"     /* afs statistics */
 
-#if    defined(AFS_SUN56_ENV)
+#if    defined(AFS_SUN5_ENV)
 #include <inet/led.h>
 #include <inet/common.h>
-#if   defined(AFS_SUN58_ENV)
 #include <netinet/ip6.h>
-#endif
 #include <inet/ip.h>
 #endif
 
@@ -52,39 +50,6 @@ struct unixuser *afs_users[NUSERS];
 #ifndef AFS_PAG_MANAGER
 /* Forward declarations */
 void afs_ResetAccessCache(afs_int32 uid, int alock);
-
-/*
- * Called with afs_xuser, afs_xserver and afs_xconn locks held, to delete
- * appropriate conn structures for au
- */
-static void
-RemoveUserConns(register struct unixuser *au)
-{
-    register int i;
-    register struct server *ts;
-    register struct srvAddr *sa;
-    register struct afs_conn *tc, **lc;
-
-    AFS_STATCNT(RemoveUserConns);
-    for (i = 0; i < NSERVERS; i++) {
-       for (ts = afs_servers[i]; ts; ts = ts->next) {
-           for (sa = ts->addr; sa; sa = sa->next_sa) {
-               lc = &sa->conns;
-               for (tc = *lc; tc; lc = &tc->next, tc = *lc) {
-                   if (tc->user == au && tc->refCount == 0) {
-                       *lc = tc->next;
-                       AFS_GUNLOCK();
-                       rx_DestroyConnection(tc->id);
-                       AFS_GLOCK();
-                       afs_osi_Free(tc, sizeof(struct afs_conn));
-                       break;  /* at most one instance per server */
-                   }           /*Found unreferenced connection for user */
-               }               /*For each connection on the server */
-           }
-       }                       /*For each server on chain */
-    }                          /*For each chain */
-
-}                              /*RemoveUserConns */
 #endif /* !AFS_PAG_MANAGER */
 
 
@@ -98,8 +63,8 @@ RemoveUserConns(register struct unixuser *au)
 void
 afs_GCUserData(int aforce)
 {
-    register struct unixuser *tu, **lu, *nu;
-    register int i;
+    struct unixuser *tu, **lu, *nu;
+    int i;
     afs_int32 now, delFlag;
 
     AFS_STATCNT(afs_GCUserData);
@@ -115,12 +80,11 @@ afs_GCUserData(int aforce)
            delFlag = 0;        /* should we delete this dude? */
            /* Don't garbage collect users in use now (refCount) */
            if (tu->refCount == 0) {
-               if (tu->states & UHasTokens) {
-                   /*
-                    * Give ourselves a little extra slack, in case we
-                    * reauthenticate
-                    */
-                   if (tu->ct.EndTimestamp < now - NOTOKTIMEOUT)
+               if (tu->tokens) {
+                   /* Need to walk the token stack, and dispose of
+                    * all expired tokens */
+                   afs_DiscardExpiredTokens(&tu->tokens, now);
+                   if (!afs_HasUsableTokens(tu->tokens, now))
                        delFlag = 1;
                } else {
                    if (aforce || (tu->tokenTime < now - NOTOKTIMEOUT))
@@ -131,10 +95,10 @@ afs_GCUserData(int aforce)
            if (delFlag) {
                *lu = tu->next;
 #ifndef AFS_PAG_MANAGER
-               RemoveUserConns(tu);
+                afs_ReleaseConnsUser(tu);
 #endif
-               if (tu->stp)
-                   afs_osi_Free(tu->stp, tu->stLen);
+               afs_FreeTokens(&tu->tokens);
+
                if (tu->exporter)
                    EXP_RELE(tu->exporter);
                afs_osi_Free(tu, sizeof(struct unixuser));
@@ -163,8 +127,8 @@ afs_GCUserData(int aforce)
 void
 afs_CheckTokenCache(void)
 {
-    register int i;
-    register struct unixuser *tu;
+    int i;
+    struct unixuser *tu;
     afs_int32 now;
 
     AFS_STATCNT(afs_CheckCacheResets);
@@ -173,24 +137,18 @@ afs_CheckTokenCache(void)
     now = osi_Time();
     for (i = 0; i < NUSERS; i++) {
        for (tu = afs_users[i]; tu; tu = tu->next) {
-           register afs_int32 uid;
+           afs_int32 uid;
 
            /*
             * If tokens are still good and user has Kerberos tickets,
             * check expiration
             */
-           if (!(tu->states & UTokensBad) && tu->vid != UNDEFVID) {
-               if (tu->ct.EndTimestamp < now) {
+           if ((tu->states & UHasTokens) && !(tu->states & UTokensBad)) {
+               if (!afs_HasUsableTokens(tu->tokens, now)) {
                    /*
                     * This token has expired, warn users and reset access
                     * cache.
                     */
-#ifdef notdef
-                   /* I really hate this message - MLK */
-                   afs_warn
-                       ("afs: Tokens for user of AFS id %d for cell %s expired now\n",
-                        tu->vid, afs_GetCell(tu->cell)->cellName);
-#endif
                    tu->states |= (UTokensBad | UNeedsReset);
                }
            }
@@ -203,15 +161,14 @@ afs_CheckTokenCache(void)
     }
     ReleaseReadLock(&afs_xuser);
     ReleaseReadLock(&afs_xvcache);
-
 }                              /*afs_CheckTokenCache */
 
 
 void
 afs_ResetAccessCache(afs_int32 uid, int alock)
 {
-    register int i;
-    register struct vcache *tvc;
+    int i;
+    struct vcache *tvc;
     struct axscache *ac;
 
     AFS_STATCNT(afs_ResetAccessCache);
@@ -237,11 +194,11 @@ afs_ResetAccessCache(afs_int32 uid, int alock)
  * access info.
  */
 void
-afs_ResetUserConns(register struct unixuser *auser)
+afs_ResetUserConns(struct unixuser *auser)
 {
-    int i;
+    int i, j;
     struct srvAddr *sa;
-    struct afs_conn *tc;
+    struct sa_conn_vector *tcv;
 
     AFS_STATCNT(afs_ResetUserConns);
     ObtainReadLock(&afs_xsrvAddr);
@@ -249,9 +206,11 @@ afs_ResetUserConns(register struct unixuser *auser)
 
     for (i = 0; i < NSERVERS; i++) {
        for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
-           for (tc = sa->conns; tc; tc = tc->next) {
-               if (tc->user == auser) {
-                   tc->forceConnectFS = 1;
+           for (tcv = sa->conns; tcv; tcv = tcv->next) {
+               if (tcv->user == auser) {
+                   for(j = 0; j < CVEC_LEN; ++j) {
+                       (tcv->cvec[j]).forceConnectFS = 1;
+                   }
                }
            }
        }
@@ -268,8 +227,8 @@ afs_ResetUserConns(register struct unixuser *auser)
 struct unixuser *
 afs_FindUser(afs_int32 auid, afs_int32 acell, afs_int32 locktype)
 {
-    register struct unixuser *tu;
-    register afs_int32 i;
+    struct unixuser *tu;
+    afs_int32 i;
 
     AFS_STATCNT(afs_FindUser);
     i = UHash(auid);
@@ -278,6 +237,7 @@ afs_FindUser(afs_int32 auid, afs_int32 acell, afs_int32 locktype)
        if (tu->uid == auid && ((tu->cell == acell) || (acell == -1))) {
            tu->refCount++;
            ReleaseWriteLock(&afs_xuser);
+           afs_LockUser(tu, locktype, 365);
            return tu;
        }
     }
@@ -312,9 +272,9 @@ afs_FindUser(afs_int32 auid, afs_int32 acell, afs_int32 locktype)
 void
 afs_ComputePAGStats(void)
 {
-    register struct unixuser *currPAGP;        /*Ptr to curr PAG */
-    register struct unixuser *cmpPAGP; /*Ptr to PAG being compared */
-    register struct afs_stats_AuthentInfo *authP;      /*Ptr to stats area */
+    struct unixuser *currPAGP; /*Ptr to curr PAG */
+    struct unixuser *cmpPAGP;  /*Ptr to PAG being compared */
+    struct afs_stats_AuthentInfo *authP;       /*Ptr to stats area */
     int curr_Record;           /*Curr record */
     int currChain;             /*Curr hash chain */
     int currChainLen;          /*Length of curr hash chain */
@@ -353,7 +313,7 @@ afs_ComputePAGStats(void)
             * We've found a previously-uncounted PAG.  If it's been deleted
             * but just not garbage-collected yet, we step over it.
             */
-           if (currPAGP->vid == UNDEFVID)
+           if (!(currPAGP->states & UHasTokens))
                continue;
 
            /*
@@ -445,11 +405,11 @@ afs_ComputePAGStats(void)
 
 
 struct unixuser *
-afs_GetUser(register afs_int32 auid, afs_int32 acell, afs_int32 locktype)
+afs_GetUser(afs_int32 auid, afs_int32 acell, afs_int32 locktype)
 {
-    register struct unixuser *tu, *pu = 0;
-    register afs_int32 i;
-    register afs_int32 RmtUser = 0;
+    struct unixuser *tu, *pu = 0;
+    afs_int32 i;
+    afs_int32 RmtUser = 0;
 
     AFS_STATCNT(afs_GetUser);
     i = UHash(auid);
@@ -466,20 +426,20 @@ afs_GetUser(register afs_int32 auid, afs_int32 acell, afs_int32 locktype)
                /* Here we setup the real cell for the client */
                tu->cell = acell;
                tu->refCount++;
-               ReleaseWriteLock(&afs_xuser);
-               return tu;
+               goto done;
            } else if (tu->cell == acell || acell == -1) {
                tu->refCount++;
-               ReleaseWriteLock(&afs_xuser);
-               return tu;
+               goto done;
            }
        }
     }
-    tu = (struct unixuser *)afs_osi_Alloc(sizeof(struct unixuser));
+    tu = afs_osi_Alloc(sizeof(struct unixuser));
+    osi_Assert(tu != NULL);
 #ifndef AFS_NOSTATS
     afs_stats_cmfullperf.authent.PAGCreations++;
 #endif /* AFS_NOSTATS */
     memset(tu, 0, sizeof(struct unixuser));
+    AFS_RWLOCK_INIT(&tu->lock, "unixuser lock");
     tu->next = afs_users[i];
     afs_users[i] = tu;
     if (RmtUser) {
@@ -490,24 +450,63 @@ afs_GetUser(register afs_int32 auid, afs_int32 acell, afs_int32 locktype)
         * structure
         */
        if (pu && pu->exporter) {
-           (void)EXP_HOLD(tu->exporter = pu->exporter);
+           tu->exporter = pu->exporter;
+           (void)EXP_HOLD(tu->exporter);
        }
     }
     tu->uid = auid;
     tu->cell = acell;
-    tu->vid = UNDEFVID;
+    tu->viceId = UNDEFVID;
     tu->refCount = 1;
     tu->tokenTime = osi_Time();
+
+ done:
     ReleaseWriteLock(&afs_xuser);
+    afs_LockUser(tu, locktype, 364);
     return tu;
 
 }                              /*afs_GetUser */
 
+void
+afs_LockUser(struct unixuser *au, afs_int32 locktype,
+             unsigned int src_indicator)
+{
+    switch (locktype) {
+    case READ_LOCK:
+       ObtainReadLock(&au->lock);
+       break;
+    case WRITE_LOCK:
+       ObtainWriteLock(&au->lock, src_indicator);
+       break;
+    case SHARED_LOCK:
+       ObtainSharedLock(&au->lock, src_indicator);
+       break;
+    default:
+       /* noop */
+       break;
+    }
+}
 
 void
-afs_PutUser(register struct unixuser *au, afs_int32 locktype)
+afs_PutUser(struct unixuser *au, afs_int32 locktype)
 {
     AFS_STATCNT(afs_PutUser);
+
+    switch (locktype) {
+    case READ_LOCK:
+       ReleaseReadLock(&au->lock);
+       break;
+    case WRITE_LOCK:
+       ReleaseWriteLock(&au->lock);
+       break;
+    case SHARED_LOCK:
+       ReleaseSharedLock(&au->lock);
+       break;
+    default:
+       /* noop */
+       break;
+    }
+
     --au->refCount;
 }                              /*afs_PutUser */
 
@@ -517,10 +516,10 @@ afs_PutUser(register struct unixuser *au, afs_int32 locktype)
  * dude has the flag set at any time for a particular unix uid.
  */
 void
-afs_SetPrimary(register struct unixuser *au, register int aflag)
+afs_SetPrimary(struct unixuser *au, int aflag)
 {
-    register struct unixuser *tu;
-    register int i;
+    struct unixuser *tu;
+    int i;
     struct unixuser *pu;
 
     AFS_STATCNT(afs_SetPrimary);
@@ -561,11 +560,43 @@ afs_SetPrimary(register struct unixuser *au, register int aflag)
 
 }                              /*afs_SetPrimary */
 
+void
+afs_NotifyUser(struct unixuser *auser, int event)
+{
+#ifdef AFS_DARWIN_ENV
+    darwin_notify_perms(auser, event);
+#endif
+}
+
+/**
+ * Mark all of the unixuser records held for a particular PAG as
+ * expired
+ *
+ * @param[in] pag
+ *     PAG to expire records for
+ */
+void
+afs_MarkUserExpired(afs_int32 pag)
+{
+    afs_int32 i;
+    struct unixuser *tu;
+
+    i = UHash(pag);
+    ObtainWriteLock(&afs_xuser, 9);
+    for (tu = afs_users[i]; tu; tu = tu->next) {
+       if (tu->uid == pag) {
+           tu->states &= ~UHasTokens;
+           tu->tokenTime = 0;
+       }
+    }
+    ReleaseWriteLock(&afs_xuser);
+}
+
 
 #if AFS_GCPAGS
 
 /*
- * Called by osi_TraverseProcTable (from afs_GCPAGs) for each 
+ * Called by osi_TraverseProcTable (from afs_GCPAGs) for each
  * process in the system.
  * If the specified process uses a PAG, clear that PAG's temporary
  * 'deleteme' flag.
@@ -591,7 +622,7 @@ static size_t afs_GCPAGs_cred_count = 0;
 /*
  * LOCKS: afs_GCPAGs_perproc_func requires write lock on afs_xuser
  */
-#if !defined(LINUX_KEYRING_SUPPORT) && (!defined(STRUCT_TASK_HAS_CRED) || defined(EXPORTED_RCU_READ_LOCK))
+#if !defined(LINUX_KEYRING_SUPPORT) && (!defined(STRUCT_TASK_STRUCT_HAS_CRED) || defined(HAVE_LINUX_RCU_READ_LOCK))
 void
 afs_GCPAGs_perproc_func(afs_proc_t * pproc)
 {
@@ -607,21 +638,21 @@ afs_GCPAGs_perproc_func(afs_proc_t * pproc)
     afs_GCPAGs_cred_count++;
 
     pag = PagInCred(pcred);
-#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD40_ENV) || defined(AFS_LINUX22_ENV)
-    uid = (pag != NOPAG ? pag : pcred->cr_uid);
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_LINUX22_ENV)
+    uid = (pag != NOPAG ? pag : afs_cr_uid(pcred));
 #elif defined(AFS_SUN510_ENV)
     uid = (pag != NOPAG ? pag : crgetruid(pcred));
 #else
-    uid = (pag != NOPAG ? pag : pcred->cr_ruid);
+    uid = (pag != NOPAG ? pag : afs_cr_ruid(pcred));
 #endif
     hash = UHash(uid);
 
-    /* if this token is PAG based, or it's UID based and 
+    /* if this token is PAG based, or it's UID based and
      * UID-based tokens exist */
     if ((pag != NOPAG) || (afs_GCPAGs_UIDBaseTokenCount)) {
        /* find the entries for this uid in all cells and clear the not
         * referenced flag.  Can't use afs_FindUser, because it just returns
-        * the specific cell asked for, or the first one found. 
+        * the specific cell asked for, or the first one found.
         */
        struct unixuser *pu;
        for (pu = afs_users[hash]; pu; pu = pu->next) {
@@ -630,7 +661,7 @@ afs_GCPAGs_perproc_func(afs_proc_t * pproc)
                    /* clear the 'deleteme' flag for this entry */
                    pu->states &= ~TMP_UPAGNotReferenced;
                    if (pag == NOPAG) {
-                       /* This is a uid based token that hadn't 
+                       /* This is a uid based token that hadn't
                         * previously been cleared, so decrement the
                         * outstanding uid based token count */
                        afs_GCPAGs_UIDBaseTokenCount--;
@@ -643,7 +674,7 @@ afs_GCPAGs_perproc_func(afs_proc_t * pproc)
 #endif
 
 /*
- * Go through the process table, find all unused PAGs 
+ * Go through the process table, find all unused PAGs
  * and cause them to be deleted during the next GC.
  *
  * returns the number of PAGs marked for deletion
@@ -681,7 +712,7 @@ afs_GCPAGs(afs_int32 * ReleasedCount)
        }
     }
 
-    /* Now, iterate through the systems process table, 
+    /* Now, iterate through the systems process table,
      * for each process, mark it's PAGs (if any) in use.
      * i.e. clear the temporary deleteme flag.
      */
@@ -717,10 +748,8 @@ afs_GCPAGs(afs_int32 * ReleasedCount)
                 * i.e. nfs translator, etc.
                 */
                if (!pu->exporter && afs_gcpags == AFS_GCPAGS_OK) {
-                   /* set the expire times to 0, causes 
-                    * afs_GCUserData to remove this entry 
-                    */
-                   pu->ct.EndTimestamp = 0;
+                   /* make afs_GCUserData remove this entry  */
+                   pu->states &= ~UHasTokens;
                    pu->tokenTime = 0;
 
                    (*ReleasedCount)++; /* remember how many we marked (info only) */