/*  File: areasamp.c  */

/*****************************************************************************/
/*                                                                           */
/*                                                                           */
/*   ©Copyright  2009 – 2012 BMC Software, Inc.                              */
/*   BMC, BMC Software, the BMC logos and other BMC marks are trademarks or  */
/*   registered trademarks of BMC Software, Inc. in the U.S. and /or         */
/*   certain other countries.                                                */
/*****************************************************************************/

#ifdef _WIN32
#include <windows.h>
#endif /* _WIN32 */

#include <stdlib.h>
#include <string.h>

#include "area.h"

/*****************************************************************************/
/*                                                                           */
/*       Action Request System External Authentication (AREA) Sample         */
/*                                                                           */
/*****************************************************************************/
/* Description: This is a sample external authentication plug-in.  It is     */
/*    intended for use by AR System customers in implementing a customized      */
/*    authentication plug-in.                                                */
/*                                                                           */
/*    This sample allows the user "Good User" to log in and acquire a        */
/*    floating license if one is available.  The user "Bad User" is not      */
/*    allowed to login.  Any other users are unknown and it is up to the     */
/*    AR System server to log the user in as a guest user.                   */
/*                                                                           */
/*****************************************************************************/

#ifdef _WIN32
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
   return TRUE;
}

#endif /* _WIN32 */

/*****************************************************************************/
/*                                                                           */
/*                             ARPluginIdentify                              */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called by the plug-in service to identify   */
/*    what type of plug-in this implements.                                  */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT int ARPluginIdentify(
ARPluginIdentification *id,     /* OUT; information about the plug-in */
ARStatusList           *status  /* OUT; error message(s)*/
)
{
   id->type = AR_PLUGIN_TYPE_AREA;
   strcpy(id->name, "EXAMPLE.AREA.SIMPLE");
   id->version = AREA_PLUGIN_VERSION;
   memset(status, 0, sizeof(*status));

   return AR_RETURN_OK;
}


/*****************************************************************************/
/*                                                                           */
/*                          ARPluginInitialization                           */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called by the plug-in service to initilize  */
/*    the plug-in.  This is where the plug-in should initialize any data     */
/*    that will be global and accessed by all instances of the plug-in that  */
/*    are created via ARPluginCreateInstance().                              */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT int ARPluginInitialization(
int argc,             /*  IN; argc from main() */
char **argv,          /*  IN; argv from main() */
ARStatusList *status
)
{
   if (status != NULL)
      memset(status, 0, sizeof(*status));

   return AR_RETURN_OK;
}


/*****************************************************************************/
/*                                                                           */
/*                          ARPluginTermination                              */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called by the plug-in service to terminate  */
/*    the plug-in.  This is where the plug-in should deallocate any          */
/*    resources that have been allocated either globally or by each instance */
/*    created by ARPluginCreateInstance().                                   */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT int ARPluginTermination(
ARStatusList *status        /* OUT; status of the operation */
)
{
   if (status != NULL)
      memset(status, 0, sizeof(*status));
   
   return AR_RETURN_OK;
}


/*****************************************************************************/
/*                                                                           */
/*                          ARPluginCreateInstance                           */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called by the plug-in service to create an  */
/*    instance of the plug-in.  Each instance is guaranteed to be involved   */
/*    in one thread of operation at any one time.                            */
/*                                                                           */
/*    The structure returned via the 'object' pointer will be provided in    */
/*    subsequent plug-in calls.  This allows you to attach arbitrary data    */
/*    to an instance that will be inherently thread safe.                    */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT int ARPluginCreateInstance(
void         **object,   /* OUT; plug-in instance */
ARStatusList  *status    /* OUT; status of the operation */
)
{
   if (status != NULL)
      memset(status, 0, sizeof(*status));

   if (object != NULL)
   {
      /*
       * Set *object to point to something that you have 
       * allocated and initialized.
       */
      *object = NULL;
   }

   return AR_RETURN_OK;
}


/*****************************************************************************/
/*                                                                           */
/*                          ARPluginDeleteInstance                           */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called by the plug-in service to delete an  */
/*    instance of the plug-in.  Each instance is guaranteed to be involved   */
/*    in one thread of operation at any one time.                            */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT int ARPluginDeleteInstance(
void         *object,  /* IN;  plug-in instance to delete*/
ARStatusList *status   /* OUT; status of the operation */
)
{
   if (object != NULL)
   {
      /*
       * Anything that you allocated in ARPluginCreateInstance
       * should be deallocated here.
       */
   }

   return AR_RETURN_OK;
}


