Index: openafs/src/WINNT/afsd/afsd_service.c
diff -c openafs/src/WINNT/afsd/afsd_service.c:1.52.4.19 openafs/src/WINNT/afsd/afsd_service.c:1.52.4.21
*** openafs/src/WINNT/afsd/afsd_service.c:1.52.4.19	Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/afsd_service.c	Sun Jan  6 01:26:04 2008
***************
*** 250,255 ****
--- 250,260 ----
      {
      case SERVICE_CONTROL_SHUTDOWN:
      case SERVICE_CONTROL_STOP:
+ 	if (ctrlCode == SERVICE_CONTROL_SHUTDOWN)
+ 	    afsi_log("SERVICE_CONTROL_SHUTDOWN");
+ 	else
+             afsi_log("SERVICE_CONTROL_STOP");
+ 
          ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
          ServiceStatus.dwWin32ExitCode = NO_ERROR;
          ServiceStatus.dwCheckPoint = 1;
***************
*** 1000,1006 ****
          RegCloseKey (parmKey);
      }
  
!     if (verifyServiceSig && cacheSize < 716800) {
          trustVerified = VerifyTrust(filename);
      } else {
          afsi_log("Signature Verification disabled");
--- 1005,1015 ----
          RegCloseKey (parmKey);
      }
  
