There is a javascript library for Active Roles.
For use it, create a wsf-file:
<package>
<job>
<script language="JScript" src="modules/basic.js"/>
<script language="JScript" src="modules/ars.js"/>
<script language="JScript" >
..... code is here ......
</script>
</job>
</package>
And write your code.
WScript.Echo("Creating User Accounts");
// This code snippet illustrates how to create a user account in the specified OU.
// The script enables the newly created user.
var ARS = new ArsProvider();
ARS.bind = {server: "frodo.shir.msk.qsft", login: "SHIR\\Administrator", password: "kuku01"};
var container = ARS.ArsEntry("OU=Mordor,OU=Middle-earth,DC=shir,DC=msk,DC=qsft")
var user = IContainer(container).Create("user", "Ork442353")
user.InvokeSet("sAMAccountName", "Ork442353")
user.InvokeSet("userPrincipalName", "Ork442353@mordor.com")
user.InvokeSet("edsaNormalAccount", true)
user.InvokeSet("edsaAccountIsDisabled", false)
IUser(user).SetPassword("ZXcvbn78")
user.CommitChanges()
WScript.Echo("Done.");
basic.js
//********************************************************************************
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
//
// IF YOU WANT THIS FUNCTIONALITY TO BE CONDITIONALLY SUPPORTED,
// PLEASE CONTACT ONE IDENTITY PROFESSIONAL SERVICES.
//*********************************************************************************
// ============================================================================
// Interface for Active Roles script modules
// ============================================================================
// Using:
// Interface for Active Roles script modules
// var QCD = ScriptLib.Load("Script Modules/.../basic.js")
// QCD.Extend(VBArray, Error, String, Array)
function Extend()
{
for (var i = 0; i < arguments.length; i++)
{
var extendedObj = arguments
if (typeof extendedObj == 'function')
switch (Object.ConstructorName(extendedObj))
{
default: break
case "Object":
extendedObj.ConstructorName = Object.ConstructorName
break
case "VBArray":
extendedObj.Parse = VBArray.parse
extendedObj.parse = VBArray.parse
extendedObj.count = VBArray.count
break
case "Error":
extendedObj.prototype.HResult = Error.prototype.HResult
extendedObj.prototype.toString = Error.prototype.toString
break
case "String":
extendedObj.prototype.Trim = String.prototype.Trim
extendedObj.prototype.Quoted = String.prototype.Quoted
extendedObj.Empty = String.Empty
break
case "Array":
extendedObj.IndexOf = Array.IndexOf
extendedObj.CaseIgnoredOrder = Array.CaseIgnoredOrder
break
case "Boolean":
extendedObj.Parse = Boolean.Parse
break
}
}
}
// ============================================================================
// Extend base classes
// ============================================================================
// ----------------------------------------------------------------------------
// Object
// ----------------------------------------------------------------------------
Object.ConstructorName = function(func)
{
if (typeof func != 'function')
throw Error("[Object.ConstuctorName] Arguments is not a function.")
if (func.toString().search(/^\nfunction (\w+)/i) == 0)
return RegExp.$1
throw Error("[Object.ConstuctorName] Funciton has the emtpy constructor.")
};
// ----------------------------------------------------------------------------
// VBArray
// ----------------------------------------------------------------------------
(function()
{
var dic = new ActiveXObject("Scripting.Dictionary");
//
// Returns safe array from JavaScript array
//
// Example of an using,
// var safeArray1 = VBArray.parse(["A", "B", "C"]) // returns an array has 3 items
// var safeArray2 = VBArray.parse("A", "B", "C") // returns an array has 3 items
VBArray.parse = function()
{
dic.RemoveAll();
var a = arguments;
if (1 == a.length && "object" == typeof a[0] && Array == a[0].constructor)
a = a[0];
for (var i = 0; i < a.length; i++)
dic.Add(i, a);
return dic.Items()
};
// depricated
VBArray.Parse = VBArray.parse
//
// Returns JavaScript array from a safe array.
//
// Example of an using,
// var array1 = VBArray.toArray(safeArray)
VBArray.toArray = function()
{
if (arguments.length == null || arguments[0] == null)
return null
var temp = new VBArray(arguments[0])
return temp.toArray()
};
//
// Returns a length of a VBArray instance
//
// Example of an using,
// var count = VBArray.parse(["A", "B", "C"]).count() // it equals: ["A", "B", "C"].length
VBArray.prototype.count = function()
{
return (1 + this.ubound() - this.lbound())
};
}
)();
// ----------------------------------------------------------------------------
// Error
// ----------------------------------------------------------------------------
Error.prototype.HResult = function()
{
var lowPart = this.number & 0xFFFF
var hiPart = this.number >>> 16
return hiPart * 0x10000 + lowPart
}
Error.prototype.toString = function()
{
return "Error 0x" + this.HResult().toString(16).toUpperCase() + ": " + this.message
}
// ----------------------------------------------------------------------------
// String
// ----------------------------------------------------------------------------
String.prototype.Trim = function()
{
return this.replace(/(^\s+)|(\s+$)/g, "")
}
String.prototype.Quoted = function(/* char */ quote)
{
if (quote == null) quote = "\""
return quote + this + quote
}
String.Empty = ""
// ----------------------------------------------------------------------------
// Array
// ----------------------------------------------------------------------------
Array.IndexOf = function(/* array */ arr, value)
{
for (var i = 0; i < arr.length; i++)
if (arr == value) return i
return -1
}
Array.CaseIgnoredOrder = function(ai, bi)
{
// lexico case-ignored order
var a = ai.toLowerCase()
var b = bi.toLowerCase()
if (a == b)
return (ai == bi)? 0 : (ai > bi)? 1 : -1
return (a > b)? 1 : -1
}
// ----------------------------------------------------------------------------
// Boolean
// ----------------------------------------------------------------------------
// resolve value to boolean type
Boolean.Parse = function(obj)
{
if (obj === undefined)
throw new Error("[Boolean.Parse] Argument is undefined.")
switch (typeof obj)
{
case 'boolean':
return obj
case 'object': // (obj === null)
case 'array':
case 'function':
case 'undefined':
case 'unknown':
default:
throw new Error("[Boolean.Parse] Argument cannot be resolve.")
case 'string':
if (obj.Trim().toLowerCase() == 'true') return true
if (obj.Trim().toLowerCase() == 'false') return false
var numberObj = parseInt(obj)
if (numberObj == NaN)
throw new Error("[Boolean.Parse] Argument string " + obj.Quoted() + " cannot be resolve.")
return numberObj? true : false
case 'number':
return obj? true : false
}
}
ars.js
// This module requires extended basic objects from "basic.js"
// ================================================================================================
// Content
// class ArsProvider
// class ArsSearch
// class ArsEntry
// class ArsLookup
// class MembershipRule
// inteface IUser
// inteface IEnumerator
// inteface IContainer
// inteface IGroup
// inteface IDynamicGroup
// inteface IManagedUnit
// inteface IVirtualAttribute
// object ArsAttributes
// object EventLog
// object Octet
// enum IADsPropertyValue
// function EscapeSlash(text)
// function ParseDN(path)
// ================================================================================================
// Release
// ------------------------------------------------------------------------------------------------
// ArsProvider class
// ------------------------------------------------------------------------------------------------
// Constructors
// ArsProvider()
// ArsProvider({server: <host>, login: <username>, password: <password>})
// Properties
// bind
// Methods
// ProviderVersion()
// ServiceVersion()
// Connect()
// ConfigurationDN()
// ReConnect()
// Test()
// IsBound()
// GetObject()
// Exists()
// toString()
// also
// ArsEntry(DN)
// ArsLookup()
// ArsSearch()
//
function ArsProvider(/* {server: "", login: "", password: ""} */ bind)
{
var theArsProvider = this
this.bind = { server: 'localhost', login: String.Empty, password: String.Empty }
if (bind != null)
{
if (bind.hasOwnProperty("server")) this.bind.server = bind.server
if (bind.hasOwnProperty("login")) this.bind.login = bind.login
if (bind.hasOwnProperty("password")) this.bind.password = bind.password
}
var provider = null
function GetProvider()
{
if (provider == null)
provider = GetObject("EDMS:")
return provider
}
this.ProviderVersion = function()
{
try
{
GetProvider()
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument")
xmlDoc.async = false
xmlDoc.resolveExternals = false
xmlDoc.loadXML(provider.VersionInfo)
return String(xmlDoc.selectSingleNode("//VersionInfo/ProductVersion").text)
}
catch (e)
{
throw new Error(e.number, "\n[ArsProvider.ProviderVersion] " + "\n" + e)
}
}
this.ServiceVersion = function()
{
if (rootDSE == null) theArsProvider.Connect()
try
{
var ver = theArsProvider.GetObject(rootDSE.Get("edsaVersionInfoDN"))
ver.GetInfoEx(VBArray.Parse(["edsaVersionProductVersion"]), 0)
return String(ver.Get("edsaVersionProductVersion"))
}
catch (e)
{
throw new Error(e.number, "\n[ArsProvider.ServiceVersion] " + "\n" + e)
}
}
var rootDSE = null
this.Connect = function()
{
// The method doesn't get a garanitee to it connects to ARS.
// Use method Test() for check connection.
var connectionString = "EDMS://" + theArsProvider.bind.server + "/rootDSE"
try
{
GetProvider()
rootDSE = provider.OpenDSObject(connectionString, theArsProvider.bind.login, theArsProvider.bind.password, /* ADS_EDMSERVER_BIND */ 32768)
}
catch(e)
{
if (e.HResult() == 0x80041455) // The ActiveRoles Administration Service is not available on...
e.message = e.message.substr(e.message.indexOf("\n")).Trim()
throw new Error(e.number, "\n[ArsProvider.Connect] ActiveRoles Service is unavailable on the server " +
String(theArsProvider.bind.server).Quoted() +
(theArsProvider.bind.login != String.Empty? " (by " + String(theArsProvider.bind.login).Quoted() + ")" : String.Empty) +
"\n" + e)
}
}
var confDn = null // cache
this.ConfigurationDN = function()
{
if (rootDSE == null) theArsProvider.Connect()
if (confDn != null)
return confDn
try
{
confDn = String(rootDSE.Get('edsaEDMConfigurationDN'))
return confDn
}
catch (e)
{
throw new Error(e.number, "\n[ArsProvider.ConfigurationDN]\n" + e)
}
}
this.ReConnect = function()
{
try
{
this.GetObject(this.ConfigurationDN()).RefreshSchema()
//this.GetObject("CN=Active Directory").RefreshSchema()
}
catch(e)
{
throw new Error(e.number, "\n[ArsProvider.ReConnect]\n" + e)
}
}
this.Test = function()
{
// Test request to server.
try
{
this.GetObject(this.ConfigurationDN()).RefreshSchema()
return true
}
catch(e)
{
return e
}
}
this.IsBound = function()
{
return (rootDSE == null? false : true)
}
this.GetObject = function(/* string */ dn)
{
if (rootDSE == null) this.Connect()
try
{
dn = ParseDN(dn)
dn = EscapeSlash(dn)
var connectionString = "EDMS://" + this.bind.server + "/" + dn
return provider.OpenDSObject(connectionString, this.bind.login, this.bind.password, /* ADS_EDMSERVER_BIND */ 32768)
}
catch(e)
{
var hresult = e.HResult()
if (hresult == 0x8007208D) // Directory object not found.
return null
if (hresult == 0x80040FA0) // The object not found.
return null
throw new Error(e.number, "\n[ArsProvider.GetObject] " + connectionString +
"\nService have returned a following error:\n" + e)
}
}
// Determines if the specified path represents an actual entry in the directory service.
this.Exists = /* boolean */ function(/* string */ dn)
{
if (rootDSE == null) this.Connect()
try
{
var obj = theArsProvider.GetObject(dn)
return (obj == null)? false : true
}
catch(e)
{
var hresult = e.HResult()
if (hresult == 0x8007208D) // Directory object not found.
return false
if (hresult == 0x80040FA0) // The object not found.
return false
// MSDN:../adsi/adsi/common_errors.htm
if (hresult == 0x80005000) // An invalid ADSI pathname was passed.
return false
if (hresult == 0x8000500D) // The ADSI property cannot be found in the property cache.
return false
if (hresult == 0x800041E4) // Object not found. This error predominantly occurs due to misspelling the ADsPath string when binding to an object.
return false
throw new Error(e.number, "\n[ArsProvider.Exists] " + "\n" + e)
}
}
this.toString = function()
{
return "<ArsProvider server=" + this.bind.server.Quoted() + " login=" + this.bind.login.Quoted() + ">"
}
this.ArsEntry = function(/* string (dn) | object (adsi object) */ constuctObj)
{
return new ArsEntry(theArsProvider, constuctObj)
}
this.ArsLookup = function()
{
return new ArsLookup(theArsProvider)
}
this.ArsSearch = function()
{
return new ArsSearch(theArsProvider)
}
}
// ------------------------------------------------------------------------------------------------
// ArsSearch
// ------------------------------------------------------------------------------------------------
// Constructors
// ArsSearch(ArsProvider)
// Methods
// Execute(from, where, select, scope)
// ExecuteEx({from: <SourceDN>, where: <Filter>, select: <PropertyList>, scope: <Base|OneLevel|SubTree>})
//
function ArsSearch(/* ArsProvider */ ARS)
{
// An provider to ActiveRoles Server
var arsProvider = (ARS == null)? new ArsProvider() : ARS
var adodbConnection = null
function GetAdodbConnection(login, password)
{
if (adodbConnection != null) return adodbConnection
var adodbConnection = new ActiveXObject("ADODB.Connection")
adodbConnection.Provider = "ADsDSOObject"
adodbConnection.Properties("ADSI Flag") = /* ADS_EDMSERVER_BIND */ 32768
adodbConnection.Open("DS Query", login, password)
return adodbConnection
}
this.Execute = function(
/* string */ from,
/* string */ where,
/* string | array */ select,
/* string */ scope,
/* boolean */ sortBy)
{
// scope = (Base | OneLevel | SubTree | ...)
if (typeof select == Array)
select = select.join(",")
var command = new ActiveXObject("ADODB.Command")
command.ActiveConnection = GetAdodbConnection(arsProvider.bind.login, arsProvider.bind.password)
command.CommandText = "<EDMS://" + (arsProvider.bind.server? arsProvider.bind.server + "/" : '') +
from + ">;" +
where + ";" +
select + ";" +
scope
if (sortBy != null)
command.Properties("Sort on") = sortBy? "ASC" : "DESC"
try
{
return command.Execute()
}
catch(e)
{
throw new Error(e.number, "\n[ArsSearch.Search]\n" + "Query: " + command.CommandText + "\n" + e)
}
}
function CommandText(/* string */ server, /* string */ from, /* string */ where, /* string */ select, /* string */ scope)
{
return "<EDMS://" + (server? server + "/" : '') + from + ">;" +
where + ";" +
select + ";" +
scope
}
this.ExecuteEx = function(query)
/* { from: string,
where: string,
select: array,
scope: string, // base, oneLevel, subTree
*sortBy: string } */
{
var from = query.from // string
if (from == null || typeof from != 'string' || from === String.Empty)
throw new Error("\n[ArsSearch.SearchEx.InvalidArgument] " + "Argument 'from' is null or empty.")
var where = query.where // string
if (from == null || typeof from != 'string' || from === String.Empty)
throw new Error("\n[ArsSearch.SearchEx.InvalidArgument] " + "Argument 'where' is null or empty.")
var select = query.select // array
if (select == null || select.constructor == null || select.constructor != Array)
throw new Error("\n[ArsSearch.SearchEx.InvalidArgument] Argument 'select' must be array.")
var scope = query.scope // string
if (from == null || typeof from != 'string' || from === String.Empty)
throw new Error("\n[ArsSearch.SearchEx.InvalidArgument] " + "Argument 'scope' is null or empty.")
var sortBy = query.sortBy // boolean | string (ASC, DESC)
if ( typeof sortBy != 'string' )
sortBy == ''
var command = new ActiveXObject("ADODB.Command")
command.ActiveConnection = GetAdodbConnection(arsProvider.bind.login, arsProvider.bind.password)
command.CommandText = CommandText(arsProvider.bind.server, from, where, select.join(","), scope)
if (sortBy != null && sortBy !== String.Empty)
command.Properties("Sort on") = sortBy
try
{
var rs = command.Execute()
}
catch(e)
{
throw new Error(e.number, "\n[ArsSearch.SearchEx.Execute]\n" + "Query: " + command.CommandText + "\n" + e)
}
var result = []
try
{
if (rs.EOF) return []
for (rs.MoveFirst(); !rs.EOF; rs.MoveNext())
{
var obj = {}
for (var i = 0; i < select.length; i++)
obj[select] = rs.fields(i).value
result.push(obj)
}
}
catch(e)
{
throw new Error(e.number, "\n[ArsSearch.SearchEx.GetValues]\n" + e)
}
return result
}
}
// ------------------------------------------------------------------------------------------------
// ArsEntry
// ------------------------------------------------------------------------------------------------
// Constructors
// ArsEntry(ArsProvider, dn)
// ArsEntry(ArsProvider, adsiObject)
// Methods
// ArsProvider()
// NativeObject()
// InvokeGet(propertyName)
// RefreshCache(attributes)
// InvokeSet(propertyName, args)
// CommitChanges()
// Parent()
// DN()
// Name()
// MoveTo()
// Rename()
// Delete()
// toString()
//
function ArsEntry(/* ArsProvider */ ARS, /* string (dn) | object (adsi object) */ constuctObj)
{
// The value should be used in sub functions.
var theArsEntry = this
if (constuctObj == null || constuctObj === '')
throw new Error("\n[ArsEntry.Constructor] An argument is invalid.")
var inputDn
var adsiObject = null
if (typeof constuctObj == 'string')
inputDn = constuctObj // ASSERT: It isn't empty.
else
adsiObject = constuctObj // ASSERT: It isn't null.
// An provider to ActiveRoles Server
var arsProvider = (ARS == null)? new ArsProvider() : ARS
this.ArsProvider = function() { return arsProvider }
// Correspond an adsi object
this.NativeObject = function()
{
if (adsiObject != null)
return adsiObject
try
{
adsiObject = ARS.GetObject(inputDn)
return adsiObject
}
catch(e)
{
throw new Error(e.number, "\n[ArsEntry.NativeObject] " + "\n" + e)
}
}
function CastValue(value)
{
// return known-type values
if ((typeof value) != 'unknown') return value
var prop = theArsEntry.NativeObject().Item(propertyName)
// return ars specific values
switch (parseInt(prop.ADsType))
{
case /* ADSTYPE_OCTET_STRING */ 8:
case /* ADSTYPE_LARGE_INTEGER */ 10:
return value
default:
// conversion VBArray to JSArray
if (value.toArray)
return value.toArray()
// return as is
return value
}
}
this.InvokeGet = function(propertyName)
{
try
{
// // performs an implicit IADs::GetInfoEx
// if (theArsEntry.NativeObject().Item(propertyName) == null)
// theArsEntry.NativeObject().GetInfoEx(propertyName, 0)
// The IADs::GetEx method retrieves properties from the property cache.
// If the specified property is not found in the cache,
// IADs::GetEx performs an implicit IADs::GetInfo call.
var values = theArsEntry.NativeObject().GetEx(propertyName)
// The IADs::GetEx method returns a variant array of variants regardless of the number of values
// returned from the server. This is true even if the attribute only contains one value.
values = values.toArray()
for (var i = 0; i < values.length; i++)
values = CastValue(values)
return (values.length == 1)? values[0]: values
}
catch(e)
{
// If no value is set for the attribute, IADs::GetEx returns
// the error "Property not found in cache".
if (e.HResult() == /* property not found */ 0x8000500D)
return null
throw e
}
}
this.RefreshCache = function(/* empty | string | string[] */ attributes)
{
// allows syntax:
// .RefreshCache("attr1")
// .RefreshCache(["attr1", "attr2", "attr3"])
if (typeof attributes == 'string')
attributes = [attributes]
// allows syntax:
// .RefreshCache()
if (attributes != null)
// denies syntax:
// .RefreshCache(object)
if (!Array.prototype.isPrototypeOf(attributes))
throw new Error("\n[ArsEntry.RefreshCache.InvalidArgument] " + attributes)
// allows syntax:
// .RefreshCache("attr1", "attr2", "attr3")
if (arguments.length > 1)
for (var i = 1; i < arguments.length; i++)
attributes.push(arguments)
try
{
if (attributes != null && attributes.length > 0)
theArsEntry.NativeObject().GetInfoEx(VBArray.Parse(attributes), 0)
else
theArsEntry.NativeObject().GetInfo()
}
catch(e)
{
throw new Error(e.number, "\n[ArsEntry.RefreshCache] " + "\n" + e)
}
}
this.InvokeSet = function(propertyName, args, /* ADS_PROPERTY_ */ MODE)
{
if (propertyName == null || propertyName === String.Empty)
throw new Error("\n[ArsEntry.InvokeSet.InvalidArgument] The attribute name is null or empty.")
if (args === undefined)
throw new Error("\n[ArsEntry.InvokeSet.InvalidArgument] The value of the attribute is undefined.")
if (typeof args != "unknown" && typeof args != "date") // Octet, Integer8, date [(new Date()).getVarDate()]
if (args.constructor == Array)
args = (args.length > 1)? VBArray.Parse(args) :
(args.length == 1)? args[0] :
/* args.length == 0 */ null
try
{
if (MODE != null && MODE !== String.Empty)
theArsEntry.NativeObject().PutEx(MODE, propertyName, args)
else
if (args == null)
theArsEntry.NativeObject().PutEx(/* ADS_PROPERTY_CLEAR */ 1, propertyName, String.Empty)
else
theArsEntry.NativeObject().Put(propertyName, args)
}
catch(e)
{
throw new Error(e.number, "\n[ArsEntry.InvokeSet] " + "\n" + e)
}
}
this.CommitChanges = function()
{
try
{
theArsEntry.NativeObject().SetInfo()
// ToDo: research
// theArsEntry.NativeObject().GetInfo()
}
catch(e)
{
throw new Error(e.number, "\n[ArsEntry.CommitChanges] " + "\n" + e)
}
}
this.DN = function()
{
try
{
if (! IPropertyCache(theArsEntry).Contains("distinguishedName"))
theArsEntry.RefreshCache(["distinguishedName"])
return theArsEntry.InvokeGet("distinguishedName")
}
catch(e) { throw new Error(e.number, "\n[ArsEntry.DN] " + "\n" + e) }
}
this.PropertyCache = function()
{
NativeObject().Item(propertyName)
}
this.Parent = function()
{
try
{
return ParseDN(this.NativeObject().Parent)
}
catch(e) { throw new Error(e.number, "\n[ArsEntry.Parent]\n" + e) }
}
// ms-help://../fxref_system.directoryservices/html/601be6a2-bdb8-663e-b8c4-b316c9b74a98.htm
this.Name = function()
{
try
{
return this.InvokeGet("name")
}
catch(e) { throw new Error(e.number, "\n[ArsEntry.Name]\n" + e) }
}
// ms-help://../fxref_system.directoryservices/html/bf0d15fb-3c56-604c-2c50-2c69300f7c29.htm
this.MoveTo = function(/* ArsEntry | Container's DN */ container)
{
try
{
if (typeof container == 'string')
container = this.ArsProvider().ArsEntry(container)
IContainer(container).MoveHere(this.DN(), "")
}
catch(e)
{
throw new Error(e.number, "\n[ArsEntry.MoveTo] " + "\n" + e)
}
}
// ms-help://../fxref_system.directoryservices/html/bf23e398-e9ee-dabb-c58d-9de0f0b3d585.htm
this.Rename = function(/* string */ newName)
{
try
{
var container = this.ArsProvider().ArsEntry(this.Parent())
IContainer(container).MoveHere(this.DN(), newName)
}
catch(e) { throw new Error(e.number, "\n[ArsEntry.Rename] " + "\n" + e) }
}
this.Delete = function()
{
try
{
var parent = this.ArsProvider().GetObject(this.NativeObject().Parent)
parent.Delete(this.NativeObject().Class, this.NativeObject().Name)
adsiObject = null
}
catch(e) { throw new Error(e.number, "\n[ArsEntry.Delete] " + "\n" + e) }
}
this.toString = function()
{
var dn
try
{
dn = this.DN()
}
catch(e)
{
dn = ParseDN(this.NativeObject().AdsPath)
}
return "<ArsEntry DN=" + dn.Quoted() + ">"
}
}
// ------------------------------------------------------------------------------------------------
// ArsLookup
// ------------------------------------------------------------------------------------------------
// Constructors
// ArsLookup(ArsProvider, dn)
// ArsLookup(ArsProvider, adsiObject)
// Methods
// GetLookup()
// GUID(guid)
// SID(sid)
// Reverse(text)
//
function ArsLookup(/* ArsProvider */ ARS)
{
// An provider to ActiveRoles Server
var arsProvider = (ARS == null)? new ArsProvider() : ARS
var lookup = null
this.GetLookup = function()
{
if (lookup != null) return lookup
try
{
var connectionString = "EDMS://" + arsProvider.bind.server
lookup = new ActiveXObject("EDSILookup")
lookup.Initialize2(connectionString, arsProvider.bind.login, arsProvider.bind.password, /* ADS_EDMSERVER_BIND */ 32768)
}
catch(e)
{
if (e.HResult() == 0x80041455) // The ActiveRoles Administration Service is not available on...
e.message = e.message.substr(e.message.indexOf("\n")).Trim()
throw new Error(e.number, "\n[ArsLookup.GetLookup.Failed] Lookup is unavailable on " +
String(arsProvider.bind.server).Quoted() +
(arsProvider.bind.login != String.Empty? " (by " + String(arsProvider.bind.login).Quoted() + ")" : String.Empty) +
"\n" + e)
}
return lookup
}
// return {DN, PrintableName} by GUID
this.GUID = function(guid)
{
this.GetLookup()
try
{
// reduction to an octet
guid = Octet.GetOctetString(guid)
// looking by lookup object
var r = new Enumerator(lookup.LookupGUIDs(VBArray.Parse([guid])))
r.moveFirst()
var lookupInfo = r.item()
if (lookupInfo != null)
return { DN: lookupInfo.DN, PrintableName: lookupInfo.PrintableName }
// get an object by a special distingushed name "<GUID=..."
var arsEntry = this.ArsProvider().ArsEntry("<GUID=" + Octet.GetGuidString(guid) + ">")
if (arsEntry == null)
return null
var dn = arsEntry.DN()
arsEntry.RefreshCache(["edsaDomainNetbiosName", "sAMAccountName"])
var domain = arsEntry.InvokeGet("edsaDomainNetbiosName")
var account = arsEntry.InvokeGet("sAMAccountName")
return { DN: dn, PrintableName: domain + "\\" + account }
}
catch(e)
{ throw new Error(e.number, "\n[ArsLookup.GUID.Failed]\n" + e) }
}
// return {DN, PrintableName} by SID
this.SID = function(sid)
{
this.GetLookup()
try
{
// reduction to an octet
sid = Octet.GetSidString(sid)
var r = new Enumerator(lookup.LookupSIDs(VBArray.Parse([sid])))
r.moveFirst()
var lookupInfo = r.item()
if (lookupInfo != null)
return { DN: lookupInfo.DN, PrintableName: lookupInfo.PrintableName }
// get an object by a special distingushed name "<GUID=..."
var arsEntry = arsProvider.ArsEntry("<SID=" + Octet.GetSidString(sid) + ">")
var dn = arsEntry.DN()
arsEntry.RefreshCache(["edsaDomainNetbiosName", "sAMAccountName"])
var domain = arsEntry.InvokeGet("edsaDomainNetbiosName")
var account = arsEntry.InvokeGet("sAMAccountName")
return { DN: dn, PrintableName: domain + "\\" + account }
}
catch(e)
{ throw new Error(e.number, "\n[ArsLookup.SID.Failed]\n" + e) }
}
// return SID (bin) by Domain and/or Account
this.Reverse = function(text)
{
if (text == null || text === String.Empty)
return null
var domain = text.substr(0, text.indexOf("\\"))
var name = text.substr(text.indexOf("\\") + 1)
this.GetLookup()
function Resolve(domain, name)
{
try
{
var lookupInfoCollection = lookup.ReverseLookup(domain, name)
}
catch(e)
{
return null
}
var r = new Enumerator(lookupInfoCollection)
r.moveFirst()
var sidLookupInfo = r.item()
if (sidLookupInfo == null)
return null
return sidLookupInfo.Sid
}
var sid
if (domain != String.Empty)
{
sid = Resolve(domain, name)
if (sid == null || sid === String.Empty)
return null
return sid
}
// if domain === String.Empty
// try domains "NT AUTHORITY", "BUILDIN"
var wellknownDomains = ["", "NT AUTHORITY", "BUILTIN"]
for (var i = 0; i < wellknownDomains.length; i++)
{
sid = Resolve(wellknownDomains, name)
if (sid != null && sid !== String.Empty)
return sid
}
return null
}
}
// ================================================================================================
// Specific ARS objects and interfaces
function $Entry(/* ArsEntry */ entry)
{
this.Entry = entry
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// PropertyCache
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IPropertyCache(/* ArsEntry */ entry)
{
return new $PropertyCache(entry)
}
function $PropertyCache(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
this.Contains = function(attributeName)
{
return this.Entry.NativeObject().Item(attributeName) == null? false : true
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// User
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IUser(/* ArsEntry */ entry)
{
return new $User(entry)
}
function $User(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
this.SetPassword = function(/* string */ password)
{
try
{
this.Entry.NativeObject().SetPassword(password)
}
catch(e) { throw new Error(e.number, "\n[$User.SetPassword]\n" + e) }
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Enumerator
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IEnumerator(/* ArsEntry */ entry)
{
return new $Enumerator(entry, entry.NativeObject())
}
function $Enumerator(/* ArsEntry */ entry, /* Collection */ collection)
{
$Entry.call(this, entry)
this.Collection = collection
var _en = new Enumerator(this.Collection)
this.item = function()
{
if (this.CastItem)
return this.CastItem(_en.item())
return _en.item()
}
this.moveFirst = function() { return _en.moveFirst() }
this.atEnd = function() { return _en.atEnd() }
this.moveNext = function() { return _en.moveNext() }
// overrideable
this.CastItem = function(item)
{
return new this.Entry.ArsProvider().ArsEntry(item)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Container
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IContainer(/* ArsEntry */ entry)
{
return new $Container(entry)
}
function $Container(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
this.GetEnumerator = function(/* string[] */ filter)
{
if (filter != null && filter !== String.Empty)
{
if (filter.constructor != Array) filter = [filter]
this.Entry.NativeObject().Filter = VBArray.Parse(filter)
}
return IEnumerator(this.Entry)
}
this.AdsEnumerator = function(/* string[] */ filter)
{
if (filter != null)
if (filter.constructor != Array) filter = [filter]
this.Entry.NativeObject().Filter = VBArray.Parse(filter)
return new Enumerator(this.Entry.NativeObject())
}
//create AD object in this container
this.Create = function(/* string */ objectClass, /* string */ name)
{
var prefix = (objectClass.toLowerCase() == "organizationalunit")? "OU=" : "CN="
try
{
var adsiObject = this.Entry.NativeObject().Create(objectClass, prefix + name)
return this.Entry.ArsProvider().ArsEntry(adsiObject)
}
catch(e) { throw new Error(e.number, "\n[$Container.Create]\n" + e) }
}
this.CopyHere = function(sourceObjectDN, newObjectName)
{
try
{
var prefix = sourceObjectDN.substring(0, sourceObjectDN.indexOf("=")+1)
var adsiObject = this.Entry.NativeObject().CopyHere("EDMS://" + sourceObjectDN, prefix + newObjectName)
return this.Entry.ArsProvider().ArsEntry(adsiObject)
}
catch(e) { throw new Error(e.number, "\n[$Container.CopyHere]\n" + e) }
}
// ms-help://../adsi/adsi/iadscontainer_movehere.htm
// Note. ARS provider supports move only without a change of name (by design).
this.MoveHere = function(sourceObjectDN, newName)
{
try
{
newName = (newName == null || newName == String.Empty)? String.Empty :
sourceObjectDN.substring(0, sourceObjectDN.indexOf("=")+1) + newName
// ARS bug: move and rename are supported separately
var adsiObject = this.Entry.ArsProvider().GetObject(sourceObjectDN)
var newObject = this.Entry.NativeObject().MoveHere(adsiObject.AdsPath, newName)
return this.Entry.ArsProvider().ArsEntry(newObject)
}
catch(e) { throw new Error(e.number, "\n[$Container.MoveHere]\n" + e) }
}
this.Delete = function(/* string */ objectClass, /* string */ name)
{
var prefix = (objectClass.toLowerCase() == "organizationalunit")? "OU=" : "CN="
try
{
this.Entry.NativeObject().Delete(objectClass, prefix + name)
}
catch(e) { throw new Error(e.number, "\n[$Container.Delete]\n" + e) }
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Group
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IGroup(/* ArsEntry */ entry)
{
return new $Group(entry)
}
function $Group(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
// Get members
this.Members = function()
{
try
{
this.Entry.RefreshCache(["Member"])
var members = this.Entry.InvokeGet("Member")
if (members == null)
return []
if (typeof members == 'string')
return [members]
return members
}
catch(e)
{
throw new Error(e.number, "\n[$Group.Members] " + "\n" + e)
}
}
// Check membership
this.IsMember = function(/* DN string */ dn)
{
try
{
// this.RefreshCache(["distingushedName"])
return Boolean.Parse(this.Entry.NativeObject().IsMember("EDMS://" + dn))
}
catch(e)
{
throw new Error(e.number, "\n[$Group.IsMember] " + "\n" + e)
}
}
// Add members
this.Add = function(/* string | string[] */ newMembers)
{
if (newMembers == null || newMembers === String.Empty) return
if (newMembers.constructor != Array) newMembers = [newMembers]
try
{
for (var i = 0; i < newMembers.length; i++)
this.Entry.NativeObject().Add("EDMS://" + newMembers)
}
catch(e)
{
throw new Error(e.number, "\n[$Group.Add] " + "\n" + e)
}
}
// Add members
this.Remove = function(/* string | string[] */ removeMembers)
{
if (removeMembers == null || removeMembers === String.Empty) return
if (removeMembers.constructor != Array) removeMembers = [removeMembers]
try
{
for (var i = 0; i < removeMembers.length; i++)
this.Entry.NativeObject().Remove("EDMS://" + removeMembers)
}
catch(e)
{
throw new Error(e.number, "\n[$Group.Remove] " + "\n" + e)
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// MembershipRule
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// IEDMMembershipRule
function MembershipRule(/* object */ constructObject)
{
var nativeRule
if (MembershipRule.prototype.isPrototypeOf(constructObject))
{
// Warning: double cast
nativeRule = constructObject.NativeObject()
}
else
if (! Object.prototype.isPrototypeOf(constructObject))
{
nativeRule = constructObject
}
else
{
nativeRule = new ActiveXObject("EDSIManagedUnitCondition")
for (var prop in constructObject)
switch (prop.toLowerCase())
{
default:
throw new Error("Unkonw property " + prop.Quoted())
case "type": nativeRule.Type = constructObject[prop]; break
case "base":
var value = constructObject[prop]
if (value.search(/^EDMS:\/\//i) == -1) value = "EDMS://" + value
nativeRule.Base = value
break
case "baseguid": nativeRule.BaseGuid = constructObject[prop]; break
case "filter": nativeRule.Filter = constructObject[prop]; break
}
}
this.NativeObject = function()
{
return nativeRule
}
this.Type = function(/* EDS_MUCONDITIONENUM */ type)
{
if (type !== undefined) nativeRule.Type = type
return nativeRule.Type
}
this.Base = function(/* dn */ base)
{
if (base !== undefined)
{
if (base.search(/^EDMS:\/\//i) == -1) base = "EDMS://" + base
nativeRule.Base = base
}
return ParseDN(nativeRule.Base)
}
this.BaseGuid = function(/* guid */ baseGuid)
{
if (baseGuid !== undefined) nativeRule.BaseGuid = baseGuid
return nativeRule.BaseGuid
}
this.Filter = function(/* string */ filter)
{
if (filter !== undefined) nativeRule.Filter = filter
return nativeRule.Filter
}
this.IsModified = function()
{
return nativeRule.IsModified
}
this.toString = function()
{
return "<MembershipRule base=" + this.Base().Quoted() + " baseGuid=" + this.BaseGuid().Quoted() +
" filter=" + this.Filter().Quoted() + ">"
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Dynamic Groups
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IDynamicGroup(/* ArsEntry */ entry)
{
return new $DynamicGroup(entry)
}
function $DynamicGroup(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
this.Rebuild = function()
{
// 84C1A76B-2A6B-4F4B-837A-22D2CCAC777A is the guid of the policy object
// CN=Dynamic Groups,CN=Builtin,CN=Policy Objects,CN=Configuration
// The guid is an invariant of ActiveRoles server version.
var policies = VBArray.Parse(["84C1A76B-2A6B-4F4B-837A-22D2CCAC777A"])
this.Entry.NativeObject().Control(/* EDS_CONTROL_FIX */ 4) = policies
this.Entry.NativeObject().Control(/* EDS_CONTROL_CHECK_POLICY_COMPLIANCE */ 5) = policies
this.Entry.NativeObject().CheckPropertyValues()
}
//add a rule to existent set
this.AddRule = function(/* MembershipRule | EDSIManagedUnitCondition | hash */ rule)
{
if (! MembershipRule.prototype.isPrototypeOf(rule))
rule = new MembershipRule(rule)
var ruleCollection = this.Entry.NativeObject().MembershipRuleCollection
ruleCollection.Add(rule.NativeObject())
}
// IEDMDynamicGroup
this.IsDynamicGroup = function()
{
try
{
var isDynamicGroup = this.Entry.NativeObject().IsDynamicGroup
return Boolean.Parse(isDynamicGroup)
}
catch(e) { throw new Error(e.number, "\n[$DynamicGroup.IsDynamicGroup]\n" + e) }
}
this.MemberShipRuleCollection = function()
{
try
{
this.Entry.RefreshCache()
var collection = this.Entry.NativeObject().MemberShipRuleCollection
var enumerator = new $Enumerator(this.Entry, collection)
enumerator.CastItem = function(item)
{
return new MembershipRule(item)
}
enumerator.Count = function()
{
return this.Collection.Count
}
return enumerator
}
catch(e) { throw new Error(e.number, "\n[$DynamicGroup.MemberShipRuleCollection]\n" + e) }
}
this.ConvertToRegularGroup = function()
{
try
{
this.Entry.NativeObject().ConvertToRegularGroup()
}
catch(e) { throw new Error(e.number, "\n[$DynamicGroup.ConvertToRegularGroup]\n" + e) }
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Managed Unit
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IManagedUnit(/* ArsEntry */ entry)
{
return new $ManagedUnit(entry)
}
function $ManagedUnit(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
//add a rule to existent set
this.AddRule = function(/* MembershipRule | EDSIManagedUnitCondition | hash */ rule)
{
if (! MembershipRule.prototype.isPrototypeOf(rule))
rule = new MembershipRule(rule)
try
{
var ruleCollection = this.Entry.NativeObject().MembershipRuleCollection
ruleCollection.Add(rule.NativeObject())
}
catch(e) { throw new Error(e.number, "\n[$ManagedUnit.AddRule]\n" + e) }
}
this.MemberShipRuleCollection = function()
{
try
{
this.Entry.RefreshCache()
var collection = this.Entry.NativeObject().MemberShipRuleCollection
var enumerator = new $Enumerator(this.Entry, collection)
enumerator.CastItem = function(item)
{
return new MembershipRule(item)
}
enumerator.Count = function()
{
return this.Collection.Count
}
return enumerator
}
catch(e) { throw new Error(e.number, "\n[$ManagedUnit.MemberShipRuleCollection]\n" + e) }
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Virtual Attributes
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IVirtualAttribute(/* ArsEntry */ entry)
{
return new $VirtualAttribute(entry)
}
function $VirtualAttribute(/* ArsEntry */ entry)
{
$Entry.call(this, entry)
}
function VirtualAttributeClass(/* ArsProvider */ ARS)
{
// An provider to ActiveRoles Server
var arsProvider = (ARS == null)? new ArsProvider() : ARS
this.ArsProvider = function() { return arsProvider }
var vaContainer = null
this.VAContainer = function()
{
if (vaContainer != null) return vaContainer
var containerDn = "CN=Virtual Attributes,CN=Server Configuration," +
this.ArsProvider().ConfigurationDN()
vaContainer = this.ArsProvider().ArsEntry(containerDn)
return vaContainer
}
//create VirtualAttribute
this.Create = function(/* string */ name, /* ArsAttributes.Syntax */ syntax)
{
var va = IContainer(this.VAContainer()).Create("edsVirtualAttribute", name)
var policyInfoList = va.NativeObject().GetPolicyInfoList(/* EDST_REQ_CREATE */ 4)
Octet.SetGuidString(policyInfoList("schemaIDGUID").GeneratedValue)
va.InvokeSet("schemaIDGUID", Octet.GetOctetString())
va.InvokeSet("attributeID", policyInfoList("attributeID").GeneratedValue)
if (syntax != null)
{
va.InvokeSet("attributeSyntax", ArsAttributes.Syntax[syntax].attributeSyntax)
va.InvokeSet("oMSyntax", ArsAttributes.Syntax[syntax].oMSyntax)
}
return va
}
this.GetAttribute = function(/* string */ name)
{
var dn = "CN=" + name + ",CN=Virtual Attributes,CN=Server Configuration," + this.ArsProvider().ConfigurationDN()
return this.ArsProvider().ArsEntry(dn)
}
this.Delete = function(/* string */ name)
{
IContainer(this.VAContainer()).Delete("edsVirtualAttribute", name)
}
this.Instance = function(/* string (dn) | object (adsi object) */ constuctObj)
{
return new $VirtualAttribute(new ArsEntry(this.ArsProvider(), constuctObj))
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ARS Attributes
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var ArsAttributes = new function()
{
this.Syntax =
{
// and from ARS developer
// http://msdn.microsoft.com/en-us/library/ms684419(VS.85).aspx
"DN": { attributeSyntax: "2.5.5.1", oMSyntax: 127, Description: "A distinguished name of a directory service object." },
"Oid": { attributeSyntax: "2.5.5.2", oMSyntax: 6, Description: "An OID value type." },
"CaseExactString": { attributeSyntax: "2.5.5.3", oMSyntax: 27, Description: "A case-sensitive string type." },
"CaseIgnoreString": { attributeSyntax: "2.5.5.4", oMSyntax: 20, Description: "A case-insensitive string type." },
"PrintableString": { attributeSyntax: "2.5.5.5", oMSyntax: 19, Description: "A printable character set string." },
"IA5String": { attributeSyntax: "2.5.5.5", oMSyntax: 22, Description: "An IA5 character set string." },
"NumericString": { attributeSyntax: "2.5.5.6", oMSyntax: 18, Description: "A numeric value represented as a string." },
"DNWithBinary": { attributeSyntax: "2.5.5.7", oMSyntax: 127, Description: "An ADS_DN_WITH_BINARY structure used for mapping a distinguished name to a non-varying GUID. For more information, see the topic \"ADS_DN_WITH_BINARY\" in the MSDN Library at http://msdn.microsoft.com/library ." },
"Bool": { attributeSyntax: "2.5.5.8", oMSyntax: 1, Description: "A Boolean value type." },
"Int": { attributeSyntax: "2.5.5.9", oMSyntax: 2, Description: "A 32-bit integer value type." },
"Enumeration": { attributeSyntax: "2.5.5.9", oMSyntax: 10, Description: "An enumeration value type." },
"OctetString": { attributeSyntax: "2.5.5.10", oMSyntax: 4, Description: "A byte array represented as a string." },
"ReplicaLink": { attributeSyntax: "2.5.5.10", oMSyntax: 127, Description: "A Replica-Link object type." },
"UtcTime": { attributeSyntax: "2.5.5.11", oMSyntax: 23, Description: "A time expressed in Coordinated Universal Time format." },
"GeneralizedTime": { attributeSyntax: "2.5.5.11", oMSyntax: 24, Description: "A time expressed in generalized time format." },
"DirectoryString": { attributeSyntax: "2.5.5.12", oMSyntax: 64, Description: "A directory string specification." },
"PresentationAddress": { attributeSyntax: "2.5.5.13", oMSyntax: 127, Description: "A Presentation-Address object type." },
"DNWithString": { attributeSyntax: "2.5.5.14", oMSyntax: 127, Description: "An ADS_DN_WITH_STRING structure used for mapping a distinguished name to a non-varying string value. For more information, see the topic \"ADS_DN_WITH_STRING\" in the MSDN Library at http://msdn.microsoft.com/library " },
"SecurityDescriptor": { attributeSyntax: "2.5.5.15", oMSyntax: 66, Description: "A security descriptor value type." },
"Int64": { attributeSyntax: "2.5.5.16", oMSyntax: 65, Description: "A 64 bit (large) integer value type." },
"Sid": { attributeSyntax: "2.5.5.17", oMSyntax: 4, Description: "An SID value type." },
//"AccessPointDN": { attributeSyntax: "2.5.5.00", oMSyntax: 00, Description: "An AccessPoint object type." },
//"ORName": { attributeSyntax: "2.5.5.00", oMSyntax: 00, Description: "An OR-Name object type." },
// http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/distrib/dsbe_ext_dghb.mspx
"Undefined": { attributeSyntax: "2.5.5.0", oMSyntax: "", Description: "Not a legal syntax." },
"Object(DN-DN)": { attributeSyntax: "2.5.5.1", oMSyntax: 127, Description: "The fully qualified name of an object in the directory." },
"String(Object-Identifier)": { attributeSyntax: "2.5.5.2", oMSyntax: 6, Description: "The object identifier." },
"String": { attributeSyntax: "2.5.5.3", oMSyntax: 27, Description: "General String." },
"Case-Sensitive": { attributeSyntax: "2.5.5.3", oMSyntax: 27, Description: "General String." },
"CaseIgnoreString(Teletex)": { attributeSyntax: "2.5.5.4", oMSyntax: 20, Description: "Teletex. Does not differentiate uppercase and lowercase." },
"String(Printable)": { attributeSyntax: "2.5.5.5", oMSyntax: 19, Description: "Printable string or IA5-String." },
"String(IA5)": { attributeSyntax: "2.5.5.5", oMSyntax: 22, Description: "Printable string or IA5-String." },
"String(Numeric)": { attributeSyntax: "2.5.5.6", oMSyntax: 18, Description: "A sequence of digits." },
"Object(DN-Binary)": { attributeSyntax: "2.5.5.7", oMSyntax: 127, Description: "A distinguished name plus a binary large object." },
"Boolean": { attributeSyntax: "2.5.5.8", oMSyntax: 1, Description: "TRUE or FALSE values." },
"Integer": { attributeSyntax: "2.5.5.9", oMSyntax: 2, Description: "A 32-bit number or enumeration." },
//Double: "Enumeration": { attributeSyntax: "2.5.5.9", oMSyntax: "10", Description: "A 32-bit number or enumeration." },
"String(Octet)": { attributeSyntax: "2.5.5.10", oMSyntax: 4, Description: "A string of bytes." },
"String(UTC-Time)": { attributeSyntax: "2.5.5.11", oMSyntax: 23, Description: "UTC Time or Generalized-Time." },
"String(Generalized-Time)": { attributeSyntax: "2.5.5.11", oMSyntax: 24, Description: "UTC Time or Generalized-Time." },
"String(Unicode)": { attributeSyntax: "2.5.5.12", oMSyntax: 64, Description: "Unicode string." },
"Object(Presentation-Address)": { attributeSyntax: "2.5.5.13", oMSyntax: 127, Description: "Presentation address." },
"Object(DN-String)": { attributeSyntax: "2.5.5.14", oMSyntax: 127, Description: "A DN-String plus a Unicode string." },
"String(NT-Sec-Desc)": { attributeSyntax: "2.5.5.15", oMSyntax: 66, Description: "A Microsoft® Windows NT® Security descriptor." },
"LargeInteger": { attributeSyntax: "2.5.5.16", oMSyntax: 65, Description: "A 64-bit number." },
"String(Sid)": { attributeSyntax: "2.5.5.17", oMSyntax: 4, Description: "Security identifier (SID)." }
}
}
// IADsPropertyValue ms-help://../adsi/adsi/iadspropertyvalue.htm
// /adsi/adsi/iadspropertylist_getpropertyitem.htm
var IADsPropertyValue =
{
/* ADSTYPE_DN_STRING */ 1: "DNString",
/* ADSTYPE_CASE_EXACT_STRING */ 2: "CaseExactString",
/* ADSTYPE_CASE_IGNORE_STRING */ 3: "CaseIgnoreString",
/* ADSTYPE_PRINTABLE_STRING */ 4: "PrintableString",
/* ADSTYPE_NUMERIC_STRING */ 5: "NumericString",
/* ADSTYPE_BOOLEAN */ 6: "Boolean",
/* ADSTYPE_INTEGER */ 7: "Integer",
/* ADSTYPE_OCTET_STRING */ 8: "OctetString",
/* ADSTYPE_UTC_TIME */ 9: "UTCTime",
/* ADSTYPE_LARGE_INTEGER */ 10: "LargeInteger",
/* ADSTYPE_NT_SECURITY_DESCRIPTOR */ 25: "SecurityDescriptor"
}
// ================================================================================================
// Tools & Objects
// ------------------------------------------------------------------------------------------------
// ActiveRoles EventLog
// ------------------------------------------------------------------------------------------------
var EventLog = new function()
{
this.Type = {SUCCESS: 0, ERROR: 1, WARNING: 2, INFORMATION: 4, AUDIT_SUCCESS: 8, AUDIT_FAILURE: 16}
this.ReportEvent = function(type, /* messages */ msg1, msg2)
{
var stringInfo = {0: "SUCCESS", 1: "ERROR", 2: "WARNING", 4: "INFORMATION", 8: "AUDIT_SUCCESS", 16: "AUDIT_FAILURE"}
var now = new Date()
var n = {Y:now.getYear(), M:now.getMonth()+1, D:now.getDate(), h:now.getHours(), m:now.getMinutes(), s:now.getSeconds()}
var nowString = n.Y + "-" + (n.M>9?n.M:"0"+n.M) + "-" + (n.D>9?n.D:"0"+n.D) + " " + (n.h>9?n.h:"0"+n.h) + ":" + (n.m>9?n.m:"0"+n.m) + ":" + (n.s>9?n.s:"0"+n.s)
var message = "[" + nowString + "] " + stringInfo[type] + "\n"
for (var i = 1; i < arguments.length; i++)
message += arguments + "\n"
WScript.Echo(message)
}
}
// ------------------------------------------------------------------------------------------------
// EDM Octet
// ------------------------------------------------------------------------------------------------
var Octet = new function()
{
var octet = new ActiveXObject("AelitaEDM.EDMOctetString")
var temp = new ActiveXObject("AelitaEDM.EDMOctetString")
// Returns a string
this.GetString = function(/* EDMOctetString */ binVal)
{
if (binVal === undefined)
return octet.GetString()
temp.Set(binVal)
return temp.GetString()
}
// Returns an array of bytes
this.GetOctetString = function(/* EDMOctetString | obj.GUID string */ binVal)
{
if (binVal === undefined)
return octet.GetOctetString()
if (typeof binVal == 'string')
temp.SetGuidString(binVal)
else
temp.Set(binVal)
return temp.GetOctetString()
}
// Returns a string conforming to the syntax Sid
this.GetSidString = function(/* EDMOctetString */ binVal)
{
if (binVal === undefined)
return octet.GetSidString()
if (typeof binVal == 'string')
temp.SetSidString(binVal)
else
temp.Set(binVal)
return temp.GetSidString()
}
// Returns a string conforming to the syntax OctetString
this.GetGuidString = function(/* EDMOctetString */ binVal)
{
if (binVal === undefined)
return octet.GetGuidString()
temp.Set(binVal)
return temp.GetGuidString()
}
// Sets the binary value
this.Set = function(/* EDMOctetString */ binVal)
{
octet.Set(binVal)
}
// Sets the binary value
this.SetSidString = function(/* string */ text)
{
octet.SetSidString(text)
}
// Sets the binary value
this.SetGuidString = function(/* string */ text)
{
octet.SetGuidString(text)
}
this.Length /* integer */ = new function()
{
return octet.Length
}
// Generates a new GUID and stores it in the object EDMOctetString
this.GenerateGuid = function()
{
octet.GenerateGuid()
}
// Generates a new GUID and stores it in the object EDMOctetString
this.GenerateGuidString = function()
{
temp.GenerateGuid()
return temp.GetGuidString()
}
/*
octet.BitLength
octet.GetBase64String
octet.GetBit
octet.GetBoolArray
octet.GetByte
octet.GetByteArray
octet.GetGPLink
octet.SetBase64String
octet.SetBit
octet.SetByte
octet.SetGPLink
*/
}
// ToDo: reformat. EscapeSlash go to adProvider.Get, cut it from all
// EDS provider doesn't quote /
var dnEscapeForwardSlashRegExp = new RegExp()
dnEscapeForwardSlashRegExp.compile("((\\\\{2})*([^\\\\]|))\\/", "gim")
function EscapeSlash(DN)
{
if (typeof DN != 'string')
throw new Error('\n[EscapeSlash] Argument is not a string. This type is ', [(typeof DN)])
return DN.replace(dnEscapeForwardSlashRegExp, "$1\\/")
}
// ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.WIN32COM.v10.en/adsi/adsi/ldap_adspath.htm
var adsPathRegExp = new RegExp()
adsPathRegExp.compile("^(?:(\\w+)\\:\\/{2}(?:([\\w\\d_\\-\\.]+)(?:\\:(\\d+))*\\/)*)*(.*)$", "i")
function ParseDN(path)
{
var a = adsPathRegExp.exec(path)
if (a.length == 0) return ""
return a[4]
}
//***** END OF CODE ***************************************************************