#1 2015-03-03 20:59:20

awilcox
Member
Registered: 2015-03-02

Nested script inside hookldappam.groovy script

Hello,

I am making use of the hookldappam.groovy sample script and wanted to modify it such that it calls another script to perform additional tasks. I was trying to do this by making use of the call ' GLOBALS.exec ("myscript") ' from inside the LdapPAM.authenticate() method but am having trouble getting references to GLOBALS.

In other scripts, the GlobalsWrapper was passed as a parameter in the class constructor and I was able to execute my nested script with the syntax above but I'm not sure how to do something similar with the hookldappam script.

Is it possible to do this in the hookldappam script, and if so, how else should I be doing it?

Offline

#2 2015-03-03 21:15:59

Arno Mittelbach
datenwerke
Registered: 2012-02-14

Re: Nested script inside hookldappam.groovy script

Hi,

you should be able to add a method like the following to the LdapPAM class

public void init(GlobalsWrapper GLOBALS){
   this.GLOBALS = GLOBALS;
}

together with a field for it

private GlobalsWrapper GLOBALS;

Be sure to also import the corresponding class

import net.datenwerke.rs.scripting.service.scripting.scriptservices.GlobalsWrapper;

Now after instantiating ldapPam if you call

init(GLOBALS);

you should then be able to use the object later on in the authenticate method.

Cheers
-Arno

Offline

#3 2015-03-04 14:42:53

awilcox
Member
Registered: 2015-03-02

Re: Nested script inside hookldappam.groovy script

That worked perfectly, thanks!

Offline

#4 2015-03-05 20:08:34

awilcox
Member
Registered: 2015-03-02

Re: Nested script inside hookldappam.groovy script

This worked perfectly when calling a very simple "Hello World" script that just took a single parameter and returned a String.

Today I have been trying to call a script that does a bit more and am having problems. This called script is working fine if I run it on its own. When I try and execute it from the authenticate() method of another script as mentioned in my earlier post, I get an Exception that I'm not sure how to interpret.

I had previously seen a ViolatedSecurityException when I tried to execute Script B from Script A and did not put the full path to the Script B location, so perhaps it is something equally simple that I have missed? Do you know why the "GLOBALS.findObject" line would be causing an exception under this scenario?

Here is how I am executing Script B from Script A:

User userFromAD = GLOBALS.exec("/fileserver/bin/my_scripts/authorize.groovy", "username");

Here is a snippet from Script B that I am trying to call (it is based on the sample ldapimport script):

UserManagerService umService = GLOBALS.getRsService(UserManagerService.class);
Authorizor auth = new Authorizor(GLOBALS, args);
System.out.println("AAA - This message is seen");
OrganisationalUnit targetNode = (GLOBALS.findObject("/usermanager/Internal AD"));
System.out.println("AAA - This message is not seen");

if(null == targetNode)
{
    AbstractUserManagerNode umRoot = umService.getRoots().get(0);
    targetNode = new OrganisationalUnit("Internal AD");
    umRoot.addChild(targetNode);
    umService.persist(targetNode);
}

auth.setTargetNode(targetNode);
auth.run();

This is the exception that I am seeing in the log file:

