void AfsAdmSvr_Action_StopRefresh (ASID idScope)
{
   AfsAdmSvr_Enter();

   for (size_t iOp = 0; iOp < l.cOperationsAllocated; ++iOp)
      {
      if (!l.aOperations[ iOp ].fInUse)
         continue;
      if (!l.aOperations[ iOp ].pAction)
         continue;
      if (l.aOperations[ iOp ].pAction->Action != ACTION_REFRESH)
         continue;
      if (l.aOperations[ iOp ].pAction->u.Refresh.idScope != idScope)
         continue;

      AfsAdmSvr_EndOperation (iOp);
      break;
      }

   if (GetAsidType (idScope) == itCELL)
      {
      AfsAdmSvr_MarkRefreshThread (idScope);
      }

   AfsAdmSvr_Leave();
}
LPASACTIONLIST AfsAdmSvr_GetOperations (UINT_PTR idClientSearch, ASID idCellSearch)
{
   LPASACTIONLIST pList = AfsAdmSvr_CreateActionList();
   AfsAdmSvr_Enter();

   for (WORD iOp = 0; iOp < l.cOperationsAllocated; ++iOp)
      {
      if (!l.aOperations[ iOp ].fInUse)
         continue;
      if (!l.aOperations[ iOp ].pAction)
         continue;
      if (idClientSearch && ((UINT_PTR)idClientSearch != l.aOperations[ iOp ].pAction->idClient))
         continue;
      if (idCellSearch && (idCellSearch != l.aOperations[ iOp ].pAction->idCell))
         continue;

      ASACTION Action;
      memcpy (&Action, l.aOperations[ iOp ].pAction, sizeof(ASACTION));
      Action.csecActive = (GetTickCount() - l.aOperations[ iOp ].dwTickStart) / 1000;
      if (!AfsAdmSvr_AddToActionList (&pList, &Action))
         {
         AfsAdmSvr_FreeActionList (&pList);
         break;
         }
      }

   AfsAdmSvr_Leave();
   return pList;
}
BOOL AfsAdmSvr_AttachClient (LPCTSTR pszName, PVOID *pidClient, ULONG *pStatus)
{
   AfsAdmSvr_Enter();
   size_t iClient;
   for (iClient = 0; iClient < l.cClientsAllocated; ++iClient)
      {
      if (!l.aClients[ iClient ])
         break;
      }
   if (!REALLOC (l.aClients, l.cClientsAllocated, 1+iClient, cREALLOC_CLIENTS))
      {
      *pidClient = NULL;
      return FALSE;
      }
   if ((l.aClients[ iClient ] = New (CLIENTINFO)) == NULL)
      {
      *pidClient = NULL;
      return FALSE;
      }
   memset (l.aClients[ iClient ], 0x00, sizeof(CLIENTINFO));
   lstrcpy (l.aClients[ iClient ]->szName, pszName);
   l.aClients[ iClient ]->timeLastPing = AfsAdmSvr_GetCurrentTime();
   l.cClients ++;

   if (!AfsAdmSvr_ResolveName (&l.aClients[ iClient ]->ipAddress, l.aClients[ iClient ]->szName))
      memset (&l.aClients[ iClient ]->ipAddress, 0x00, sizeof(SOCKADDR_IN));

   *pidClient = (PVOID)(l.aClients[ iClient ]);
   AfsAdmSvr_Leave();
   return TRUE;
}
DWORD WINAPI AfsAdmSvr_AutoShutdownThread (LPVOID lp)
{
   for (;;)
      {
      AfsAdmSvr_Enter();

      BOOL fShutdown = l.fAutoShutdown;

      // If there are any clients connected, forcably disconnect any
      // that haven't pinged us for too long
      //
      for (size_t iClient = 0; iClient < l.cClientsAllocated; ++iClient)
         {
         if (!l.aClients[ iClient ])
            continue;
         if (l.aClients[ iClient ]->timeLastPing + cminREQ_CLIENT_PING <= AfsAdmSvr_GetCurrentTime())
            {
            Print (dlCONNECTION, "Client 0x%08lX idle for too long; detaching", l.aClients[ iClient ]);
            AfsAdmSvr_DetachClient ((UINT_PTR)l.aClients[ iClient ]);
            }
         }

      // If any operations are in progress, we can't shutdown.
      //
      if (l.cOperations)
         fShutdown = FALSE;

      // If any clients are still connected, we can't shutdown.
      //
      if (l.cClients)
         fShutdown = FALSE;

      // If we haven't been idle long enough, we can't shutdown
      //
      if (!l.timeLastIdleStart)
         fShutdown = FALSE;
      else if (l.timeLastIdleStart + cminAUTO_SHUTDOWN > AfsAdmSvr_GetCurrentTime())
         fShutdown = FALSE;

      // That's it; can we stop now?
      //
      if (fShutdown)
         {
         Print ("Idle for too long; shutting down.");
         RpcMgmtStopServerListening (NULL);
         AfsAdmSvr_StopCallbackManagers();
         }

      AfsAdmSvr_Leave();

      if (fShutdown)
         break;

      Sleep (cminAUTO_SHUTDOWN_SLEEP * 60L * 1000L);
      }

   return 0;
}
PVOID Leave_NULL_ (ULONG status, ULONG *pStatus, size_t iOp)
{
   AfsAdmSvr_Leave();
   if (pStatus)
      *pStatus = status;
   if (iOp != (size_t)-2)
      AfsAdmSvr_EndOperation (iOp);
   return NULL;
}
BOOL Leave_TRUE_ (ULONG *pStatus, size_t iOp)
{
   AfsAdmSvr_Leave();
   if (pStatus)
      *pStatus = 0;
   if (iOp != (size_t)-2)
      AfsAdmSvr_EndOperation (iOp);
   return TRUE;
}
BOOL Leave_FALSE_ (ULONG status, ULONG *pStatus, size_t iOp)
{
   AfsAdmSvr_Leave();
   if (pStatus)
      *pStatus = status;
   if (iOp != (size_t)-2)
      AfsAdmSvr_EndOperation (iOp);
   return FALSE;
}
void AfsAdmSvr_StopCallbackManagers (void)
{
   AfsAdmSvr_Enter();
   if (l.cManagers)
      {
      l.fStopManagers = TRUE;
      SetEvent (l.heCallback);
      }
   AfsAdmSvr_Leave();
}
Example #9
0
      // AfsAdmSvr_Ping
      // ...reminds the admin server that the specified client is still around.
      //    this call should be made at least every csecAFSADMSVR_CLIENT_PING
      //    seconds, lest the admin server think you've disconnected. (The
      //    client library TaAfsAdmSvrClient.lib automatically handles this.)
      //