!     if (verifyServiceSig 
! #ifndef _WIN64
!          && cacheSize < 716800
! #endif
!          ) {
          trustVerified = VerifyTrust(filename);
      } else {
          afsi_log("Signature Verification disabled");
Index: openafs/src/WINNT/afsd/cm_daemon.c
diff -c openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.21 openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.22
*** openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.21	Mon Dec 24 00:24:14 2007
--- openafs/src/WINNT/afsd/cm_daemon.c	Sat Jan  5 12:56:29 2008
***************
*** 74,79 ****
--- 74,80 ----
          thrd_SetEvent(cm_IPAddrDaemon_ShutdownEvent);
          Result = NotifyAddrChange(NULL,NULL);
          if (Result == NO_ERROR && daemon_ShutdownFlag == 0) {
+             smb_LanAdapterChange();
              thrd_ResetEvent(cm_IPAddrDaemon_ShutdownEvent);
  	    Sleep(2500);
              if (daemon_ShutdownFlag == 0) {
Index: openafs/src/WINNT/afsd/cm_dcache.c
diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.23 openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.24
*** openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.23	Fri Dec 28 02:26:00 2007
--- openafs/src/WINNT/afsd/cm_dcache.c	Mon Jan  7 12:56:37 2008
***************
*** 688,719 ****
          
      osi_Log3(afsd_logp, "Starting BKG prefetch scp 0x%p, base 0x%x:%x", scp, p2, p1);
  
!     for (code = 0, offset = base;
            code == 0 && LargeIntegerLessThan(offset, end); 
!           offset = LargeIntegerAdd(offset, tblocksize))
      {
          if (mxheld) {
              lock_ReleaseMutex(&scp->mx);
              mxheld = 0;
          }
          code = buf_Get(scp, &offset, &bp);
          if (!mxheld) {
              lock_ObtainMutex(&scp->mx);
              mxheld = 1;
          }
  
-         if (code || (bp->cmFlags & CM_BUF_CMFETCHING)) {
-             code = 0;
-             if (bp) {
-                 buf_Release(bp);
-                 bp = NULL;
-             }
-             break;
-         }
- 
          code = cm_GetBuffer(scp, bp, NULL, userp, &req);
          if (code == 0)
              fetched = LargeIntegerAdd(fetched, tblocksize); 
      }
      
      if (!mxheld) {
--- 688,721 ----
          
      osi_Log3(afsd_logp, "Starting BKG prefetch scp 0x%p, base 0x%x:%x", scp, p2, p1);
  
!     for ( code = 0, offset = base;
            code == 0 && LargeIntegerLessThan(offset, end); 
!           offset = LargeIntegerAdd(offset, tblocksize) )
      {
          if (mxheld) {
              lock_ReleaseMutex(&scp->mx);
              mxheld = 0;
          }
          code = buf_Get(scp, &offset, &bp);
+         if (code)
+             break;
+ 
+         if (bp->cmFlags & CM_BUF_CMFETCHING) {
+             /* skip this buffer as another thread is already fetching it */
+             buf_Release(bp);
+             bp = NULL;
+             continue;
+         }
+ 
          if (!mxheld) {
              lock_ObtainMutex(&scp->mx);
              mxheld = 1;
          }
  
          code = cm_GetBuffer(scp, bp, NULL, userp, &req);
          if (code == 0)
              fetched = LargeIntegerAdd(fetched, tblocksize); 
+         buf_Release(bp);
      }
      
      if (!mxheld) {
***************
*** 723,732 ****
      cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code, 
                           scp, &base, &fetched);
      lock_ReleaseMutex(&scp->mx);
-     if (bp) {
-         buf_Release(bp);
-         bp = NULL;
-     }
  
      osi_Log4(afsd_logp, "Ending BKG prefetch scp 0x%p, code %d bytes 0x%x:%x", 
                scp, code, fetched.HighPart, fetched.LowPart);
--- 725,730 ----
Index: openafs/src/WINNT/afsd/cm_ioctl.c
diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.28 openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.29
*** openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.28	Sat Dec 22 22:44:58 2007
--- openafs/src/WINNT/afsd/cm_ioctl.c	Fri Jan  4 02:58:40 2008
***************
*** 2989,2991 ****
--- 2989,3093 ----
  }       
  
  
+ long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
+ {
+     long code;
+     cm_cell_t *cellp = NULL;
+     cm_volume_t *volp;
+     cm_vol_state_t *statep;
+     struct VolStatTest * testp;
+     cm_req_t req;
+     afs_uint32 n;
+     size_t len;
+ 
+     cm_InitReq(&req);
+ 
+     cm_SkipIoctlPath(ioctlp);	/* we don't care about the path */
+     testp = (struct VolStatTest *)ioctlp->inDatap;
+ 
+ #ifdef AFS_FREELANCE_CLIENT
+     if (testp->fid.cell == -1) 
+         return CM_ERROR_NOACCESS;
+ #endif
+ 
+     if (testp->flags & VOLSTAT_TEST_CHECK_VOLUME) {
+         cm_CheckOfflineVolumes();
+         return 0;
+     }
+ 
+     if (testp->flags & VOLSTAT_TEST_NETWORK_UP) {
+         cm_VolStatus_Network_Started(cm_NetbiosName
+ #ifdef _WIN64
+                                   , cm_NetbiosName
+ #endif
+                                   );
+         return 0;
+     }
+ 
+     if (testp->flags & VOLSTAT_TEST_NETWORK_DOWN) {
+         cm_VolStatus_Network_Stopped(cm_NetbiosName
+ #ifdef _WIN64
+                                   , cm_NetbiosName
+ #endif
+                                   );
+         return 0;
+     }
+ 
+     if (testp->cellname[0]) {
+         n = atoi(testp->cellname);
+         if (n)
+             testp->fid.cell = n;
+         else
+             cellp = cm_GetCell(testp->cellname, 0);
+     }
+ 
+     if (testp->fid.cell > 0) {
+         cellp = cm_FindCellByID(testp->fid.cell);
+     }
+ 
+     if (!cellp)
+         return CM_ERROR_NOSUCHCELL;
+ 
+     if (testp->volname[0]) {
+         n = atoi(testp->volname);
+         if (n)
+             testp->fid.volume = n;
+         else
+             code = cm_GetVolumeByName(cellp, testp->volname, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
+     }
+ 
+     if (testp->fid.volume > 0)
+         code = cm_GetVolumeByID(cellp, testp->fid.volume, userp, &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
+ 
+     if (code)
+         return code;
+ 	
+     if (testp->fid.volume) {
+         if (testp->fid.volume == volp->rw.ID)
+             statep = &volp->rw;
+         else if (testp->fid.volume == volp->ro.ID)
+             statep = &volp->ro;
+         else
+             statep = &volp->bk;
+     } else {
+         len = strlen(testp->volname);
+ 
+         if (stricmp(".readonly", &testp->volname[len-9]) == 0)
+             statep = &volp->ro;
+         else if (stricmp(".backup", &testp->volname[len-7]) == 0)
+             statep = &volp->bk;
+         else 
+             statep = &volp->rw;
+     }
+ 
+     if (statep) {
+         statep->state = testp->state;
+         code = cm_VolStatus_Change_Notification(cellp->cellID, statep->ID, testp->state);
+     }
+ 
+     cm_PutVolume(volp);
+ 
+     return code;
+ }       
+ 
+ 
Index: openafs/src/WINNT/afsd/cm_ioctl.h
diff -c openafs/src/WINNT/afsd/cm_ioctl.h:1.14.2.3 openafs/src/WINNT/afsd/cm_ioctl.h:1.14.2.4
*** openafs/src/WINNT/afsd/cm_ioctl.h:1.14.2.3	Tue May 15 16:20:55 2007
--- openafs/src/WINNT/afsd/cm_ioctl.h	Fri Jan  4 02:58:40 2008
***************
*** 171,176 ****
--- 171,178 ----
  
  extern long cm_IoctlPathAvailability(struct smb_ioctl * ioctlp, struct cm_user *userp);
  
+ extern long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp);
+ 
  #endif /* __CM_IOCTL_INTERFACES_ONLY__ */
  
  #endif /*  __CM_IOCTL_H_ENV__ */
Index: openafs/src/WINNT/afsd/cm_memmap.c
diff -c openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.7 openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.8
*** openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.7	Fri Aug 10 16:39:26 2007
--- openafs/src/WINNT/afsd/cm_memmap.c	Wed Jan  2 10:55:00 2008
***************
*** 234,253 ****
  
      afsi_log("Closing AFS Cache:");
      afsi_log("  Base Address   = %p", config_data_p);
!     afsi_log("  stats          = %d", cm_data.stats);
!     afsi_log("  chunkSize      = %d", cm_data.chunkSize);
!     afsi_log("  blockSize      = %d", cm_data.blockSize);
!     afsi_log("  bufferSize     = %d", cm_data.bufferSize);
!     afsi_log("  cacheType      = %d", cm_data.cacheType);
!     afsi_log("  volumeHashTableSize = %d", cm_data.volumeHashTableSize);
!     afsi_log("  currentVolumes = %d", cm_data.currentVolumes);
!     afsi_log("  maxVolumes     = %d", cm_data.maxVolumes);
!     afsi_log("  cellHashTableSize = %d", cm_data.cellHashTableSize);
!     afsi_log("  currentCells   = %d", cm_data.currentCells);
!     afsi_log("  maxCells       = %d", cm_data.maxCells);
!     afsi_log("  scacheHashTableSize  = %d", cm_data.scacheHashTableSize);
!     afsi_log("  currentSCaches = %d", cm_data.currentSCaches);
!     afsi_log("  maxSCaches     = %d", cm_data.maxSCaches);
  
      cm_ShutdownDCache();
      cm_ShutdownSCache();
--- 234,253 ----
  
      afsi_log("Closing AFS Cache:");
      afsi_log("  Base Address   = %p", config_data_p);
!     afsi_log("  stats          = %u", cm_data.stats);
!     afsi_log("  chunkSize      = %u", cm_data.chunkSize);
!     afsi_log("  blockSize      = %u", cm_data.blockSize);
!     afsi_log("  bufferSize     = %I64u", cm_data.bufferSize);
!     afsi_log("  cacheType      = %u", cm_data.cacheType);
!     afsi_log("  volumeHashTableSize = %u", cm_data.volumeHashTableSize);
!     afsi_log("  currentVolumes = %u", cm_data.currentVolumes);
!     afsi_log("  maxVolumes     = %u", cm_data.maxVolumes);
!     afsi_log("  cellHashTableSize = %u", cm_data.cellHashTableSize);
!     afsi_log("  currentCells   = %u", cm_data.currentCells);
!     afsi_log("  maxCells       = %u", cm_data.maxCells);
!     afsi_log("  scacheHashTableSize  = %u", cm_data.scacheHashTableSize);
!     afsi_log("  currentSCaches = %u", cm_data.currentSCaches);
!     afsi_log("  maxSCaches     = %u", cm_data.maxSCaches);
  
      cm_ShutdownDCache();
      cm_ShutdownSCache();
***************
*** 419,438 ****
  
      fprintf(stderr,"AFS Cache data:\n");
      fprintf(stderr,"  Base Address   = %p\n",baseAddress);
!     fprintf(stderr,"  stats          = %d\n", config_data_p->stats);
!     fprintf(stderr,"  chunkSize      = %d\n", config_data_p->chunkSize);
!     fprintf(stderr,"  blockSize      = %d\n", config_data_p->blockSize);
!     fprintf(stderr,"  bufferSize     = %d\n", config_data_p->bufferSize);
!     fprintf(stderr,"  cacheType      = %d\n", config_data_p->cacheType);
!     fprintf(stderr,"  volumeHashTableSize = %d", config_data_p->volumeHashTableSize);
!     fprintf(stderr,"  currentVolumes = %d\n", config_data_p->currentVolumes);
!     fprintf(stderr,"  maxVolumes     = %d\n", config_data_p->maxVolumes);
!     fprintf(stderr,"  cellHashTableSize = %d", config_data_p->cellHashTableSize);
!     fprintf(stderr,"  currentCells   = %d\n", config_data_p->currentCells);
!     fprintf(stderr,"  maxCells       = %d\n", config_data_p->maxCells);
!     fprintf(stderr,"  scacheHashTableSize  = %d\n", config_data_p->scacheHashTableSize);
!     fprintf(stderr,"  currentSCaches = %d\n", config_data_p->currentSCaches);
!     fprintf(stderr,"  maxSCaches     = %d\n", config_data_p->maxSCaches);
      cm_data = *config_data_p;      
  
      // perform validation of persisted data structures
--- 419,438 ----
  
      fprintf(stderr,"AFS Cache data:\n");
      fprintf(stderr,"  Base Address   = %p\n",baseAddress);
!     fprintf(stderr,"  stats          = %u\n", config_data_p->stats);
!     fprintf(stderr,"  chunkSize      = %u\n", config_data_p->chunkSize);
!     fprintf(stderr,"  blockSize      = %u\n", config_data_p->blockSize);
!     fprintf(stderr,"  bufferSize     = %I64u\n", config_data_p->bufferSize);
!     fprintf(stderr,"  cacheType      = %u\n", config_data_p->cacheType);
!     fprintf(stderr,"  volumeHashTableSize = %u", config_data_p->volumeHashTableSize);
!     fprintf(stderr,"  currentVolumes = %u\n", config_data_p->currentVolumes);
!     fprintf(stderr,"  maxVolumes     = %u\n", config_data_p->maxVolumes);
!     fprintf(stderr,"  cellHashTableSize = %u", config_data_p->cellHashTableSize);
!     fprintf(stderr,"  currentCells   = %u\n", config_data_p->currentCells);
!     fprintf(stderr,"  maxCells       = %u\n", config_data_p->maxCells);
!     fprintf(stderr,"  scacheHashTableSize  = %u\n", config_data_p->scacheHashTableSize);
!     fprintf(stderr,"  currentSCaches = %u\n", config_data_p->currentSCaches);
!     fprintf(stderr,"  maxSCaches     = %u\n", config_data_p->maxSCaches);
      cm_data = *config_data_p;      
  
      // perform validation of persisted data structures
***************
*** 820,839 ****
          cm_data = *config_data_p;      
  
  	afsi_log("  Base Address   = %p",baseAddress);
! 	afsi_log("  stats          = %d", config_data_p->stats);
! 	afsi_log("  chunkSize      = %d", config_data_p->chunkSize);
! 	afsi_log("  blockSize      = %d", config_data_p->blockSize);
! 	afsi_log("  bufferSize     = %d", config_data_p->bufferSize);
! 	afsi_log("  cacheType      = %d", config_data_p->cacheType);
! 	afsi_log("  volumeHashTableSize  = %d", config_data_p->volumeHashTableSize);
! 	afsi_log("  currentVolumes = %d", config_data_p->currentVolumes);
! 	afsi_log("  maxVolumes     = %d", config_data_p->maxVolumes);
!         afsi_log("  cellHashTableSize = %d", config_data_p->cellHashTableSize);
! 	afsi_log("  currentCells   = %d", config_data_p->currentCells);
! 	afsi_log("  maxCells       = %d", config_data_p->maxCells);
! 	afsi_log("  scacheHashTableSize  = %d", config_data_p->scacheHashTableSize);
! 	afsi_log("  currentSCaches = %d", config_data_p->currentSCaches);
! 	afsi_log("  maxSCaches     = %d", config_data_p->maxSCaches);
  
          // perform validation of persisted data structures
          // if there is a failure, start from scratch
--- 820,839 ----
          cm_data = *config_data_p;      
  
  	afsi_log("  Base Address   = %p",baseAddress);
! 	afsi_log("  stats          = %u", config_data_p->stats);
! 	afsi_log("  chunkSize      = %u", config_data_p->chunkSize);
! 	afsi_log("  blockSize      = %u", config_data_p->blockSize);
! 	afsi_log("  bufferSize     = %I64u", config_data_p->bufferSize);
! 	afsi_log("  cacheType      = %u", config_data_p->cacheType);
! 	afsi_log("  volumeHashTableSize  = %u", config_data_p->volumeHashTableSize);
! 	afsi_log("  currentVolumes = %u", config_data_p->currentVolumes);
! 	afsi_log("  maxVolumes     = %u", config_data_p->maxVolumes);
!         afsi_log("  cellHashTableSize = %u", config_data_p->cellHashTableSize);
! 	afsi_log("  currentCells   = %u", config_data_p->currentCells);
! 	afsi_log("  maxCells       = %u", config_data_p->maxCells);
! 	afsi_log("  scacheHashTableSize  = %u", config_data_p->scacheHashTableSize);
! 	afsi_log("  currentSCaches = %u", config_data_p->currentSCaches);
! 	afsi_log("  maxSCaches     = %u", config_data_p->maxSCaches);
  
          // perform validation of persisted data structures
          // if there is a failure, start from scratch
Index: openafs/src/WINNT/afsd/cm_server.c
diff -c openafs/src/WINNT/afsd/cm_server.c:1.25.2.16 openafs/src/WINNT/afsd/cm_server.c:1.25.2.17
*** openafs/src/WINNT/afsd/cm_server.c:1.25.2.16	Mon Dec 24 00:30:37 2007
--- openafs/src/WINNT/afsd/cm_server.c	Sun Jan  6 18:12:59 2008
***************
*** 138,145 ****
--- 138,147 ----
                      if (tsrvp->ids[i] != 0) {
                          cm_InitReq(&req);
  
+                         lock_ReleaseMutex(&tsp->mx);
                          code = cm_GetVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
                                                  &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
+                         lock_ObtainMutex(&tsp->mx);
                          if (code == 0) {
                              cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
                              cm_PutVolume(volp);
Index: openafs/src/WINNT/afsd/cm_vnodeops.c
diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.49 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.50
*** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.49	Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/cm_vnodeops.c	Sat Jan  5 17:20:30 2008
***************
*** 1140,1148 ****
           * volume for the target, then use the .backup of the target
           * instead of the read-write.
           */
!         if (cm_followBackupPath && targetType == RWVOL &&
!             (scp->flags & CM_SCACHEFLAG_RO|CM_SCACHEFLAG_PURERO) == CM_SCACHEFLAG_RO &&
!             volp->bk.ID != 0) {
              targetType = BACKVOL;
          } 
          /* if the mt pt is in a read-only volume (not just a
--- 1140,1150 ----
           * volume for the target, then use the .backup of the target
           * instead of the read-write.
           */
!         if (cm_followBackupPath && 
!             volp->bk.ID != 0 &&
!             (dscp->flags & (CM_SCACHEFLAG_RO|CM_SCACHEFLAG_PURERO)) == CM_SCACHEFLAG_RO &&
!             (targetType == RWVOL || targetType == ROVOL && volp->ro.ID == 0)
!             ) {
              targetType = BACKVOL;
          } 
          /* if the mt pt is in a read-only volume (not just a
Index: openafs/src/WINNT/afsd/cm_volstat.h
diff -c openafs/src/WINNT/afsd/cm_volstat.h:1.1.2.5 openafs/src/WINNT/afsd/cm_volstat.h:1.1.2.6
*** openafs/src/WINNT/afsd/cm_volstat.h:1.1.2.5	Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/cm_volstat.h	Fri Jan  4 02:58:40 2008
***************
*** 88,90 ****
--- 88,104 ----
      long (__fastcall * cm_VolStatus_Path_To_DFSlink)(const char * share, const char * path, afs_uint32 *pBufSize, char *pBuffer);
  } cm_VolStatus_Funcs_t;
  
+ /* pioctl */
+ struct VolStatTest {
+     afs_uint32  flags;
+     cm_fid_t    fid;
+     char cellname[CELL_MAXNAMELEN];
+     char volname[VL_MAXNAMELEN];
+     enum volstatus state;
+ };
+ 
+ #define VOLSTAT_TEST_APPLY_TO_SERVER 1
+ #define VOLSTAT_TEST_CHECK_VOLUME    2
+ #define VOLSTAT_TEST_NETWORK_UP      4
+ #define VOLSTAT_TEST_NETWORK_DOWN    8
+ 
Index: openafs/src/WINNT/afsd/cm_volume.c
diff -c openafs/src/WINNT/afsd/cm_volume.c:1.14.4.22 openafs/src/WINNT/afsd/cm_volume.c:1.14.4.23
*** openafs/src/WINNT/afsd/cm_volume.c:1.14.4.22	Mon Dec 24 00:19:09 2007
--- openafs/src/WINNT/afsd/cm_volume.c	Fri Jan  4 02:44:40 2008
***************
*** 1035,1040 ****
--- 1035,1044 ----
              cm_VolumeStatusNotification(volp, volp->rw.ID, volp->rw.state, vl_online);
              volp->rw.state = vl_online;
              online = 1;
+         } else if (code == CM_ERROR_NOACCESS) {
+             cm_VolumeStatusNotification(volp, volp->rw.ID, volp->rw.state, vl_unknown);
+             volp->rw.state = vl_unknown;
+             online = 1;
          }
      }
  
***************
*** 1064,1069 ****
--- 1068,1077 ----
              cm_VolumeStatusNotification(volp, volp->ro.ID, volp->ro.state, vl_online);
              volp->ro.state = vl_online;
              online = 1;
+         } else if (code == CM_ERROR_NOACCESS) {
+             cm_VolumeStatusNotification(volp, volp->ro.ID, volp->ro.state, vl_unknown);
+             volp->ro.state = vl_unknown;
+             online = 1;
          }
      }
  
***************
*** 1093,1098 ****
--- 1101,1110 ----
              cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_online);
              volp->bk.state = vl_online;
              online = 1;
+         } else if (code == CM_ERROR_NOACCESS) {
+             cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_unknown);
+             volp->bk.state = vl_unknown;
+             online = 1;
          }
      }
  