AAA - This message is seen
Mar 05, 2015 2:28:27 PM net.datenwerke.gf.service.gwtstacktrace.CatchStacktraceInterceptor invoke
INFO: Intercepted NonFatalException
net.datenwerke.rs.scripting.service.scripting.exceptions.ScriptEngineException: javax.script.ScriptException: javax.script.ScriptException: net.datenwerke.security.service.security.exceptions.ViolatedSecurityException
    at net.datenwerke.rs.scripting.service.scripting.engines.GroovyEngine.eval(GroovyEngine.java:67)
    at net.datenwerke.rs.scripting.service.scripting.scriptservices.CallScriptService.exec(CallScriptService.java:61)
    at net.datenwerke.rs.scripting.service.scripting.scriptservices.GlobalsWrapper.exec(GlobalsWrapper.java:115)
    at net.datenwerke.rs.scripting.service.scripting.scriptservices.GlobalsWrapper$exec.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
    at ldap.LdapPAM.authenticate(Script144.groovy:125)
    at ldap.LdapPAM$authenticate.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:145)
    at ldap.LdapPAM.authenticate(Script144.groovy:71)
    at net.datenwerke.security.service.authenticator.AuthenticatorServiceImpl.evaluateTokens(AuthenticatorServiceImpl.java:110)
    at net.datenwerke.security.service.authenticator.AuthenticatorServiceImpl.authenticate(AuthenticatorServiceImpl.java:75)
    at net.datenwerke.rs.authenticator.server.LoginHandlerImpl.authenticate(LoginHandlerImpl.java:65)
    at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:66)
    at net.datenwerke.security.service.security.aop.SecurityCheckInterceptor.invoke(SecurityCheckInterceptor.java:110)
    at net.datenwerke.gf.service.gwtstacktrace.CatchStacktraceInterceptor.invoke(CatchStacktraceInterceptor.java:38)
    at sun.reflect.GeneratedMethodAccessor91.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:561)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
    at net.datenwerke.security.service.security.aop.SecurityCheckInterceptor.invoke(SecurityCheckInterceptor.java:110)
    at net.datenwerke.gf.service.gwtstacktrace.CatchStacktraceInterceptor.invoke(CatchStacktraceInterceptor.java:38)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at net.datenwerke.security.service.security.aop.SecurityCheckInterceptor.invoke(SecurityCheckInterceptor.java:110)
    at net.datenwerke.gf.service.gwtstacktrace.CatchStacktraceInterceptor.invoke(CatchStacktraceInterceptor.java:38)
    at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263)
    at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178)
    at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62)
    at com.google.inject.persist.PersistFilter.doFilter(PersistFilter.java:89)
    at com.google.inject.servlet.FilterDefinition.doFilter(FilterDefinition.java:163)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:58)
    at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118)
    at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:193)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.script.ScriptException: javax.script.ScriptException: net.datenwerke.security.service.security.exceptions.ViolatedSecurityException
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:138)
    at net.datenwerke.rs.scripting.service.scripting.engines.GroovyEngine.eval(GroovyEngine.java:65)
    ... 56 more
Caused by: javax.script.ScriptException: net.datenwerke.security.service.security.exceptions.ViolatedSecurityException
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:335)
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:132)
    ... 57 more
Caused by: net.datenwerke.security.service.security.exceptions.ViolatedSecurityException
    at net.datenwerke.rs.terminal.service.terminal.vfs.hooks.TreeBasedVirtualFileSystem.checkRead(TreeBasedVirtualFileSystem.java:407)
    at net.datenwerke.rs.terminal.service.terminal.vfs.hooks.TreeBasedVirtualFileSystem.getLocation(TreeBasedVirtualFileSystem.java:83)
    at net.datenwerke.rs.terminal.service.terminal.vfs.VirtualFileSystemDeamon.getLocation(VirtualFileSystemDeamon.java:142)
    at net.datenwerke.rs.terminal.service.terminal.vfs.VirtualFileSystemDeamon.getAbsoluteLocation(VirtualFileSystemDeamon.java:104)
    at net.datenwerke.rs.terminal.service.terminal.vfs.VirtualFileSystemDeamon.getLocation(VirtualFileSystemDeamon.java:80)
    at net.datenwerke.rs.terminal.service.terminal.vfs.hookers.VfsObjectResolver.getLocation(VfsObjectResolver.java:86)
    at net.datenwerke.rs.terminal.service.terminal.vfs.hookers.VfsObjectResolver.getObjects(VfsObjectResolver.java:39)
    at net.datenwerke.rs.terminal.service.terminal.objresolver.ObjectResolverDeamon.getObjects(ObjectResolverDeamon.java:61)
    at net.datenwerke.rs.terminal.service.terminal.objresolver.ObjectResolverDeamon.getObject(ObjectResolverDeamon.java:96)
    at net.datenwerke.rs.terminal.service.terminal.objresolver.ObjectResolverDeamon.getObject(ObjectResolverDeamon.java:92)
    at net.datenwerke.rs.scripting.service.scripting.scriptservices.GlobalsWrapper.findObject(GlobalsWrapper.java:197)
    at sun.reflect.GeneratedMethodAccessor115.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at ldap.Script145.run(Script145.groovy:35)
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:332)
    ... 58 more

Offline

#5 2015-03-06 10:53:52