extern "C" int AfsAdmSvr_Ping (UINT_PTR idClient, ULONG *pStatus)
{
   AfsAdmSvr_Enter();

   if (!AfsAdmSvr_fIsValidClient (idClient))
      return Leave_FALSE_(ERROR_INVALID_PARAMETER, pStatus);

   AfsAdmSvr_PingClient (idClient);
   AfsAdmSvr_Leave();
   return TRUE;
}
BOOL AfsAdmSvr_GetOperation (DWORD idAction, LPASACTION pAction)
{
   AfsAdmSvr_Enter();

   for (size_t iOp = 0; iOp < l.cOperationsAllocated; ++iOp)
      {
      if (!l.aOperations[ iOp ].fInUse)
         continue;
      if (!l.aOperations[ iOp ].pAction)
         continue;
      if (l.aOperations[ iOp ].pAction->idAction != idAction)
         continue;

      memcpy (pAction, l.aOperations[ iOp ].pAction, sizeof(ASACTION));
      pAction->csecActive = (GetTickCount() - l.aOperations[ iOp ].dwTickStart) / 1000;
      AfsAdmSvr_Leave();
      return TRUE;
      }

   AfsAdmSvr_Leave();
   return FALSE;
}
void AfsAdmSvr_EnableAutoShutdown (BOOL fEnable)
{
   AfsAdmSvr_Enter();

   l.fAutoShutdown = fEnable;

   if (fEnable)
      Print (dlDETAIL, TEXT("Auto-shutdown enabled, trigger = %lu minutes idle time"), cminAUTO_SHUTDOWN);
   else
      Print (dlDETAIL, TEXT("Auto-shutdown on idle disabled"));

   AfsAdmSvr_Leave();
}
void AfsAdmSvr_PingClient (UINT_PTR idClient)
{
   AfsAdmSvr_Enter();

   for (size_t iClient = 0; iClient < l.cClientsAllocated; ++iClient)
      {
      if (idClient == (UINT_PTR)(l.aClients[ iClient ]))
         {
         l.aClients[ iClient ]->timeLastPing = AfsAdmSvr_GetCurrentTime();
         }
      }

   AfsAdmSvr_Leave();
}
Example #13
0
      // AfsAdmSvr_Disconnect
      // ...releases and invalidates the cookie representing the calling process.
      //