Index: openafs/src/WINNT/afsd/fs.c
diff -c openafs/src/WINNT/afsd/fs.c:1.32.4.14 openafs/src/WINNT/afsd/fs.c:1.32.4.16
*** openafs/src/WINNT/afsd/fs.c:1.32.4.14	Wed Oct 31 00:09:17 2007
--- openafs/src/WINNT/afsd/fs.c	Fri Jan  4 02:58:40 2008
***************
*** 1489,1495 ****
      struct cmd_item *ti;
      struct VolumeStatus *status;
      char *name, *offmsg, *motd;
-     long   online_state;
      int error = 0;
      
      SetDotDefault(&as->parms[0].items);
--- 1489,1494 ----
***************
*** 1540,1561 ****
          } else {
              Die(errno, ti->data);
          }
!         online_state = pioctl(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1);
!         switch (online_state) {
          case 0:
              printf("Volume is online\n");
              break;
!         case CM_ERROR_ALLOFFLINE:
!             printf("Volume offline\n");
              break;
!         case CM_ERROR_ALLDOWN:
              printf("All Volume servers are down\n");
              break;
!         case CM_ERROR_ALLBUSY:
              printf("All volume servers are busy\n");
              break;
          default:
!             Die(online_state, ti->data);
          }
          printf("\n");
      }
--- 1539,1563 ----
          } else {
              Die(errno, ti->data);
          }
! 
!         errno = 0;
!         code = pioctl(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1);
!         switch (errno) {
          case 0:
              printf("Volume is online\n");
              break;
!         case ENXIO:
!             printf("Volume is offline\n");
              break;
!         case ENOSYS:
              printf("All Volume servers are down\n");
              break;
!         case EBUSY:
              printf("All volume servers are busy\n");
              break;
          default:
!             printf("Unknown volume state\n");
!             Die(errno, ti->data);
          }
          printf("\n");
      }
***************
*** 4314,4319 ****
--- 4316,4401 ----
      return 0;
  }
  
+ static int
+ TestVolStatCmd(struct cmd_syndesc *as, void *arock)
+ {
+     afs_int32 code;
+     struct VolStatTest test;
+     struct ViceIoctl blob;
+     char * tp;
+     afs_uint32 n;
+ 
+     memset(&test, 0, sizeof(test));
+ 
+     if (as->parms[0].items) {	/* -network */
+         tp = as->parms[0].items->data;
+         if (strcmp(tp, "up") == 0)
+             test.flags |= VOLSTAT_TEST_NETWORK_UP;
+         else if (strcmp(tp, "down") == 0)
+             test.flags |= VOLSTAT_TEST_NETWORK_DOWN;
+         else {
+             fprintf (stderr, "%s: %s must be \"up\" or \"down\".\n", pn, tp);
+             return EINVAL;
+         }
+     }
+     if (as->parms[1].items) {	/* check */
+         test.flags |= VOLSTAT_TEST_CHECK_VOLUME;
+     }
+     if (as->parms[2].items) {	/* cell */
+         tp = as->parms[2].items->data;
+         n = atoi(tp);
+         if (n != 0)
+             test.fid.cell = n;
+         else {
+             strncpy(test.cellname, tp, sizeof(test.cellname));
+             test.cellname[sizeof(test.cellname)-1] = '\0';
+         }
+     }
+     if (as->parms[3].items) {	/* volume */
+         tp = as->parms[3].items->data;
+         n = atoi(tp);
+         if (n != 0)
+             test.fid.volume = n;
+         else {
+             strncpy(test.volname, tp, sizeof(test.volname));
+             test.volname[sizeof(test.volname)-1] = '\0';
+         }
+     }
+     if (as->parms[4].items) {   /* state */
+         tp = as->parms[4].items->data;
+         if (strcmp(tp, "online") == 0)
+             test.state = vl_online;
+         else if (strcmp(tp, "busy") == 0)
+             test.state = vl_busy;
+         else if (strcmp(tp, "offline") == 0)
+             test.state = vl_offline;
+         else if (strcmp(tp, "down") == 0)
+             test.state = vl_alldown;
+         else {
+             fprintf (stderr, "%s: %s must be \"online\", \"busy\", \"offline\" or \"down\".\n", pn, tp);
+             return EINVAL;
+         }
+     }
+ 
+     if ((test.fid.cell || test.cellname[0]) && !(test.fid.volume || test.volname[0]) ||
+          !(test.fid.cell || test.cellname[0]) && (test.fid.volume || test.volname[0])) {
+         fprintf (stderr, "%s: both a cell and a volume must be specified.\n", pn, tp);
+         return EINVAL;
+     }
+ 
+     blob.in = (char *)&test;
+     blob.in_size = sizeof(test);
+     blob.out_size = 0;
+ 
+     code = pioctl(NULL, VIOC_VOLSTAT_TEST, &blob, 1);
+     if (code != 0) {
+ 	Die(errno, NULL);
+ 	return 1;
+     }
+ 
+     return 0;
+ }
+ 
  #ifndef WIN32
  #include "AFS_component_version_number.c"
  #endif
***************
*** 4606,4611 ****
--- 4688,4700 ----
  
      ts = cmd_CreateSyntax("minidump", MiniDumpCmd, NULL, "Generate MiniDump of current service state");
  
+     ts = cmd_CreateSyntax("test_volstat", TestVolStatCmd, NULL, (char *)CMD_HIDDEN);
+     cmd_AddParm(ts, "-network", CMD_SINGLE, CMD_OPTIONAL, "set network state up or down");
+     cmd_AddParm(ts, "-check",   CMD_FLAG,   CMD_OPTIONAL, "check state of offline volumes");
+     cmd_AddParm(ts, "-cell",    CMD_SINGLE, CMD_OPTIONAL, "cell name or number");
+     cmd_AddParm(ts, "-volume",  CMD_SINGLE, CMD_OPTIONAL, "volume name or number");
+     cmd_AddParm(ts, "-state",   CMD_SINGLE, CMD_OPTIONAL, "new volume state: online, busy, offline, down");
+ 
      code = cmd_Dispatch(argc, argv);
  
      if (rxInitDone) 
Index: openafs/src/WINNT/afsd/fs.h
diff -c openafs/src/WINNT/afsd/fs.h:1.4 openafs/src/WINNT/afsd/fs.h:1.4.8.1
*** openafs/src/WINNT/afsd/fs.h:1.4	Sun Jan  2 20:05:08 2005
--- openafs/src/WINNT/afsd/fs.h	Fri Jan  4 02:49:30 2008
***************
*** 17,23 ****
  
  static int CleanAcl(struct Acl *aa, char *fname);
  
! static int SetVolCmd(struct cmd_syndesc *as, char *arock);
  
  static int GetCellName(char *cellNamep, struct afsconf_cell *infop);
  
--- 17,23 ----
  
  static int CleanAcl(struct Acl *aa, char *fname);
  
! static int SetVolCmd(struct cmd_syndesc *as, void *arock);
  
  static int GetCellName(char *cellNamep, struct afsconf_cell *infop);
  
Index: openafs/src/WINNT/afsd/smb.c
diff -c openafs/src/WINNT/afsd/smb.c:1.118.2.48 openafs/src/WINNT/afsd/smb.c:1.118.2.50
*** openafs/src/WINNT/afsd/smb.c:1.118.2.48	Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/smb.c	Sun Jan  6 01:26:06 2008
***************
*** 65,71 ****
  osi_rwlock_t smb_rctLock;
  osi_mutex_t  smb_ListenerLock;
   
! char smb_LANadapter;
  unsigned char smb_sharename[NCBNAMSZ+1] = {0};
  
  BOOL isGateway = FALSE;
--- 65,71 ----
  osi_rwlock_t smb_rctLock;
  osi_mutex_t  smb_ListenerLock;
   
! char smb_LANadapter = -1;
  unsigned char smb_sharename[NCBNAMSZ+1] = {0};
  
  BOOL isGateway = FALSE;
***************
*** 8754,8759 ****
--- 8754,8782 ----
      FreeNCB(ncbp);
  }
  
+ 
+ void smb_LanAdapterChange(void) {
+     lana_number_t lanaNum;
+     BOOL          bGateway;
+     char          NetbiosName[MAX_NB_NAME_LENGTH] = "";
+     int           change = 0;
+ 
+     if (!powerStateSuspended && 
+         SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway, 
+                                           LANA_NETBIOS_NAME_FULL))) {
+         if (smb_LANadapter != lanaNum ||
+             isGateway != bGateway ||
+             strcmp(cm_NetbiosName, NetbiosName))
+             change = 1;
+     } 
+ 
+     if (change) {
+         afsi_log("Lan Adapter Change detected");
+         smb_StopListeners();
+         smb_RestartListeners();
+     }
+ }
+ 
  /* initialize Netbios */
  int smb_NetbiosInit(void)
  {
***************
*** 8953,8959 ****
      /* we're done with the NCB now */
      FreeNCB(ncbp);
  
!     return (lana_list.length > 0 ? 1 : 0);
  }
  
  void smb_StartListeners()
--- 8976,8982 ----
      /* we're done with the NCB now */
      FreeNCB(ncbp);
  
!     return ((lana_list.length > 0 && smb_LANadapter != -1) ? 1 : 0);
  }
  
  void smb_StartListeners()
***************
*** 8984,8992 ****
  
  void smb_RestartListeners()
  {
!     if (!powerStateSuspended && smb_ListenerState == SMB_LISTENER_STOPPED) {
! 	if (smb_NetbiosInit())
! 	    smb_StartListeners();
      }
  }
  
