LDAP ObjectSID - Convert Base64 string to ObjectSID string

Johnny Chong1
Tera Contributor

As part of an SAP SSO integration project, our customer has a requirement to create an SAP user through ServiceNow automation where the Active Directory "ObjectSID" string needs to be sent across to uniquely identify an AD user.

As you are probably aware that ServiceNow LDAP import brings in ObjectSID into base64 string. This script converts it into Hexadecimal and followed by objectSID formation.

We have been searching for the community, but no luck with this. We have therefore spent a few hours on this and sharing this with you all for improvement or perhaps saving some of your precious time. We are sure the script can be improved and I hope you can share it with us in this forum for future reference.  Also, feel free to convert it to Script Includes.

We would like to thank the authors at the following 2 links as they help us a lot to understand how they are converted or formed.
http://www.selfadsi.org/deep-inside/microsoft-sid-attributes.htm
https://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hexadecimal-in-javascript

//======================================================================================

//To randomly generate some base64 string from random Hexadecimal, you can generate it from https://cryptii.com/pipes/base64-to-binary.  Here are some same base64 string generated randomly.

var source = "AQUAAAAAAAUVAAAAWUwLi17c7L1aBsrNrgQAAA=="; 
var hexaArrayString = base64ToHexa(source);
//Print out -> 01 05 00 00 00 00 00 05 15 00 00 00 59 4C 0B 8B 5E DC EC BD 5A 06 CA CD AE 04 00 00
gs.print(hexaArrayString.replace(/,/g," "));

var SIDArray = hexaArrayString.split(",");
var SID = hexaArrayToSID(SIDArray);
//Print out -> S-1-5-21-2332773465-3186416734-3452569178-1198
gs.print(SID);

function base64ToHexa (str){
    var decoded = GlideStringUtil.base64DecodeAsBytes(str);
    var n = decoded.length;
    if (n<16){
          return '';
    }
    var hexaArray = [];
    for (var i=0; i<n; i++) {
         var hexaStr = decimal2Hexadecimal(decoded[i]);
         hexaArray.push(hexaStr);
     }
     return hexaArray.toString();
}

function decimal2Hexadecimal (decimal) {
     var hexaStr = decToHex(decimal);

     if (hexaStr.length==3) {
          hexaStr = '0' + hexaStr.charAt(2);
     }
     else if (hexaStr.length==4) { // e.g. 0X42->42 or 0x5C->5C
          hexaStr = hexaStr.charAt(2) + hexaStr.charAt(3);
      }
     else {
          hexaStr = hexaStr.charAt(hexaStr.length-2) + hexaStr.charAt(hexaStr.length-1);
     }
     return hexaStr + '';
}

//Thanks to the author at
//http://www.selfadsi.org/deep-inside/microsoft-sid-attributes.htm
function hexaArrayToSID (arr){
     var revision = arr[0].toLowerCase();
     var subIDCount = arr[1].toLowerCase();
     var identifierAuthority = hexaToDecimal(arr.slice(2, 8).join('').toLowerCase()); //Not Required for NT, always 5
     var subID1 = hexaToDecimal(arr.slice(8, 11).reverse().join('').toLowerCase());
     var subID2 = hexaToDecimal(arr.slice(12, 16).reverse().join('').toLowerCase());
     var subID3 = hexaToDecimal(arr.slice(16, 20).reverse().join('').toLowerCase());
     var subID4 = hexaToDecimal(arr.slice(20, 24).reverse().join('').toLowerCase());
     //Relative ID - RID
     var subID5 = hexaToDecimal(arr.slice(24, 28).reverse().join('').toLowerCase());

     return "S-" + parseInt(revision) + "-" + parseInt(subIDCount) + "-" + subID1 + "-" + subID2 + "-" + subID3 + "-" + subID4 + "-" + subID5;
}


//Thanks to the author at
//https://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hexadecimal-in-javascript
function decToHex(decimal) { // Data (decimal)
     length = -1; // Base string length
     string = ''; // Source 'string'

     characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // character array

     do { // Grab each nibble in reverse order because JavaScript has no unsigned left shift
           string += characters[decimal & 0xF]; // Mask byte, get that character
           ++length; // Increment to length of string

     } while (decimal >>>= 4); // For next character shift right 4 bits, or break on 0

     decimal += 'x'; // Convert that 0 into a hex prefix string -> '0x'

     do {
          decimal += string[length];
     } while (length--); // Flip string forwards, with the prefixed '0x'

     return (decimal); // return (hexadecimal);
}

function hexaToDecimal (_hexaString) {
     return parseInt(_hexaString, 16);
}

 

1 ACCEPTED SOLUTION

Priyank Joshi2
Giga Contributor

Hi Phil,

I have worked with @Johnny Chong on this solution. Please find below information on how you can setup.

1. Setup the attached Script Include. ActiveDirectoryUtil.xml

2. For our solution we created a new field on sys_user table. You can use the existing field if available. 

  • Type: String
  • Label: ObjectSid
  • Name: u_objectsid
  • Max Lenght: 255

3. In your LDAP Transform Map add new Field Map and set the field Use source script to True.

    Add below code. Target field set to ObjectSid [u_objectsid]created in Step 2.

    I have attached the screenshot of the field map.

 

 

 

    

 

 

View solution in original post

8 REPLIES 8

Hi Phil,