extern "C" int AfsAdmSvr_Disconnect (UINT_PTR idClient, ULONG *pStatus)
{
   AfsAdmSvr_Enter();

   // Make sure this is a valid client, and free its l.aClients[] entry if so.
   //
   if (!AfsAdmSvr_fIsValidClient (idClient))
      return Leave_FALSE_(ERROR_INVALID_PARAMETER, pStatus);

   Print (TEXT("Disconnected from client %s (ID 0x%08lX)"), AfsAdmSvr_GetClientName (idClient), idClient);

   AfsAdmSvr_DetachClient (idClient);
   AfsAdmSvr_Leave();
   return TRUE;
}
BOOL AfsAdmSvr_fIsValidClient (UINT_PTR idClient)
{
   BOOL rc = FALSE;
   AfsAdmSvr_Enter();

   for (size_t iClient = 0; !rc && iClient < l.cClientsAllocated; ++iClient)
      {
      if (idClient == (UINT_PTR)l.aClients[ iClient ])
         {
         if (l.aClients[ iClient ]->timeLastPing + cminREQ_CLIENT_PING > AfsAdmSvr_GetCurrentTime())
            rc = TRUE;
         }
      }

   AfsAdmSvr_Leave();
   return rc;
}
void AfsAdmSvr_DetachClient (UINT_PTR idClient)
{
   AfsAdmSvr_Enter();
   size_t iClient;
   for (iClient = 0; iClient < l.cClientsAllocated; ++iClient)
      {
      if (idClient == (UINT_PTR)(l.aClients[ iClient ]))
         break;
      }
   if (iClient < l.cClientsAllocated)
      {
      Delete (l.aClients[ iClient ]);
      l.aClients[ iClient ] = NULL;
      l.cClients --;
      }
   AfsAdmSvr_TestShutdown();
   AfsAdmSvr_Leave();
}
LPCTSTR AfsAdmSvr_GetClientName (UINT_PTR idClient)
{
   static TCHAR szName[ cchSTRING ];
   LPCTSTR pszName = NULL;
   AfsAdmSvr_Enter();

   for (size_t iClient = 0; !pszName && iClient < l.cClientsAllocated; ++iClient)
      {
      if (idClient == (UINT_PTR)(l.aClients[ iClient ]))
         {
         lstrcpy (szName, l.aClients[ iClient ]->szName);
         pszName = szName;
         }
      }

   AfsAdmSvr_Leave();
   return pszName;
}
LPSOCKADDR_IN AfsAdmSvr_GetClientAddress (UINT_PTR idClient)
{
   static SOCKADDR_IN ipAddress;
   LPSOCKADDR_IN pAddress = NULL;
   AfsAdmSvr_Enter();

   for (size_t iClient = 0; !pAddress && iClient < l.cClientsAllocated; ++iClient)
      {
      if (idClient == (UINT_PTR)(l.aClients[ iClient ]))
         {
         memcpy (&ipAddress, &l.aClients[ iClient ]->ipAddress, sizeof(SOCKADDR_IN));
         pAddress = &ipAddress;
         }
      }

   AfsAdmSvr_Leave();
   return pAddress;
}
void AfsAdmSvr_EndOperation (size_t iOp)
{
   AfsAdmSvr_Enter();

   if ((iOp != (size_t)-1) && (iOp < l.cOperationsAllocated) && (l.aOperations[ iOp ].fInUse))
      {
      if (l.aOperations[ iOp ].pAction)
         {
         Print (dlOPERATION, TEXT("Ending action 0x%08lX"), l.aOperations[ iOp ].pAction->idAction);
         AfsAdmSvr_PostCallback (cbtACTION, TRUE, l.aOperations[ iOp ].pAction);
         Delete (l.aOperations[ iOp ].pAction);
         }
      memset (&l.aOperations[ iOp ], 0x00, sizeof(l.aOperations[ iOp ]));
      l.cOperations --;
      }

   AfsAdmSvr_TestShutdown();
   AfsAdmSvr_Leave();
}
void AfsAdmSvr_PostCallback (CALLBACKTYPE Type, BOOL fFinished, LPASACTION pAction, DWORD dwRemoveMe)
{
   AfsAdmSvr_Enter();
   if (l.pListCallbacks)
      {
      LPCALLBACKDATA pData = New (CALLBACKDATA);
      memset (pData, 0x00, sizeof(CALLBACKDATA));
      pData->Type = Type;
      pData->fFinished = fFinished;
      if (pAction)
         {
         pData->pAction = New (ASACTION);
         memcpy (pData->pAction, pAction, sizeof(ASACTION));
         }

      l.pListCallbacks->Add (pData);
      SetEvent (l.heCallback);
      }
   AfsAdmSvr_Leave();
}
void AfsAdmSvr_CallbackManager (void)
{
   AfsAdmSvr_Enter();
   if ((++l.cManagers) == 1)
      {
      l.heCallback = CreateEvent (NULL, TRUE, FALSE, TEXT("AfsAdmSvr_CallbackManager Event"));
      l.pListCallbacks = New (HASHLIST);
      }
   AfsAdmSvr_Leave();

   for (;;)
      {
      WaitForSingleObjectEx (l.heCallback, INFINITE, FALSE);

      if (l.fStopManagers)
         break;

      // We must ensure that we don't block the server's operations because
      // a callback doesn't go through; since other operations may need
      // access to the l.pListCallbacks structure in order to queue new
      // callbacks, we can't leave it locked by issuing callbacks while
      // enumerating it. Instead we'll copy the list into a local copy,
      // clear it, and enumerate that local copy--other threads can then
      // continue to add new requests to l.pListCallbacks.
      //
      AfsAdmSvr_Enter();

      LPHASHLIST pList = New (HASHLIST);
      LPENUM pEnum;
      for (pEnum = l.pListCallbacks->FindFirst(); pEnum; pEnum = pEnum->FindNext())
         {
         LPCALLBACKDATA pData = (LPCALLBACKDATA)( pEnum->GetObject() );
         pList->Add (pData);
         l.pListCallbacks->Remove (pData);
         }

      ResetEvent (l.heCallback);
      AfsAdmSvr_Leave();

      // Now enumerate that copied list, and issue callbacks for each item.
      //
      for (pEnum = pList->FindFirst(); pEnum; pEnum = pEnum->FindNext())
         {
         LPCALLBACKDATA pData = (LPCALLBACKDATA)( pEnum->GetObject() );

         try {
            switch (pData->Type)
               {
               case cbtACTION:
                  AfsAdmSvrCallback_Action (pData->pAction, pData->fFinished);
                  break;
               }
         } catch(...) {
            ;
         }

         pList->Remove (pData);
         AfsAdmSvr_FreeCallbackData (pData);
         }

      Delete (pList);
      }

   AfsAdmSvr_Enter();
   if ((--l.cManagers) == 0)
      {
      Delete (l.pListCallbacks);
      l.pListCallbacks = NULL;
      CloseHandle (l.heCallback);
      l.heCallback = NULL;
      }
   AfsAdmSvr_Leave();
}
size_t AfsAdmSvr_BeginOperation (UINT_PTR idClient, LPASACTION pAction)
{
   AfsAdmSvr_Enter();

   ++l.cOperations;

   size_t iOp;
   for (iOp = 0; iOp < l.cOperationsAllocated; ++iOp)
      {
      if (!l.aOperations[ iOp ].fInUse)
         break;
      }
   if (!REALLOC (l.aOperations, l.cOperationsAllocated, 1+iOp, cREALLOC_OPERATIONS))
      {
      AfsAdmSvr_Leave();
      return (size_t)(-1);
      }

   l.aOperations[ iOp ].idClient = idClient;
   l.aOperations[ iOp ].pAction = NULL;
   l.aOperations[ iOp ].fInUse = TRUE;

   if (pAction)
      {
      l.aOperations[ iOp ].pAction = New (ASACTION);
      memcpy (l.aOperations[ iOp ].pAction, pAction, sizeof(ASACTION));
      l.aOperations[ iOp ].pAction->idAction = ++l.idActionLast;
      l.aOperations[ iOp ].pAction->idClient = idClient;
      l.aOperations[ iOp ].pAction->csecActive = 0;

      TCHAR szDesc[256];
      switch (l.aOperations[ iOp ].pAction->Action)
         {
         case ACTION_REFRESH:
            wsprintf (szDesc, TEXT("Refresh (scope=0x%08lX)"), l.aOperations[ iOp ].pAction->u.Refresh.idScope);
            break;
         case ACTION_SCOUT:
            wsprintf (szDesc, TEXT("Scout (scope=0x%08lX)"), l.aOperations[ iOp ].pAction->u.Refresh.idScope);
            break;
         case ACTION_USER_CHANGE:
            wsprintf (szDesc, TEXT("ChangeUser (user=0x%08lX)"), l.aOperations[ iOp ].pAction->u.User_Change.idUser);
            break;
         case ACTION_USER_PW_CHANGE:
            wsprintf (szDesc, TEXT("SetUserPassword (user=0x%08lX)"), l.aOperations[ iOp ].pAction->u.User_Pw_Change.idUser);
            break;
         case ACTION_USER_UNLOCK:
            wsprintf (szDesc, TEXT("UnlockUser (user=0x%08lX)"), l.aOperations[ iOp ].pAction->u.User_Unlock.idUser);
            break;
         case ACTION_USER_CREATE:
            wsprintf (szDesc, TEXT("CreateUser (user=%s)"), l.aOperations[ iOp ].pAction->u.User_Create.szUser);
            break;
         case ACTION_USER_DELETE:
            wsprintf (szDesc, TEXT("CreateUser (user=0x%08lX)"), l.aOperations[ iOp ].pAction->u.User_Delete.idUser);
            break;
         case ACTION_GROUP_CHANGE:
            wsprintf (szDesc, TEXT("ChangeGroup (group=0x%08lX)"), l.aOperations[ iOp ].pAction->u.Group_Change.idGroup);
            break;
         case ACTION_GROUP_MEMBER_ADD:
            wsprintf (szDesc, TEXT("AddGroupMember (group=0x%08lX, user=0x%08lX)"), l.aOperations[ iOp ].pAction->u.Group_Member_Add.idGroup, l.aOperations[ iOp ].pAction->u.Group_Member_Add.idUser);
            break;
         case ACTION_GROUP_MEMBER_REMOVE:
            wsprintf (szDesc, TEXT("RemoveGroupMember (group=0x%08lX, user=0x%08lX)"), l.aOperations[ iOp ].pAction->u.Group_Member_Remove.idGroup, l.aOperations[ iOp ].pAction->u.Group_Member_Remove.idUser);
            break;
         case ACTION_GROUP_RENAME:
            wsprintf (szDesc, TEXT("RenameGroup (group=0x%08lX, new name=%s)"), l.aOperations[ iOp ].pAction->u.Group_Rename.idGroup, l.aOperations[ iOp ].pAction->u.Group_Rename.szNewName);
            break;
         case ACTION_GROUP_DELETE:
            wsprintf (szDesc, TEXT("CreateGroup (group=0x%08lX)"), l.aOperations[ iOp ].pAction->u.Group_Delete.idGroup);
            break;
         case ACTION_CELL_CHANGE:
            wsprintf (szDesc, TEXT("ChangeCell (cell=0x%08lX)"), l.aOperations[ iOp ].pAction->idCell);
            break;
         default:
            wsprintf (szDesc, TEXT("Unknown Action (#%lu)"), l.aOperations[ iOp ].pAction->Action);
            break;
         }
      Print (dlOPERATION, TEXT("Starting action 0x%08lX: %s"), l.aOperations[ iOp ].pAction->idAction, szDesc);

      AfsAdmSvr_PostCallback (cbtACTION, FALSE, l.aOperations[ iOp ].pAction);
      }

   l.aOperations[ iOp ].dwTickStart = GetTickCount();
   AfsAdmSvr_Leave();
   return iOp;
}