Posted in : NetScaler By Simon Gottschlag

3 years ago

UPDATE: Updated the Lua-code, which seems to work better and is about 21 times faster. Big thanks to Ulrik! You can find the updated code here.
There was a question on the Citrix discussion forums where an administrator wants to output the groups a user is member of in a SAML Assertion, but with the caveat that only groups with a specific names should be included.
In this case the following expression is usually used: HTTP.REQ.USER.GROUPS_AS_XML(”xmltag”)
I was thinking about it and couldn’t figure out what the easiest way to do this was, so I started thinking about Lua since it’s extremely flexible and it’s fun learning new stuff. (the NetScaler developers helped me last time with a bug in the JSON-parser – see this post.)
Since I’m no developer myself, and my Lua-knowledge is very limited (at best), I started trying it out using an example Citrix have written.
The result:

local function split(str, pat)
    local t = {}
    local fpat = "(.-)" .. pat
    local last_end = 1
    local s, e, cap = str:find(fpat, 1)
    while s do
        if s ~= 1 or cap ~= "" then
            table.insert(t,cap)
        end
        last_end = e+1
        s, e, cap = str:find(fpat, last_end)
    end
    if last_end <= #str then
        cap = str:sub(last_end)
        table.insert(t, cap)
    end
    return t
end
function NSTEXT:FILTER_XML_LIST(pattern : NSTEXT, delimiter : NSTEXT, xmltag : NSTEXT) : NSTEXT
    local out = ""
    local input = self
    local lines = split(input, delimiter)
    local key,value
    for key,value in pairs(lines) do
        if (value:lower():find(pattern)) then
            out = out .. "<" .. xmltag .. ">" .. value .. "</" .. xmltag .. ">"
        end
    end
    return(out)
end

When you’ve imported the policy extension, you can use it like this:

# Parameters: pattern, delimiter, xmltag
HTTP.REQ.USER.GROUPS.FILTER_XML_LIST("group",",","xmltag")

In my case, the output for HTTP.REQ.USER.GROUPS would be:
group2,group1,grupp2,grupp1
When using the policy extension, the output is:
<xmltag>group2</xmltag><xmltag>group1</xmltag>
Now remember, the above is an example and should as always be tested (and most likely optimized) before being used in production. But it works (at least in my lab) and it’s really cool to be able to modify the functionality of NetScaler this easliy.
Do you know of any way to do this without policy extensions? Or do you know Lua and there’s a better way of doing the policy extension?

Tags : Lua, NetScaler, Policy Extension, XML

Comments

Ulrik Strd says

Not a Lua expert but you could probably use string.gmatch(input, pattern). That should give you a list that you then just loop over once. You will have to write some regex for your groups but that seems fine as it's not user input.

Simon Gottschlag says

Thank you Ulrik! :) Updated it: http://xenit.se/techblogg/filtering-list-netscaler-converting-xml-using-policy-extension-v2/

Add comment

Your comment will be revised by the site if needed.