--- 9007,9019 ----
  
  void smb_RestartListeners()
  {
!     if (!powerStateSuspended) {
! 	if (smb_ListenerState == SMB_LISTENER_STOPPED) {
! 		if (smb_NetbiosInit())
! 		    smb_StartListeners();
! 	}
! 	if (smb_LANadapter == -1)
! 		smb_LanAdapterChange();
      }
  }
  
Index: openafs/src/WINNT/afsd/smb.h
diff -c openafs/src/WINNT/afsd/smb.h:1.41.2.19 openafs/src/WINNT/afsd/smb.h:1.41.2.21
*** openafs/src/WINNT/afsd/smb.h:1.41.2.19	Sat Dec 22 23:52:58 2007
--- openafs/src/WINNT/afsd/smb.h	Sat Jan  5 12:56:30 2008
***************
*** 332,338 ****
      char *inDatap;			/* ioctl func's current position
  					 * in input parameter block */
      char *inAllocp;			/* allocated input parameter block */
!     long inCopied;			/* # of input bytes copied in so far
  					 * by write calls */
      cm_space_t *prefix;		        /* prefix for subst drives */
      char *tidPathp;			/* Pathname associated with Tree ID */
--- 332,338 ----
      char *inDatap;			/* ioctl func's current position
  					 * in input parameter block */
      char *inAllocp;			/* allocated input parameter block */
!     afs_uint32 inCopied;			/* # of input bytes copied in so far
  					 * by write calls */
      cm_space_t *prefix;		        /* prefix for subst drives */
      char *tidPathp;			/* Pathname associated with Tree ID */
***************
*** 340,350 ****
      /* output side */
      char *outDatap;			/* output results assembled so far */
      char *outAllocp;		        /* output results assembled so far */
!     long outCopied;			/* # of output bytes copied back so far
                                           * by read calls */
  	
      /* flags */
!     long flags;
  
      /* fid pointer */
      struct smb_fid *fidp;
--- 340,350 ----
      /* output side */
      char *outDatap;			/* output results assembled so far */
      char *outAllocp;		        /* output results assembled so far */
!     afs_uint32 outCopied;		/* # of output bytes copied back so far
                                           * by read calls */
  	
      /* flags */
!     afs_uint32 flags;
  
      /* fid pointer */
      struct smb_fid *fidp;
***************
*** 759,764 ****
--- 759,765 ----
  extern void smb_StopListeners(void);
  extern void smb_StopListener(NCB *ncbp, int lana);
  extern long smb_IsNetworkStarted(void);
+ extern void smb_LanAdapterChange(void);
  
  #define SMB_LISTENER_UNINITIALIZED -1
  #define SMB_LISTENER_STOPPED 0
Index: openafs/src/WINNT/afsd/smb_iocons.h
diff -c openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.4 openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.5
*** openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.4	Tue May 15 16:20:55 2007
--- openafs/src/WINNT/afsd/smb_iocons.h	Fri Jan  4 02:58:40 2008
***************
*** 93,96 ****
--- 93,99 ----
  #define VIOC_RXSTAT_PEER                0x2f
  #define VIOC_UUIDCTL                    0x30
  #define VIOC_PATH_AVAILABILITY          0x31
+ 
+ #define VIOC_VOLSTAT_TEST               0x3F
+ /* Not to exceed SMB_IOCTL_MAXPROCS from smb_ioctl.h */
  #endif /*  __SMB_IOCONS_H_ENV_ */
Index: openafs/src/WINNT/afsd/smb_ioctl.c
diff -c openafs/src/WINNT/afsd/smb_ioctl.c:1.25.2.6 openafs/src/WINNT/afsd/smb_ioctl.c:1.25.2.7
*** openafs/src/WINNT/afsd/smb_ioctl.c:1.25.2.6	Sun Nov  4 19:24:47 2007
--- openafs/src/WINNT/afsd/smb_ioctl.c	Fri Jan  4 02:58:40 2008
***************
*** 85,90 ****
--- 85,91 ----
          smb_ioctlProcsp[VIOC_RXSTAT_PEER] = cm_IoctlRxStatPeer;
          smb_ioctlProcsp[VIOC_UUIDCTL] = cm_IoctlUUIDControl;
          smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = cm_IoctlPathAvailability;
+         smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = cm_IoctlVolStatTest;
  }
  
  /* called to make a fid structure into an IOCTL fid structure */
Index: openafs/src/WINNT/aklog/aklog.c
diff -c openafs/src/WINNT/aklog/aklog.c:1.14.4.7 openafs/src/WINNT/aklog/aklog.c:1.14.4.8
*** openafs/src/WINNT/aklog/aklog.c:1.14.4.7	Thu Nov 29 15:55:30 2007
--- openafs/src/WINNT/aklog/aklog.c	Sat Jan  5 12:01:24 2008
***************
*** 701,706 ****
--- 701,731 ----
                              NULL,
  #endif
                              &v5cred);
+ 
+         if (status == 0 && strcmp(realm_of_cell, "") == 0) {
+             krb5_error_code code;
+             krb5_ticket *ticket;
+ 
+             code = krb5_decode_ticket(&v5cred->ticket, &ticket);
+ 
+             if (code != 0) {
+                 fprintf(stderr,
+                          "%s: Couldn't decode ticket to determine realm for "
+                          "cell %s.\n",
+                          progname, cell_to_use);
+             } else {
+                 int len = krb5_princ_realm(context, ticket->server)->length;
+                 /* This really shouldn't happen. */
+                 if (len > REALM_SZ-1)
+                     len = REALM_SZ-1;
+ 
+                 strncpy(realm_of_cell, krb5_princ_realm(context, ticket->server)->data, len);
+                 realm_of_cell[len] = 0;
+ 
+                 krb5_free_ticket(context, ticket);
+             }
+         }
+ 
  	if (status == KRB5_ERR_HOST_REALM_UNKNOWN) {
  	    realm_fallback = 1;
  	    goto try_v5;
Index: openafs/src/WINNT/netidmgr_plugin/afsfuncs.c
diff -c openafs/src/WINNT/netidmgr_plugin/afsfuncs.c:1.1.2.13 openafs/src/WINNT/netidmgr_plugin/afsfuncs.c:1.1.2.17
*** openafs/src/WINNT/netidmgr_plugin/afsfuncs.c:1.1.2.13	Tue Nov 27 12:31:39 2007
--- openafs/src/WINNT/netidmgr_plugin/afsfuncs.c	Sat Jan  5 13:57:12 2008
***************
*** 1,5 ****
  /*
!  * Copyright (c) 2005,2006,2007 Secure Endpoints Inc.
   *
   * Permission is hereby granted, free of charge, to any person
   * obtaining a copy of this software and associated documentation
--- 1,5 ----
  /*
!  * Copyright (c) 2005,2006,2007, 2008 Secure Endpoints Inc.
   *
   * Permission is hereby granted, free of charge, to any person
   * obtaining a copy of this software and associated documentation
***************
*** 22,28 ****
   * SOFTWARE.
   */
  
! /* $Id: afsfuncs.c,v 1.1.2.13 2007/11/27 17:31:39 jaltman Exp $ */
  
  /* Disable the 'macro redefinition' warning which is getting
     triggerred by a redefinition of the ENCRYPT and DECRYPT macros. */
--- 22,28 ----
   * SOFTWARE.
   */
  
! /* $Id: afsfuncs.c,v 1.1.2.17 2008/01/05 18:57:12 jaltman Exp $ */
  
  /* Disable the 'macro redefinition' warning which is getting
     triggerred by a redefinition of the ENCRYPT and DECRYPT macros. */
***************
*** 703,708 ****
--- 703,726 ----
  }
  
  