Are you converting objectSid or objectGUID?

If its Objectguid than Script Include code will be different. 

Please provide one of you source, I can run background script and check.

like var source = "AQUAAAAAAAUVAAAAWUwLi17c7L1aBsrNrgQAAA=="; 

 

Regards,

Priyank

Hi Priyak,

Below is what I see and where for the same user.

--------------------------------

Import Set Table

s9GE2EDyB0OR7p2qCt9OEw==

--------------------------------

In Service Now the sys_user form in the employee number field

S-NaN-NaN-10350225-323936010-NaN-NaN-NaN

--------------------------------

Active Directory Attribute editor front screen

find_real_file.pngfind_real_file.png

--------------------------------

Active Directory Attribute editor (edit Screen)

find_real_file.png

--------------------------------

Actual Value from the edit screen

B3 D1 84 D8 40 F2 07 43 91 EE 9D AA 0A DF 4E 13

--------------------------------

Hope that helps and thanks for your assistance so far.

 

 

Hi Phil,

Please try with the below code in background script and see if it works for you and than you can update the script include.

From previous code I commented out line.

// var SIDArray = hexaArrayString.split(",");
// var SID = hexaArrayToSID(SIDArray);

 

*** Script: B3 D1 84 D8 40 F2 07 43 91 EE 9D AA 0A DF 4E 13
*** Script: \B3\D1\84\D8\40\F2\07\43\91\EE\9D\AA\0A\DF\4E\13

 

var source = "s9GE2EDyB0OR7p2qCt9OEw==";
var hexaArrayString = base64ToHexa(source);
//Print out -> 01 05 00 00 00 00 00 05 15 00 00 00 59 4C 0B 8B 5E DC EC BD 5A 06 CA CD AE 04 00 00
gs.print(hexaArrayString.replace(/,/g," "));

gs.print("\\" + hexaArrayString.replace(/,/g,"\\"));

// var SIDArray = hexaArrayString.split(",");
// var SID = hexaArrayToSID(SIDArray);
// //Print out -> S-1-5-21-2332773465-3186416734-3452569178-1198
// gs.print(SID);

function base64ToHexa (str){
var decoded = GlideStringUtil.base64DecodeAsBytes(str);
gs.print(decoded);
var n = decoded.length;
if (n<16){
return '';
}
var hexaArray = [];
for (var i=0; i<n; i++) {
var hexaStr = decimal2Hexadecimal(decoded[i]);
hexaArray.push(hexaStr);
}
return hexaArray.toString();
}

function decimal2Hexadecimal (decimal) {
var hexaStr = decToHex(decimal);

if (hexaStr.length==3) {
hexaStr = '0' + hexaStr.charAt(2);
}
else if (hexaStr.length==4) { // e.g. 0X42->42 or 0x5C->5C
hexaStr = hexaStr.charAt(2) + hexaStr.charAt(3);
}
else {
hexaStr = hexaStr.charAt(hexaStr.length-2) + hexaStr.charAt(hexaStr.length-1);
}
return hexaStr + '';
}

//Thanks to the author at
//http://www.selfadsi.org/deep-inside/microsoft-sid-attributes.htm
function hexaArrayToSID (arr){
gs.print(arr);
var revision = arr[0].toLowerCase();
var subIDCount = arr[1].toLowerCase();
var identifierAuthority = hexaToDecimal(arr.slice(2, 8).join('').toLowerCase()); //Not Required for NT, always 5
var subID1 = hexaToDecimal(arr.slice(8, 11).reverse().join('').toLowerCase());
var subID2 = hexaToDecimal(arr.slice(12, 16).reverse().join('').toLowerCase());
var subID3 = hexaToDecimal(arr.slice(16, 20).reverse().join('').toLowerCase());
var subID4 = hexaToDecimal(arr.slice(20, 24).reverse().join('').toLowerCase());
//Relative ID - RID
var subID5 = hexaToDecimal(arr.slice(24, 28).reverse().join('').toLowerCase());

return "S-" + parseInt(revision) + "-" + parseInt(subIDCount) + "-" + subID1 + "-" + subID2 + "-" + subID3 + "-" + subID4 + "-" + subID5;
}


//Thanks to the author at
//https://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hexadecimal-in-javascript
function decToHex(decimal) { // Data (decimal)
length = -1; // Base string length
string = ''; // Source 'string'

characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // character array

do { // Grab each nibble in reverse order because JavaScript has no unsigned left shift
string += characters[decimal & 0xF]; // Mask byte, get that character
++length; // Increment to length of string

} while (decimal >>>= 4); // For next character shift right 4 bits, or break on 0

decimal += 'x'; // Convert that 0 into a hex prefix string -> '0x'

do {
decimal += string[length];
} while (length--); // Flip string forwards, with the prefixed '0x'

return (decimal); // return (hexadecimal);
}

function hexaToDecimal (_hexaString) {
return parseInt(_hexaString, 16);
}

Hi Priyank,

Without following the process mentioned by you on 'mS_Ds_ConsistenctGuid' attribute. I saw below format in User form.

find_real_file.png

after I followed the process mentioned by you on 'mS_Ds_ConsistenctGuid' attribute. Show as below in User form.

find_real_file.png

Can you help me out here, should I comment 2 lines in script include you mentioned in the thread? or any other suggestion.

Thank you,