Arno Mittelbach
datenwerke
Registered: 2012-02-14

Re: Nested script inside hookldappam.groovy script

Hi, this should be a problem with the permissions set up for the user executing the script. What is your script doing in line 35? (The part "at ldap.Script145.run(Script145.groovy:35)" in the stack trace points to the line that triggers the problem.) This should probably be something like

GLOBALS.findObject(..)

which throws the ViolatedSecurityException as the user that is running the script does not have read access on the object that it tries to load.

Does that help?

Cheers
-Arno

Offline

#6 2015-03-06 14:49:51

awilcox
Member
Registered: 2015-03-02

Re: Nested script inside hookldappam.groovy script

Yes, line 35 in the 2nd script is:

OrganisationalUnit targetNode = (GLOBALS.findObject("/usermanager/Internal AD"));

The 1st script that runs is a hookldappam script - I had thought that script would be running with some sort of root privileges, since a user hasn't logged in yet. Before the authenticate() method returns, the call to the 2nd script (that does the GLOBALS.findObject() call) is made. Is that somehow happening with the user that is attempting to log in? I don't see how it could be doing that, since authenticate() hasn't yet returned an AuthenticationResult with a user in it but the only other user I have is a root user which should have all privileges.

Offline

#7 2015-03-06 18:56:02

Arno Mittelbach
datenwerke
Registered: 2012-02-14

Re: Nested script inside hookldappam.groovy script

You are right. The problem is that at the point the script is executed no user is logged in. Thus, if you run any method that triggers a permission check you will get a ViolatedSecurityException. GLOBALS.findObject performs basic security checks and can thus not be used.

There are multiple ways to locate an object without triggering security checks. One is to use

GLOBALS.findEntity(Class<T>, Object)

which directly goes to the database. The first parameter is the entity type, the second the entities id. In your case this could for example look like

import net.datenwerke.security.service.usermanager.entities.AbstractUserManagerNode

GLOBALS.findEntity(AbstractUserManagerNode.class, 42l)

An alternative if you want to work with a path instead of an ID is to obtain a TerminalService which offers the method getObjectByLocation.

import net.datenwerke.rs.terminal.service.terminal.TerminalService

def terminal = GLOBALS.getInstance(TerminalService.class)
def node = terminal.getObjectByLocation("/usermanager/Internal AD", false)

Here the boolean "false" tells the service not perform security checks on the way.

Hope this helps.

Cheers
-Arno

Offline

#8 2015-03-12 20:52:17

awilcox
Member
Registered: 2015-03-02

Re: Nested script inside hookldappam.groovy script

I used your second approach of using the path instead of the ID and I no longer got the ViolatedSecurityException.

In addition, once I was logged in I could see that the Organisational Unit of "Internal AD" had been created (see code from my original post). Later on in my script I also created a User object as a child to that "Internal AD" OU and this was successful.

However, I then wanted to do something similar and write a startup script (ie a script that I put under onstartup.d folder) that would call a second script to a) create an Organisational Unit if it did not exist and b) create some Groups under it.

Neither script gives any errors, the logs suggest that the OU and the Groups are being created and the script finishes successfully, but when I log in I do not see the objects (nor are they in the database). It is almost like when a script is executed manually in the terminal and the "-c" is excluded. I am calling the nested script using "GLOBALS.exec("/fileserver/bin/my_scripts/createGroups.groovy")", which is the same approach in the hookldappam script and it worked fine there and committed changes to the database.

I had thought maybe it was because no one is logged in when the startup script is run, but that would have been similar in the case of the hookldappam calling another script to create an OU and user, and I would have thought I'd see an error if it was not able to write to the database.

If my description is not clear, I can post some code snippets. Should it be be possible for me to do what I have described, and create an OU and Group from a startup script?

Offline

#9 2015-03-13 15:50:04

Arno Mittelbach
datenwerke
Registered: 2012-02-14

Re: Nested script inside hookldappam.groovy script

Hi,

you are right again. The onlogin and onstartup scripts were not executed in committing mode. We've discussed this and decided that it doesn't make much sense for onlogin and onstartup not to be run in non-committing mode. We've already implemented the changes in the trunk so if you need a patched build please open a ticket in the support portal.

Cheers
-Arno

Offline

Board footer

Powered by FluxBB