+ static void
+ copy_realm_of_ticket(krb5_context context, char * dest, size_t destlen, krb5_creds *v5cred) {
+     krb5_error_code code;
+     krb5_ticket *ticket;
+     size_t len;
+ 
+     code = pkrb5_decode_ticket(&v5cred->ticket, &ticket);
+     if (code == 0) {
+         len = krb5_princ_realm(context, ticket->server)->length;
+         if (len > destlen - 1)
+             len = destlen - 1;
+ 
+         StringCbCopyA(dest, len, krb5_princ_realm(context, ticket->server)->data);
+ 
+         pkrb5_free_ticket(context, ticket);
+     }
+ }
+ 
  int
  afs_klog(khm_handle identity,
           char *service,
***************
*** 727,733 ****
      char	CellName[128];
      char	ServiceName[128];
      khm_handle	confighandle = NULL;
!     khm_int32	supports_krb4 = 1;
      khm_int32   got524cred = 0;
  
      /* signalling */
--- 745,751 ----
      char	CellName[128];
      char	ServiceName[128];
      khm_handle	confighandle = NULL;
!     khm_int32	supports_krb4 = (pkrb_get_tf_realm == NULL ? 0 : 1);
      khm_int32   got524cred = 0;
  
      /* signalling */
***************
*** 845,851 ****
  #endif
        retry_retcred:
          r = pkrb5_get_credentials(context, 0, k5cc, &increds, &k5creds);
! 	if ((r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
  	      r == KRB5KRB_ERR_GENERIC /* Heimdal */) &&
  	     !RealmName[0]) {
  	    StringCbCopyA(RealmName, sizeof(RealmName), 
--- 863,869 ----
  #endif
        retry_retcred:
          r = pkrb5_get_credentials(context, 0, k5cc, &increds, &k5creds);
!         if ((r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
  	      r == KRB5KRB_ERR_GENERIC /* Heimdal */) &&
  	     !RealmName[0]) {
  	    StringCbCopyA(RealmName, sizeof(RealmName), 
***************
*** 887,892 ****
--- 905,913 ----
  	    goto retry_retcred;
  	}
  
+         if (r == 0 && strlen(RealmName) == 0) 
+             copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), k5creds);
+ 
          pkrb5_free_principal(context, increds.server);
          pkrb5_free_principal(context, client_principal);
          client_principal = 0;
***************
*** 1009,1016 ****
  
          _reportf(L"Trying Krb524");
  
!         if (method == AFS_TOKEN_AUTO ||
!             method == AFS_TOKEN_KRB524) {
              /* This requires krb524d to be running with the KDC */
              r = pkrb524_convert_creds_kdc(context, k5creds, &creds);
              if (r) {
--- 1030,1037 ----
  
          _reportf(L"Trying Krb524");
  
!         if (pkrb524_convert_creds_kdc && 
!             (method == AFS_TOKEN_AUTO || method == AFS_TOKEN_KRB524)) {
              /* This requires krb524d to be running with the KDC */
              r = pkrb524_convert_creds_kdc(context, k5creds, &creds);
              if (r) {
***************
*** 1036,1048 ****
      /* Kerberos 4 */
   try_krb4:
  
!     kcdb_identity_get_config(identity, 0, &confighandle);
!     khc_read_int32(confighandle, L"Krb4Cred\\Krb4NewCreds", &supports_krb4);
!     khc_close_space(confighandle);
  
!     if (!supports_krb4) {
          _reportf(L"Kerberos 4 not configured");
-     }
  
      if (!bGotCreds && supports_krb4 && 
          (method == AFS_TOKEN_AUTO ||
--- 1057,1070 ----
      /* Kerberos 4 */
   try_krb4:
  
!     if (supports_krb4) {
! 	kcdb_identity_get_config(identity, 0, &confighandle);
! 	khc_read_int32(confighandle, L"Krb4Cred\\Krb4NewCreds", &supports_krb4);
! 	khc_close_space(confighandle); 
!     }
  
!     if (!supports_krb4)
          _reportf(L"Kerberos 4 not configured");
  
      if (!bGotCreds && supports_krb4 && 
          (method == AFS_TOKEN_AUTO ||
Index: openafs/src/afs/afs_osi_pag.c
diff -c openafs/src/afs/afs_osi_pag.c:1.29.4.11 openafs/src/afs/afs_osi_pag.c:1.29.4.12
*** openafs/src/afs/afs_osi_pag.c:1.29.4.11	Thu Nov  8 09:23:27 2007
--- openafs/src/afs/afs_osi_pag.c	Fri Jan  4 13:38:34 2008
***************
*** 23,29 ****
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_osi_pag.c,v 1.29.4.11 2007/11/08 14:23:27 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
--- 23,29 ----
  #include "afs/param.h"
  
  RCSID
!     ("$Header: /cvs/openafs/src/afs/afs_osi_pag.c,v 1.29.4.12 2008/01/04 18:38:34 shadow Exp $");
  
  #include "afs/sysincludes.h"	/* Standard vendor system headers */
  #include "afsincludes.h"	/* Afs-based standard headers */
***************
*** 145,150 ****
--- 145,151 ----
   */
  
  static int afs_pag_sleepcnt = 0;
+ static int afs_pag_timewarn = 0;
  
  static int
  afs_pag_sleep(struct AFS_UCRED **acred)
***************
*** 155,160 ****
--- 156,168 ----
  	if(osi_Time() - pag_epoch < pagCounter) {
  	    rv = 1;
  	}
+ 	if (rv && (osi_Time() < pag_epoch)) {
+ 	    if (!afs_pag_timewarn) {
+ 		afs_pag_timewarn = 1;
+ 		printf("clock went backwards, not PAG throttling");
+ 	    }
+ 	    rv = 0;
+ 	}
      }
  
      return rv;
Index: openafs/src/aklog/aklog_main.c
diff -c openafs/src/aklog/aklog_main.c:1.12.2.11 openafs/src/aklog/aklog_main.c:1.12.2.12
*** openafs/src/aklog/aklog_main.c:1.12.2.11	Sun Dec  9 01:07:31 2007
--- openafs/src/aklog/aklog_main.c	Fri Jan  4 23:46:52 2008
***************
*** 1,5 ****
  /* 
!  * $Id: aklog_main.c,v 1.12.2.11 2007/12/09 06:07:31 shadow Exp $
   *
   * Copyright 1990,1991 by the Massachusetts Institute of Technology
   * For distribution and copying rights, see the file "mit-copyright.h"
--- 1,5 ----
  /* 
!  * $Id: aklog_main.c,v 1.12.2.12 2008/01/05 04:46:52 shadow Exp $
   *
   * Copyright 1990,1991 by the Massachusetts Institute of Technology
   * For distribution and copying rights, see the file "mit-copyright.h"
***************
*** 36,42 ****
  
  #if !defined(lint) && !defined(SABER)
  static char *rcsid =
! 	"$Id: aklog_main.c,v 1.12.2.11 2007/12/09 06:07:31 shadow Exp $";
  #endif /* lint || SABER */
  
  #include <afsconfig.h>
--- 36,42 ----
  
  #if !defined(lint) && !defined(SABER)
  static char *rcsid =
! 	"$Id: aklog_main.c,v 1.12.2.12 2008/01/05 04:46:52 shadow Exp $";
  #endif /* lint || SABER */
  
  #include <afsconfig.h>
***************
*** 670,675 ****
--- 670,702 ----
  	status = get_credv5(context, name, primary_instance, realm_of_cell,
  			    &v5cred);
  
+ #if !defined(USING_HEIMDAL) && defined(HAVE_KRB5_DECODE_TICKET)
+ 	if (status == 0 && strcmp(realm_of_cell, "") == 0) {
+ 	    krb5_error_code code;
+ 	    krb5_ticket *ticket;
+ 
+ 	    code = krb5_decode_ticket(&v5cred->ticket, &ticket);
+ 
+ 	    if (code != 0) {
+ 		fprintf(stderr,
+ 			"%s: Couldn't decode ticket to determine realm for "
+ 			"cell %s.\n",
+ 			progname, cell_to_use);
+ 	    } else {
+ 		int len = realm_len(context, ticket->server);
+ 		/* This really shouldn't happen. */
+ 		if (len > REALM_SZ-1)
+ 		    len = REALM_SZ-1;
+ 
+ 		strncpy(realm_of_cell, realm_data(context, ticket->server), 
+ 			len);
+ 		realm_of_cell[len] = 0;
+ 
+ 		krb5_free_ticket(context, ticket);
+ 	    }
+ 	}
+ #endif
+ 
  	if ((status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || status == KRB5KRB_ERR_GENERIC) &&
  	    !realm_of_cell[0]) {
  	    char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, TRUE);
Index: openafs/src/cf/kerberos.m4
diff -c openafs/src/cf/kerberos.m4:1.7.2.5 openafs/src/cf/kerberos.m4:1.7.2.6
*** openafs/src/cf/kerberos.m4:1.7.2.5	Fri Nov 23 08:59:34 2007
--- openafs/src/cf/kerberos.m4	Fri Jan  4 23:46:52 2008
***************
*** 1,5 ****
  dnl
! dnl $Id: kerberos.m4,v 1.7.2.5 2007/11/23 13:59:34 shadow Exp $
  dnl
  dnl Kerberos autoconf glue
  dnl
--- 1,5 ----
  dnl
! dnl $Id: kerberos.m4,v 1.7.2.6 2008/01/05 04:46:52 shadow Exp $
  dnl
  dnl Kerberos autoconf glue
  dnl
***************
*** 58,64 ****
  	CPPFLAGS="$CPPFLAGS $KRB5CFLAGS"
  	save_LIBS="$LIBS"
  	LIBS="$LIBS $KRB5LIBS"
! 	AC_CHECK_FUNCS([add_to_error_table add_error_table krb5_princ_size krb5_principal_get_comp_string encode_krb5_enc_tkt_part encode_krb5_ticket krb5_c_encrypt krb5_c_encrypt_length krb5_cc_register])
  	AC_CHECK_FUNCS([krb5_524_convert_creds], ,
  	    [AC_CHECK_FUNCS([krb524_convert_creds_kdc], ,
  		[AC_CHECK_LIB([krb524], [krb524_convert_creds_kdc],
--- 58,64 ----
  	CPPFLAGS="$CPPFLAGS $KRB5CFLAGS"
  	save_LIBS="$LIBS"
  	LIBS="$LIBS $KRB5LIBS"
! 	AC_CHECK_FUNCS([add_to_error_table add_error_table krb5_princ_size krb5_principal_get_comp_string encode_krb5_enc_tkt_part encode_krb5_ticket krb5_c_encrypt krb5_c_encrypt_length krb5_cc_register krb5_decode_ticket])
  	AC_CHECK_FUNCS([krb5_524_convert_creds], ,
  	    [AC_CHECK_FUNCS([krb524_convert_creds_kdc], ,
  		[AC_CHECK_LIB([krb524], [krb524_convert_creds_kdc],
Index: openafs/src/cf/linux-test1.m4
diff -c openafs/src/cf/linux-test1.m4:1.6.4.8 openafs/src/cf/linux-test1.m4:1.6.4.9
*** openafs/src/cf/linux-test1.m4:1.6.4.8	Sat Dec  8 12:46:09 2007
--- openafs/src/cf/linux-test1.m4	Mon Jan  7 13:33:15 2008
***************
*** 29,35 ****
  _ACEOF
      echo make -C $LINUX_KERNEL_PATH M=$SRCDIR_PARENT/conftest.dir modules KBUILD_VERBOSE=1 >&AS_MESSAGE_LOG_FD &&
      make -C $LINUX_KERNEL_PATH M=$SRCDIR_PARENT/conftest.dir modules KBUILD_VERBOSE=1 >&AS_MESSAGE_LOG_FD 2>conftest.err &&
!     ! grep "^WARNING: .* undefined!$" conftest.err >/dev/null 2>&1
      then [$3]
      else
        sed '/^ *+/d' conftest.err >&AS_MESSAGE_LOG_FD
--- 29,35 ----
  _ACEOF
      echo make -C $LINUX_KERNEL_PATH M=$SRCDIR_PARENT/conftest.dir modules KBUILD_VERBOSE=1 >&AS_MESSAGE_LOG_FD &&
      make -C $LINUX_KERNEL_PATH M=$SRCDIR_PARENT/conftest.dir modules KBUILD_VERBOSE=1 >&AS_MESSAGE_LOG_FD 2>conftest.err &&
!     ! grep -i "^WARNING: .* undefined!$" conftest.err >/dev/null 2>&1
      then [$3]
      else
        sed '/^ *+/d' conftest.err >&AS_MESSAGE_LOG_FD
Index: openafs/src/packaging/RedHat/.cvsignore
diff -c /dev/null openafs/src/packaging/RedHat/.cvsignore:1.1.6.2
*** /dev/null	Wed Jan  9 12:23:16 2008
--- openafs/src/packaging/RedHat/.cvsignore	Thu Jan  3 13:03:45 2008
***************
*** 0 ****
--- 1 ----
+ openafs.spec
Index: openafs/src/sys/Makefile.in
diff -c openafs/src/sys/Makefile.in:1.36.2.6 openafs/src/sys/Makefile.in:1.36.2.8
*** openafs/src/sys/Makefile.in:1.36.2.6	Mon Nov 12 13:28:36 2007
--- openafs/src/sys/Makefile.in	Mon Jan  7 15:10:39 2008
***************
*** 19,26 ****
  SFLAGS=-I${TOP_INCDIR}
  LIBS=libsys.a ${TOP_LIBDIR}/librx.a libsys.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a ${XLIBS}
  
! OBJECTS= afssyscalls.o setpag.o glue.o syscall.o
! SHLIBOBJS = picobj/setpag.o picobj/glue.o syscall.o
  RMTOBJS=rmtsysnet.o rmtsysc.o rmtsys.cs.o rmtsys.xdr.o rmtsys.ss.o rmtsyss.o 
  
  LIBAFSSETPAG = libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR}
--- 19,26 ----
  SFLAGS=-I${TOP_INCDIR}
  LIBS=libsys.a ${TOP_LIBDIR}/librx.a libsys.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/util.a ${XLIBS}
  
! OBJECTS= afssyscalls.o setpag.o glue.o
! SHLIBOBJS = picobj/setpag.o picobj/glue.o
  RMTOBJS=rmtsysnet.o rmtsysc.o rmtsys.cs.o rmtsys.xdr.o rmtsys.ss.o rmtsyss.o 
  
  LIBAFSSETPAG = libafssetpag.${SHLIB_SUFFIX}.${LIBAFSSETPAGMAJOR}.${LIBAFSSETPAGMINOR}
***************
*** 46,75 ****
  	    ${MAKE} '${TOP_LIBDIR}/${LIBAFSSETPAG}';; \
  	esac
  
! libsys.a: ${OBJECTS} ${RMTOBJS} afsl.exp AFS_component_version_number.o
  	-$(RM) -f $@
! 	$(AR) crv $@ ${OBJECTS} ${RMTOBJS} \
! 		AFS_component_version_number.o ${LIBSYS_AIX_EXP}
  	$(RANLIB) $@
  	@set -x; case "${SYS_NAME}" in                   	\
  		rs_aix*) 			        \
  			$(AR) crv $@ afsl.exp;;         \
  	esac
  
! ${LIBAFSSETPAG}: ${SHLIBOBJS}
  	@set -x; case ${SYS_NAME} in \
  	*_linux*) \
  	    ${SHLIB_LINKER} -Wl,-h,libafssetpag.so.${LIBAFSSETPAGMAJOR} \
  	        -o ${LIBAFSSETPAG} -Wl,--version-script=${srcdir}/mapfile \
! 	        ${SHLIBOBJS};; \
  	rs_aix4*) \
! 	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS} \
  	        -bE:afssetpag.exp;; \
  	sun*_5*) \
  	    ${SHLIB_LINKER} -h libafssetpag.so.${LIBAFSSETPAGMAJOR} \
! 	        -o ${LIBAFSSETPAG} ${SHLIBOBJS};; \
! 	*) \
  	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS};; \
  	esac
  
  ${LIBAFSSETPAG_DARWIN}: ${SHLIBOBJS}
--- 46,83 ----
  	    ${MAKE} '${TOP_LIBDIR}/${LIBAFSSETPAG}';; \
  	esac
  
! libsys.a: ${OBJECTS} ${RMTOBJS} syscall.o afsl.exp AFS_component_version_number.o
  	-$(RM) -f $@
! 	@set -x; case "${SYS_NAME}" in                   	\
! 		hp_ux11*) \
! 			$(AR) crv $@ ${OBJECTS} ${RMTOBJS} \
! 				AFS_component_version_number.o ${LIBSYS_AIX_EXP} ;; \
! 		*) \
! 			$(AR) crv $@ ${OBJECTS} ${RMTOBJS} syscall.o \
! 				AFS_component_version_number.o ${LIBSYS_AIX_EXP} ;; \
! 	esac
  	$(RANLIB) $@
  	@set -x; case "${SYS_NAME}" in                   	\
  		rs_aix*) 			        \
  			$(AR) crv $@ afsl.exp;;         \
  	esac
  
! ${LIBAFSSETPAG}: ${SHLIBOBJS} syscall.o
  	@set -x; case ${SYS_NAME} in \
  	*_linux*) \
  	    ${SHLIB_LINKER} -Wl,-h,libafssetpag.so.${LIBAFSSETPAGMAJOR} \
  	        -o ${LIBAFSSETPAG} -Wl,--version-script=${srcdir}/mapfile \
! 	        ${SHLIBOBJS} syscall.o ;; \
  	rs_aix4*) \
! 	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS} syscall.o \
  	        -bE:afssetpag.exp;; \
  	sun*_5*) \
  	    ${SHLIB_LINKER} -h libafssetpag.so.${LIBAFSSETPAGMAJOR} \
! 	        -o ${LIBAFSSETPAG} ${SHLIBOBJS} syscall.o;; \
! 	hp_ux11*) \
  	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS};; \
+ 	*) \
+ 	    ${SHLIB_LINKER} -o ${LIBAFSSETPAG} ${SHLIBOBJS} syscall.o ;; \
  	esac
  
  ${LIBAFSSETPAG_DARWIN}: ${SHLIBOBJS}
Index: openafs/src/tsm41/aix_aklog.c
diff -c openafs/src/tsm41/aix_aklog.c:1.1.2.5 openafs/src/tsm41/aix_aklog.c:1.1.2.6
*** openafs/src/tsm41/aix_aklog.c:1.1.2.5	Thu Dec 13 18:06:08 2007
--- openafs/src/tsm41/aix_aklog.c	Thu Jan  3 13:03:46 2008
***************
*** 11,17 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/tsm41/aix_aklog.c,v 1.1.2.5 2007/12/13 23:06:08 shadow Exp $");
  
  #if defined(AFS_AIX51_ENV)
  #include <sys/types.h>
--- 11,17 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/tsm41/aix_aklog.c,v 1.1.2.6 2008/01/03 18:03:46 shadow Exp $");
  
  #if defined(AFS_AIX51_ENV)
  #include <sys/types.h>
***************
*** 23,30 ****
--- 23,32 ----
  #include <netdb.h>
  #include <sys/socket.h>
  #include <sys/file.h>
+ #include <sys/pag.h>
  #include <errno.h>
  #include <usersec.h>
+ #include <syslog.h>
  
  #include <krb5.h>
  
***************
*** 65,71 ****
   * Other prototypes
   */
  
! static krb5_error_code get_credv5(krb5_context context, char *, char *,
  				  char *, krb5_creds **);
  static int get_user_realm(krb5_context, char *);
  
--- 67,73 ----
   * Other prototypes
   */
  
! static krb5_error_code get_credv5(krb5_context context, char *, char *, char *,
  				  char *, krb5_creds **);
  static int get_user_realm(krb5_context, char *);
  
***************
*** 108,119 ****
  char *afs_realm_of_cell(krb5_context context, struct afsconf_cell *cellconfig, int fallback)
  {
      static char krbrlm[REALM_SZ+1];
!         char **hrealms = 0;
!         krb5_error_code retval;
! 
      if (!cellconfig)
          return 0;
! 
      if (fallback) {
          char * p;
          p = strchr(cellconfig->hostName[0], '.');
--- 110,121 ----
  char *afs_realm_of_cell(krb5_context context, struct afsconf_cell *cellconfig, int fallback)
  {
      static char krbrlm[REALM_SZ+1];
!     char **hrealms = 0;
!     krb5_error_code retval;
!     
      if (!cellconfig)
          return 0;
!     
      if (fallback) {
          char * p;
          p = strchr(cellconfig->hostName[0], '.');
***************
*** 131,137 ****
              return 0; 
          if(!hrealms[0]) return 0;
          strcpy(krbrlm, hrealms[0]);
! 
          if (hrealms) krb5_free_host_realm(context, hrealms);
      }
      return krbrlm;
--- 133,139 ----
              return 0; 
          if(!hrealms[0]) return 0;
          strcpy(krbrlm, hrealms[0]);
! 	
          if (hrealms) krb5_free_host_realm(context, hrealms);
      }
      return krbrlm;
***************
*** 145,164 ****
      int code, unixauthneeded, password_expires = -1;
      int status;
      krb5_context context;
! 
      krb5_init_context(&context);
      *reenter = 0;
      *message = (char *)0;
! 
! #if 0
!     if ((pwd = getpwnam(userName)) == NULL) {
! 	*message = (char *)malloc(256);
! 	sprintf(*message, "getpwnam for user failed\n");
! 	return AUTH_FAILURE;
!     }
! #endif
! 
!     status = auth_to_cell(context, NULL, NULL);
      if (status) {
  	*message = (char *)malloc(1024);
  	sprintf(*message, "Unable to obtain AFS tokens: %s.\n",
--- 147,159 ----
      int code, unixauthneeded, password_expires = -1;
      int status;
      krb5_context context;
!     
      krb5_init_context(&context);
      *reenter = 0;
      *message = (char *)0;
!     
!     status = auth_to_cell(context, userName, NULL, NULL);
!     
      if (status) {
  	*message = (char *)malloc(1024);
  	sprintf(*message, "Unable to obtain AFS tokens: %s.\n",
***************
*** 189,195 ****
  		
  		fcell[strlen(fcell) - 1] = '\0';
  		
! 		auth_status = auth_to_cell(context, fcell, NULL);
  		if (status == AKLOG_SUCCESS)
  		    status = auth_status;
  		else
--- 184,190 ----
  		
  		fcell[strlen(fcell) - 1] = '\0';
  		
! 		auth_status = auth_to_cell(context, userName, fcell, NULL);
  		if (status == AKLOG_SUCCESS)
  		    status = auth_status;
  		else
***************
*** 200,242 ****
  #endif
      return AUTH_SUCCESS;
  }
! 	
! static krb5_error_code get_credv5(krb5_context context, 
! 			char *name, char *inst, char *realm,
! 			krb5_creds **creds)
  {
      krb5_creds increds;
      krb5_error_code r;
      static krb5_principal client_principal = 0;
! 
      memset((char *)&increds, 0, sizeof(increds));
      /* instance may be ptr to a null string. Pass null then */
      if ((r = krb5_build_principal(context, &increds.server,
!                      strlen(realm), realm,
!                      name,
!            (inst && strlen(inst)) ? inst : (void *) NULL,
!                      (void *) NULL))) {
          return r;
      }
! 
!     if (!_krb425_ccache) {
!         r = krb5_cc_default(context, &_krb425_ccache);
! 	if (r)
! 	    return r;
!     }
!     if (!client_principal) {
!         r = krb5_cc_get_principal(context, _krb425_ccache, &client_principal);
! 	if (r)
! 	    return r;
      }
! 
      increds.client = client_principal;
      increds.times.endtime = 0;
! 	/* Ask for DES since that is what V4 understands */
      get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
! 
      r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
! 
      return r;
  }
  
--- 195,236 ----
  #endif
      return AUTH_SUCCESS;
  }
! 
! static krb5_error_code get_credv5(krb5_context context, char *user,  
! 				  char *name, char *inst, char *realm,
! 				  krb5_creds **creds)
  {
      krb5_creds increds;
      krb5_error_code r;
      static krb5_principal client_principal = 0;
!     char *str;
!     
      memset((char *)&increds, 0, sizeof(increds));
      /* instance may be ptr to a null string. Pass null then */
      if ((r = krb5_build_principal(context, &increds.server,
! 				  strlen(realm), realm,
! 				  name,
! 				  (inst && strlen(inst)) ? inst : (void *) NULL,
! 				  (void *) NULL))) {
          return r;
      }
!     r = krb5_cc_default(context, &_krb425_ccache);
!     if (r) {
!         syslog(LOG_AUTH|LOG_ERR, "LAM aklog: krb5_cc_default returns %d", r);
!         return r;
      }
!     r = krb5_cc_get_principal(context, _krb425_ccache, &client_principal); 
!     if (r) {
! 	syslog(LOG_AUTH|LOG_ERR, "LAM aklog: krb5_cc_get_principal returns %d", r);
! 	return r;
!     } 
      increds.client = client_principal;
      increds.times.endtime = 0;
!     /* Ask for DES since that is what V4 understands */
      get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
!     
      r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
!     
      return r;
  }
  
***************
*** 245,261 ****
  {
      static krb5_principal client_principal = 0;
      int i;
! 
      if (!_krb425_ccache)
          krb5_cc_default(context, &_krb425_ccache);
      if (!client_principal)
          krb5_cc_get_principal(context, _krb425_ccache, &client_principal);
! 
      i = realm_len(context, client_principal);
      if (i > REALM_SZ-1) i = REALM_SZ-1;
      strncpy(realm,realm_data(context, client_principal), i);
      realm[i] = 0;
! 
      return 0;
  }
  
--- 239,255 ----
  {
      static krb5_principal client_principal = 0;
      int i;
!     
      if (!_krb425_ccache)
          krb5_cc_default(context, &_krb425_ccache);
      if (!client_principal)
          krb5_cc_get_principal(context, _krb425_ccache, &client_principal);
!     
      i = realm_len(context, client_principal);
      if (i > REALM_SZ-1) i = REALM_SZ-1;
      strncpy(realm,realm_data(context, client_principal), i);
      realm[i] = 0;
!     
      return 0;
  }
  
***************
*** 273,279 ****
  
  int
  aklog_passwdrestrictions(char *userName, char *newPasswd, char *oldPasswd,
! 		       char **message)
  {
      return AUTH_SUCCESS;
  }
--- 267,273 ----
  
  int
  aklog_passwdrestrictions(char *userName, char *newPasswd, char *oldPasswd,
! 			 char **message)
  {
      return AUTH_SUCCESS;
  }
***************
*** 290,319 ****
  {
      int status = 0;
      struct afsconf_dir *configdir;
! 
      memset(local_cell, 0, sizeof(local_cell));
      memset((char *)cellconfig, 0, sizeof(*cellconfig));
! 
      if (!(configdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
  	return AFSCONF_NODB;
      }
! 
      if (afsconf_GetLocalCell(configdir, local_cell, MAXCELLCHARS)) {
  	return AFSCONF_FAILURE;
      }
! 
      if ((cell == NULL) || (cell[0] == 0))
  	cell = local_cell;
! 
! 	linkedcell[0] = '\0';
      if (afsconf_GetCellInfo(configdir, cell, NULL, cellconfig)) {
  	status = AFSCONF_NOTFOUND;
      }
      if (cellconfig->linkedCell) 
  	strncpy(linkedcell,cellconfig->linkedCell,MAXCELLCHARS);
! 
      (void) afsconf_Close(configdir);
! 
      return(status);
  }
  
--- 284,313 ----
  {
      int status = 0;
      struct afsconf_dir *configdir;
!     
      memset(local_cell, 0, sizeof(local_cell));
      memset((char *)cellconfig, 0, sizeof(*cellconfig));
!     
      if (!(configdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
  	return AFSCONF_NODB;
      }
!     
      if (afsconf_GetLocalCell(configdir, local_cell, MAXCELLCHARS)) {
  	return AFSCONF_FAILURE;
      }
!     
      if ((cell == NULL) || (cell[0] == 0))
  	cell = local_cell;
!     
!     linkedcell[0] = '\0';
      if (afsconf_GetCellInfo(configdir, cell, NULL, cellconfig)) {
  	status = AFSCONF_NOTFOUND;
      }
      if (cellconfig->linkedCell) 
  	strncpy(linkedcell,cellconfig->linkedCell,MAXCELLCHARS);
!     
      (void) afsconf_Close(configdir);
!     
      return(status);
  }
  
***************
*** 322,333 ****
   * doing anything.  Otherwise, log to it and mark that it has been logged
   * to.
   */
! static int auth_to_cell(krb5_context context, char *cell, char *realm)
  {
      int status = 0;
      char username[BUFSIZ];	/* To hold client username structure */
      afs_int32 viceId;		/* AFS uid of user */
! 
      char name[ANAME_SZ];	/* Name of afs key */
      char primary_instance[INST_SZ];	/* Instance of afs key */
      char secondary_instance[INST_SZ];	/* Backup instance to try */
--- 316,327 ----
   * doing anything.  Otherwise, log to it and mark that it has been logged
   * to.
   */
! static int auth_to_cell(krb5_context context, char *user, char *cell, char *realm)
  {
      int status = 0;
      char username[BUFSIZ];	/* To hold client username structure */
      afs_int32 viceId;		/* AFS uid of user */
!     
      char name[ANAME_SZ];	/* Name of afs key */
      char primary_instance[INST_SZ];	/* Instance of afs key */
      char secondary_instance[INST_SZ];	/* Backup instance to try */
***************
*** 342,368 ****
      struct ktc_principal aserver;
      struct ktc_principal aclient;
      struct ktc_token atoken, btoken;
!     int afssetpag = 1;
! 
      memset(name, 0, sizeof(name));
      memset(primary_instance, 0, sizeof(primary_instance));
      memset(secondary_instance, 0, sizeof(secondary_instance));
      memset(realm_of_user, 0, sizeof(realm_of_user));
      memset(realm_of_cell, 0, sizeof(realm_of_cell));
! 
      if (confname[0] == '\0') {
  	strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
  	confname[sizeof(confname) - 2] = '\0';
      }
! 
      /* NULL or empty cell returns information on local cell */
      if ((status = get_cellconfig(cell, &ak_cellconfig,
! 			 local_cell, linkedcell)))
  	return(status);
! 
      strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
      cell_to_use[MAXCELLCHARS] = 0;
! 
      /*
       * Find out which realm we're supposed to authenticate to.  If one
       * is not included, use the kerberos realm found in the credentials
--- 336,365 ----
      struct ktc_principal aserver;
      struct ktc_principal aclient;
      struct ktc_token atoken, btoken;
!     int afssetpag = 0, uid = -1;
!     struct passwd *pwd;
!     
      memset(name, 0, sizeof(name));
      memset(primary_instance, 0, sizeof(primary_instance));
      memset(secondary_instance, 0, sizeof(secondary_instance));
      memset(realm_of_user, 0, sizeof(realm_of_user));
      memset(realm_of_cell, 0, sizeof(realm_of_cell));
!     syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog starting: user %s uid %d", user, getuid());
      if (confname[0] == '\0') {
  	strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
  	confname[sizeof(confname) - 2] = '\0';
      }
!     
      /* NULL or empty cell returns information on local cell */
      if ((status = get_cellconfig(cell, &ak_cellconfig,
! 				 local_cell, linkedcell))) {
!         syslog(LOG_AUTH|LOG_ERR, "LAM aklog: get_cellconfig returns %d", status);
  	return(status);
!     }
!     
      strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
      cell_to_use[MAXCELLCHARS] = 0;
!     
      /*
       * Find out which realm we're supposed to authenticate to.  If one
       * is not included, use the kerberos realm found in the credentials
***************
*** 376,381 ****
--- 373,379 ----
  	char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, FALSE);
  	
  	if (!afs_realm) {
+             syslog(LOG_AUTH|LOG_ERR, "LAM aklog: afs_realm_of_cell returns %d", status);
  	    return AFSCONF_FAILURE;
  	}
  	
***************
*** 431,437 ****
       * 	afs@<realm>
       */
      
!     status = get_credv5(context, name, primary_instance, realm_of_cell,
  			&v5cred);
      
      if ((status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || 
--- 429,435 ----
       * 	afs@<realm>
       */
      
!     status = get_credv5(context, user, name, primary_instance, realm_of_cell,
  			&v5cred);
      
      if ((status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || 
***************
*** 439,444 ****
--- 437,443 ----
  	char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, TRUE);
  	
  	if (!afs_realm) {
+             syslog(LOG_AUTH|LOG_ERR, "LAM aklog: afs_realm_of_cell returns %d", status);
  	    return AFSCONF_FAILURE;
  	}
  	
***************
*** 449,466 ****
  	    secondary_instance[0] = '\0';
  	}
  	
! 	status = get_credv5(context, name, primary_instance, realm_of_cell,
! 			    &v5cred);
! 	
      }
      if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || 
  	status == KRB5KRB_ERR_GENERIC) {
  	if (try_secondary)
! 	    status = get_credv5(context, name, secondary_instance,
  				realm_of_cell, &v5cred);
      }
      
      if (status) {
  	return status;
      }
      
--- 448,465 ----
  	    secondary_instance[0] = '\0';
  	}
  	
! 	status = get_credv5(context, user, name, primary_instance, 
! 			    realm_of_cell, &v5cred);
      }
      if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || 
  	status == KRB5KRB_ERR_GENERIC) {
  	if (try_secondary)
! 	    status = get_credv5(context, user, name, secondary_instance,
  				realm_of_cell, &v5cred);
      }
      
      if (status) {
+         syslog(LOG_AUTH|LOG_ERR, "LAM aklog: get_credv5 returns %d", status);
  	return status;
      }
      
***************
*** 502,509 ****
  	atoken.ticketLen = v5cred->ticket.length;
  	memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
      }
! 	
      if ((status = get_user_realm(context, realm_of_user))) {
  	return KRB5_REALM_UNKNOWN;
      }
      if (strcmp(realm_of_user, realm_of_cell)) {
--- 501,509 ----
  	atoken.ticketLen = v5cred->ticket.length;
  	memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
      }
!     
      if ((status = get_user_realm(context, realm_of_user))) {
+         syslog(LOG_AUTH|LOG_ERR, "LAM aklog: get_user_realm returns %d", status);
  	return KRB5_REALM_UNKNOWN;
      }
      if (strcmp(realm_of_user, realm_of_cell)) {
***************
*** 512,521 ****
      }
      
      strcpy(lastcell, aserver.cell);
!     
!     if (!pr_Initialize (0, confname, aserver.cell))
! 	status = pr_SNameToId (username, &viceId);
!     
      /*
       * This is a crock, but it is Transarc's crock, so
       * we have to play along in order to get the
--- 512,518 ----
      }
      
      strcpy(lastcell, aserver.cell);
! 
      /*
       * This is a crock, but it is Transarc's crock, so
       * we have to play along in order to get the
***************
*** 525,534 ****
       * the code for tokens, this hack (AFS ID %d) will
       * not work if you change %d to something else.
       */
!     
!     /* Don't do first-time registration. Handle only the simple case */
      if ((status == 0) && (viceId != ANONYMOUSID))
  	sprintf (username, "AFS ID %d", (int) viceId);
  
      /* Reset the "aclient" structure before we call ktc_SetToken.
       * This structure was first set by the ktc_GetToken call when
--- 522,551 ----
       * the code for tokens, this hack (AFS ID %d) will
       * not work if you change %d to something else.
       */
! 
! #if 0
!     /* This actually crashes long-running daemons */
!     if (!pr_Initialize (0, confname, aserver.cell))
! 	status = pr_SNameToId (username, &viceId);
      if ((status == 0) && (viceId != ANONYMOUSID))
  	sprintf (username, "AFS ID %d", (int) viceId);
+ #else
+     /* 
+      * This actually only works assuming that your uid and pts space match 
+      * and probably this works only for the local cell anyway.
+      */
+     
+     if ((uid = getuid()) == 0) {
+ 	if ((pwd = getpwnam(user)) == NULL) {
+ 	    syslog(LOG_AUTH|LOG_ERR, "LAM aklog: getpwnam %s failed", user);
+ 	    return AUTH_FAILURE;
+ 	}
+     }
+     
+     /* Don't do first-time registration. Handle only the simple case */
+     if ((status == 0) && (viceId != ANONYMOUSID)) 
+  	sprintf (username, "AFS ID %d", ((uid==0)?(int)pwd->pw_uid:(int)uid));
+ #endif
  
      /* Reset the "aclient" structure before we call ktc_SetToken.
       * This structure was first set by the ktc_GetToken call when
***************
*** 546,553 ****
       */
      write(2,"",0); /* dummy write */
  #endif
!     status = ktc_SetToken(&aserver, &atoken, &aclient, afssetpag);
! 
      return(status);
  }
  
--- 563,609 ----
       */
      write(2,"",0); /* dummy write */
  #endif
!     afssetpag = (getpagvalue("afs") > 0) ? 1 : 0;
!     if (uid == 0) {
! 	struct sigaction newAction, origAction;
! 	pid_t cid, pcid;
! 	int wstatus;
! 	
! 	sigemptyset(&newAction.sa_mask);
! 	newAction.sa_handler = SIG_DFL;
! 	newAction.sa_flags = 0;
! 	status = sigaction(SIGCHLD, &newAction, &origAction);
! 	if (status) {
! 	    syslog(LOG_AUTH|LOG_ERR, "LAM aklog: sigaction returned %d", status);
! 	    return AUTH_FAILURE;
! 	}
! 	syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog: in daemon? forking to set tokens");
! 	cid = fork();
! 	if (cid <= 0) {
! 	    syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog child: setting tokens");
! 	    setuid(pwd->pw_uid);
! 	    status = ktc_SetToken(&aserver, &atoken, &aclient, afssetpag);
! 	    if (status != 0)
! 		syslog(LOG_AUTH|LOG_ERR, "LAM aklog child: set tokens, returning %d", status);
! 	    exit((status == 0)?0:255);
! 	} else {
! 	    do {
! 		pcid = waitpid(cid, &wstatus, 0);
! 	    } while ((pcid == -1) && (errno == EINTR));
! 	    if ((pcid == cid) && WIFEXITED(wstatus))
! 		status = WEXITSTATUS(wstatus);
! 	    else 
! 		status = -1;
! 	} 
! 	syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog: collected child status %d", status);
! 	sigaction(SIGCHLD, &origAction, NULL);
!     } else {
! 	status = ktc_SetToken(&aserver, &atoken, &aclient, afssetpag);
!     }
!     if (status != 0)
! 	syslog(LOG_AUTH|LOG_ERR, "LAM aklog: set tokens returned %d", status);
!     else
! 	syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog: set tokens, pag %d", getpagvalue("afs"));
      return(status);
  }
  
***************
*** 555,561 ****
  aklog_initialize(struct secmethod_table *meths)
  {
      memset(meths, 0, sizeof(struct secmethod_table));
! 
      /*
       * Initialize the exported interface routines.
       * Aside from method_authenticate, these are just no-ops.
--- 611,617 ----
  aklog_initialize(struct secmethod_table *meths)
  {
      memset(meths, 0, sizeof(struct secmethod_table));
!     syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog loaded: uid %d pag %d", getuid(), getpagvalue("afs"));    
      /*
       * Initialize the exported interface routines.
       * Aside from method_authenticate, these are just no-ops.
***************
*** 565,571 ****
      meths->method_passwdexpired = aklog_passwdexpired;
      meths->method_passwdrestrictions = aklog_passwdrestrictions;
      meths->method_getpasswd = aklog_getpasswd;
! 
      return (0);
  }
  #endif /* AFS_AIX51_ENV */
--- 621,627 ----
      meths->method_passwdexpired = aklog_passwdexpired;
      meths->method_passwdrestrictions = aklog_passwdrestrictions;
      meths->method_getpasswd = aklog_getpasswd;
!     
      return (0);
  }
  #endif /* AFS_AIX51_ENV */
Index: openafs/src/viced/afsfileprocs.c
diff -c openafs/src/viced/afsfileprocs.c:1.113.2.20 openafs/src/viced/afsfileprocs.c:1.113.2.21
*** openafs/src/viced/afsfileprocs.c:1.113.2.20	Wed Nov 21 14:34:36 2007
--- openafs/src/viced/afsfileprocs.c	Mon Jan  7 15:23:50 2008
***************
*** 29,35 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.113.2.20 2007/11/21 19:34:36 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
--- 29,35 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/afsfileprocs.c,v 1.113.2.21 2008/01/07 20:23:50 shadow Exp $");
  
  #include <stdio.h>
  #include <stdlib.h>
***************
*** 342,348 ****
  	    hpr_End(uclient);
  	code = hpr_Initialize(&uclient);
  
! 	assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
  	H_LOCK;
  #else
  	code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
--- 342,349 ----
  	    hpr_End(uclient);
  	code = hpr_Initialize(&uclient);
  
! 	if (!code)
! 	    assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
  	H_LOCK;
  #else
  	code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
Index: openafs/src/viced/host.c
diff -c openafs/src/viced/host.c:1.93.2.24 openafs/src/viced/host.c:1.93.2.26
*** openafs/src/viced/host.c:1.93.2.24	Mon Nov 12 13:19:59 2007
--- openafs/src/viced/host.c	Mon Jan  7 15:23:51 2008
***************
*** 13,19 ****
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/host.c,v 1.93.2.24 2007/11/12 18:19:59 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
--- 13,19 ----
  #include <afs/param.h>
  
  RCSID
!     ("$Header: /cvs/openafs/src/viced/host.c,v 1.93.2.26 2008/01/07 20:23:51 shadow Exp $");
  
  #include <stdio.h>
  #include <errno.h>
***************
*** 384,390 ****
  
      if (!uclient) {
          code = hpr_Initialize(&uclient);
!         assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
      }
  
      over = 0;
--- 384,393 ----
  
      if (!uclient) {
          code = hpr_Initialize(&uclient);
! 	if (!code) 
! 	    assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
! 	else
! 	    return code;
      }
  
      over = 0;
***************
*** 415,421 ****
  
      if (!uclient) {
          code = hpr_Initialize(&uclient);
!         assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
      }
  
      for (i = 0; i < names->namelist_len; i++)
--- 418,427 ----
  
      if (!uclient) {
          code = hpr_Initialize(&uclient);
! 	if (!code)
! 	    assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
! 	else
! 	    return code;
      }
  
      for (i = 0; i < names->namelist_len; i++)
***************
*** 437,443 ****
      
      if (!uclient) {
          code = hpr_Initialize(&uclient);
!         assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
      }
  
      code = ubik_PR_IDToName(uclient, 0, ids, names);
--- 443,452 ----
      
      if (!uclient) {
          code = hpr_Initialize(&uclient);
! 	if (!code)
! 	    assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
! 	else
! 	    return code;
      }
  
      code = ubik_PR_IDToName(uclient, 0, ids, names);
***************
*** 458,464 ****
  
      if (!uclient) {
          code = hpr_Initialize(&uclient);
!         assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
      }
  
      over = 0;
--- 467,476 ----
  
      if (!uclient) {
          code = hpr_Initialize(&uclient);
! 	if (!code)
! 	    assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
! 	else
! 	    return code;
      }
  
      over = 0;
***************
*** 1440,1447 ****
  	 * of the caller matches the identity in the host structure.
  	 */
  	if ((host->hostFlags & HWHO_INPROGRESS) && 
! 	    h_threadquota(host->lock.num_waiting))
  	    return 0;
  	h_Lock_r(host);
  	if (!(host->hostFlags & ALTADDR)) {
  	    host->hostFlags &= ~HWHO_INPROGRESS;
--- 1452,1462 ----
  	 * of the caller matches the identity in the host structure.
  	 */
  	if ((host->hostFlags & HWHO_INPROGRESS) && 
! 	    h_threadquota(host->lock.num_waiting)) {
! 	    if (!held)
! 		h_Release_r(host);
  	    return 0;
+ 	}
  	h_Lock_r(host);
  	if (!(host->hostFlags & ALTADDR)) {
  	    host->hostFlags &= ~HWHO_INPROGRESS;
Index: openafs/src/vol/vnode.c
diff -c openafs/src/vol/vnode.c:1.27.2.1 openafs/src/vol/vnode.c:1.27.2.3
*** openafs/src/vol/vnode.c:1.27.2.1	Tue Oct 30 11:16:58 2007
--- openafs/src/vol/vnode.c	Fri Dec 28 17:15:02 2007
***************
*** 20,26 ****
  #define MAXINT     (~(1<<((sizeof(int)*8)-1)))
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vnode.c,v 1.27.2.1 2007/10/30 15:16:58 shadow Exp $");
  
  #include <errno.h>
  #include <stdio.h>
--- 20,26 ----
  #define MAXINT     (~(1<<((sizeof(int)*8)-1)))
  
  RCSID
!     ("$Header: /cvs/openafs/src/vol/vnode.c,v 1.27.2.3 2007/12/28 22:15:02 shadow Exp $");
  
  #include <errno.h>
  #include <stdio.h>
***************
*** 73,78 ****
--- 73,80 ----
  private void StickOnLruChain_r(register Vnode * vnp,
  			       register struct VnodeClassInfo *vcp);
  
+ extern int LogLevel;
+ 
  #define BAD_IGET	-1000
  
  /* There are two separate vnode queue types defined here:
***************
*** 699,704 ****
--- 701,709 ----
  #endif
  		mlkReason = 4;
  	    } else {
+ 		/* Probably legit; Don't knock the volume offline */
+ 		if (LogLevel >= 5) 
+ 		    Log("VGetVnode: Couldn't read vnode %u, volume %u (%s); errno %d\n", vnodeNumber, V_id(vp), V_name(vp), errno);
  		mlkReason = 5;
  		*ec = VIO;
  	    }