/*****************************************************************************/
/*                                                                           */
/*                          AREAVerifyLoginCallback                          */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called whenever a request is made by the AR */
/*    System Server to authenticate a user.                                  */
/*                                                                           */
/*    The user name and password (unencrypted) are passed as parameters.     */
/*                                                                           */
/*    A customized authentication plug-in must define this function.  Any    */
/*    global information or resources accessed here must be protected with   */
/*    appropriate mutual exclusion locks to be multi-thread safe.            */
/*                                                                           */
/*    A customized authentication plug-in must return a response.  A NULL    */
/*    response will be interpreted as a failed login attempt.                */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT void AREAVerifyLoginCallback(
void                *object,         /* IN;  plug-in instance */
ARAccessNameType     user,           /* IN;  user name to authenticate */
ARPasswordType	     password,       /* IN;  user's password */
ARNameType	     networkAddr,    /* IN;  AR API client's IP address */
ARAuthType           authString,     /* IN;  used for misc. purposes */
AREAResponseStruct **response        /* OUT; success/fail login w/ info */
)
{
   *response = (AREAResponseStruct *) calloc (sizeof(AREAResponseStruct), 1);
   if (*response == NULL)
      return;
   
   if (strcmp(user, "Good User") == 0)
   {                                 /* Good User login is successful */
      (*response)->licenseMask  = AREA_LICENSE_MASK_ALL;
      (*response)->licenseWrite = AR_LICENSE_TYPE_FLOATING;
      (*response)->licenseFTS   = AR_LICENSE_TYPE_NONE;
      (*response)->licenseRes1  = AR_LICENSE_TYPE_NONE;
      (*response)->licenseApps  = NULL;
      (*response)->groups       = NULL;
      (*response)->notifyMech   = AR_NOTIFY_VIA_DEFAULT;
      (*response)->email        = NULL;
      (*response)->loginStatus  = AREA_LOGIN_SUCCESS;
      (*response)->messageText  = NULL;
      (*response)->logText      = NULL;
      (*response)->modTime      = 0;
   }
   else if (strcmp(user, "Bad User") == 0)
   {                                 /* Bad User login fails */
      (*response)->loginStatus  = AREA_LOGIN_FAILED;
      (*response)->messageText  = NULL;
      (*response)->logText      = NULL;
   }
   else
   {                                 /* otherwise, we do not know the user */
      (*response)->loginStatus  = AREA_LOGIN_UNKNOWN_USER;
      (*response)->messageText  = NULL;
      (*response)->logText      = NULL;
   }

   return;
}


/*****************************************************************************/
/*                                                                           */
/*                             AREANeedToSyncCallback                        */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called periodically at the request of the   */
/*    AR System server.                                                      */
/*                                                                           */
/*    A customized authentication plug-in must define this function.  Any    */
/*    global information or resources accessed here must be protected with   */
/*    appropriate mutual exclusion locks to be multi-thread safe.            */
/*                                                                           */
/*    A non-zero return value will instruct the AR System server to flush    */
/*    its cache of user information.                                         */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT int AREANeedToSyncCallback(
void              *object         /* IN; plug-in instance */
)
{
   return 0;
}


/*****************************************************************************/
/*                                                                           */
/*                               AREAFreeCallback                            */
/*                                                                           */
/*****************************************************************************/
/* Description: This function is called after a response is made to the AR   */
/*    System Server to authenticate a user.                                  */
/*                                                                           */
/*    A pointer to the response structure returned by                        */
/*    AREAVerifyLoginCallback() is passed as a parameter.                    */
/*                                                                           */
/*    A customized authentication plug-in must define this function.  Any    */
/*    global information or resources accessed here must be protected with   */
/*    appropriate mutual exclusion locks to be multi-thread safe.            */
/*                                                                           */
/*    A customized authentication plug-in must return a response.  A NULL    */
/*    response will be interpreted as a failed login attempt.                */
/*                                                                           */
/*****************************************************************************/

ARPLUGIN_EXPORT void AREAFreeCallback(
void                *object,    /* IN; plug-in instance */
AREAResponseStruct  *response   /* IN; if needed, free the response */
)
{
   /* Since we allocated the response in AREAVerifyLoginCallback(), we */
   /* should free it here.                                             */

   if (response != NULL)
      free (response);

   return;
}
