Friday, October 15, 2010

Validate Windows Service User Account

Hi Friends, in many of my projects, we need to create windows service, ask credentials for running the service. I spent a lot of time in my initial stage of profession for implementing it according to the choice of the user.


Scenario:
There was a scenario, where user needs to put a choice by means of installer, whether he needs to install an run the services on behalf of Local Account, or by entering the Windows Domain Account credentials for running the service.


Solution:
I write a Installscript custom action after a lot of R&D on net for the scenario when we ask custom credentials by user.


Description:
ValidateWindowsServiceUserAccount() -- custom function which we need to call from our script.
gsServiceAccountUserName -- global variable which i had used to store the credentials which were a mix of Domain + Windows account e.g. Domain\John.Natham.


function ValidateWindowsServiceUserAccount()
    OBJECT objDSO, objDomain;
    LIST listID;
    NUMBER iIndex, nResult;
    STRING sArray(), svString, strDomain, strWinServiceUser,szMsg;
begin
try
   set objDSO = CoGetObject("WinNT:","");
   if (!IsObject(objDSO)) then
      //MessageBox("Object NOT Created", 0);
   else
      //Break User name in domain and user
      listID = ListCreate (STRINGLIST);      
      if (StrGetTokens (listID, gsServiceAccountUserName, "\\") < 0) then
         //Error
      else
         //Success
         iIndex=0;
         nResult = ListGetFirstString(listID, svString);
         while (nResult != END_OF_LIST)
              //nitems=nitems+1;
              Resize(sArray,iIndex+1);
              sArray(iIndex)=svString;
              iIndex = iIndex+1;
              nResult = ListGetNextString (listID, svString);
         endwhile;
      endif;      
      ListDestroy (listID);
      strDomain = sArray(0);
      strWinServiceUser = sArray(1);
      //
      set objDomain = objDSO.OpenDSObject("WinNT://" + strDomain,
                            strWinServiceUser, gsServiceAccountPassword, 1);

      gbValidWinServiceUser = TRUE;
      //set objDSO = Nothing
      //set objDomain = Nothing
   endif;
catch
    gbValidWinServiceUser = FALSE;
    //MessageBoxEx(Err.Number,"",INFORMATION);
   switch (Err.Number)
       case "-2147023570":
            szMsg = "Invalid user name or password.";
            ListAddString(gLIST_VALIDATION_ERROR,"- "+szMsg,AFTER);
            //MessageBoxEx("Invalid user name or password.","",SEVERE);
       case "-2147022987":
            szMsg = "User account is locked.";
            ListAddString(gLIST_VALIDATION_ERROR,"- "+szMsg,AFTER);
            //MessageBoxEx("User account is locked.","",SEVERE);
       case "-2147023565":
            szMsg = "User account is disabled.";
            ListAddString(gLIST_VALIDATION_ERROR,"- "+szMsg,AFTER);
       default:
            szMsg = "Unknown error, unable to verify credentials.";
            ListAddString(gLIST_VALIDATION_ERROR,"- "+szMsg,AFTER);
    endswitch;
endcatch;
end;