You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by de...@apache.org on 2013/11/16 14:07:49 UTC

svn commit: r1542505 - in /uima/sandbox/uima-ducc/trunk: uima-ducc-common/src/main/java/org/apache/uima/ducc/common/authentication/ uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/ uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/au...

Author: degenaro
Date: Sat Nov 16 13:07:49 2013
New Revision: 1542505

URL: http://svn.apache.org/r1542505
Log:
UIMA-3421 DUCC webserver (WS) native Linux-based authentication mechanism, as plug-in via ducc.properties

Added:
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAsUser.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAuthenticator.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/LinuxAuthenticationManager.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamTest.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java
Removed:
    uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/authentication/DuccAsUser.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/authentication/LinuxAuthenticationManager.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/authentication/PamAuthenticate.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/authentication/UserAuthenticate.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAsUser.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccAuthenticator.java
Modified:
    uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccPropertiesResolver.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorJob.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorManagedReservation.java

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccPropertiesResolver.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccPropertiesResolver.java?rev=1542505&r1=1542504&r2=1542505&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccPropertiesResolver.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/utils/DuccPropertiesResolver.java Sat Nov 16 13:07:49 2013
@@ -131,7 +131,7 @@ public class DuccPropertiesResolver {
         defaultProperties.put(ducc_orchestrator_unmanaged_reservations_accepted,"true");
         defaultProperties.put(ducc_orchestrator_use_lock_file,"false");
         defaultProperties.put(ducc_ws_login_enabled,"true");
-        defaultProperties.put(ducc_authentication_implementer,"org.apache.uima.ducc.common.authentication.LinuxAuthenticationManager");
+        defaultProperties.put(ducc_authentication_implementer,"org.apache.uima.ducc.ws.authentication.LinuxAuthenticationManager");
         defaultProperties.put(ducc_jd_queue_timeout_minutes,"5");
         defaultProperties.put(ducc_jd_queue_prefix,"ducc.jd.queue.");
         defaultProperties.put(ducc_jd_host_class,"JobDriver");

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAsUser.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAsUser.java?rev=1542505&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAsUser.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAsUser.java Sat Nov 16 13:07:49 2013
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.ws.authentication;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.uima.ducc.common.utils.DuccLogger;
+import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
+import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
+import org.apache.uima.ducc.common.utils.Utils;
+
+
+public class DuccAsUser {
+	
+	private static DuccLogger duccLogger = DuccLoggerComponents.getWsLogger(DuccAsUser.class.getName());
+	
+	public static String magicString = "1001 Command launching...";
+	
+	public static String duckling(String user, String[] args) {
+		
+		String methodName = "duckling";
+		
+		StringBuffer retVal = new StringBuffer();
+		
+		String c_launcher_path = 
+			Utils.resolvePlaceholderIfExists(
+					System.getProperty("ducc.agent.launcher.ducc_spawn_path"),System.getProperties());
+		
+		duccLogger.debug(methodName, null, "the duckling launcher "+c_launcher_path);
+		
+		ArrayList<String> cmd = new ArrayList<String>();
+		
+		cmd.add(c_launcher_path);
+		
+		StringBuffer sbInfo  = new StringBuffer();
+		StringBuffer sbDebug = new StringBuffer();
+		String prev = "";
+		
+		for( String arg : args ) {
+			cmd.add(arg);
+			if(!arg.equals("-cp")) {
+				if(!prev.equals("-cp")) {
+					sbInfo.append(arg+" ");
+				}
+			}
+			sbDebug.append(arg+" ");
+			prev = arg;
+		}
+
+		duccLogger.info(methodName, null, "plist: "+sbInfo.toString().trim());
+		duccLogger.debug(methodName, null, "plist: "+sbDebug.toString().trim());
+		
+		duccLogger.info(methodName, null, "cmd: "+cmd);
+		duccLogger.trace(methodName, null, "cmd: "+cmd);
+		
+		ProcessBuilder pb = new ProcessBuilder(cmd);
+		
+		Map<String, String> env = pb.environment();
+		
+		env.put("JobId", "webserver");
+		
+		String runmode = DuccPropertiesResolver.getInstance().getProperty(DuccPropertiesResolver.ducc_runmode);
+		if(runmode != null) {
+			if(runmode.equals("Test")) {
+				env.put("USER", user);
+			}
+		}
+		
+		try {
+			Process process = pb.start();
+			String line;
+			BufferedReader bri = new BufferedReader(new InputStreamReader(process.getInputStream()));
+			BufferedReader bre = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+			boolean trigger = false;
+			duccLogger.trace(methodName, null, "read stdout: start");
+			while ((line = bri.readLine()) != null) {
+				duccLogger.info(methodName, null, "stdout: "+line);
+				if(trigger) {
+					retVal.append(line+"\n");
+				}
+				if(line.startsWith(magicString)) {
+					duccLogger.trace(methodName, null, "magic!");
+					trigger = true;
+				}
+			}
+			bri.close();
+			duccLogger.trace(methodName, null, "read stdout: end");
+			duccLogger.trace(methodName, null, "read stderr: start");
+			while ((line = bre.readLine()) != null) {
+				duccLogger.warn(methodName, null, "stderr: "+line);
+				retVal.append(line);
+			}
+			bre.close();
+			duccLogger.trace(methodName, null, "read stderr: end");
+			duccLogger.trace(methodName, null, "process waitfor: start");
+			process.waitFor();
+			duccLogger.trace(methodName, null, "process waitfor: end");
+		}
+		catch(Exception e) {
+			duccLogger.info(methodName, null, e);
+		}
+		
+		return retVal.toString();
+	}
+	
+	public static String ducklingQuiet(String user, String[] args, String[] argsMasked) {
+
+		StringBuffer retVal = new StringBuffer();
+		
+		String c_launcher_path = 
+			Utils.resolvePlaceholderIfExists(
+					System.getProperty("ducc.agent.launcher.ducc_spawn_path"),System.getProperties());
+
+		ArrayList<String> cmd = new ArrayList<String>();
+		
+		cmd.add(c_launcher_path);
+		
+		StringBuffer sbInfo  = new StringBuffer();
+		StringBuffer sbDebug = new StringBuffer();
+		String prev = "";
+		
+		for(int i=0; i<args.length; i++) {
+			String arg = args[i];
+			cmd.add(arg);
+			if(!arg.equals("-cp")) {
+				if(!prev.equals("-cp")) {
+					sbInfo.append(argsMasked[i]+" ");
+				}
+			}
+			sbDebug.append(argsMasked[i]+" ");
+			prev = arg;
+		}
+
+		ProcessBuilder pb = new ProcessBuilder(cmd);
+		
+		Map<String, String> env = pb.environment();
+		
+		env.put("JobId", "webserver");
+		
+		String runmode = DuccPropertiesResolver.getInstance().getProperty(DuccPropertiesResolver.ducc_runmode);
+		if(runmode != null) {
+			if(runmode.equals("Test")) {
+				env.put("USER", user);
+			}
+		}
+		
+		try {
+			Process process = pb.start();
+			String line;
+			BufferedReader bri = new BufferedReader(new InputStreamReader(process.getInputStream()));
+			BufferedReader bre = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+			boolean trigger = true;
+			while ((line = bri.readLine()) != null) {
+				if(trigger) {
+					retVal.append(line+"\n");
+				}
+				if(line.startsWith(magicString)) {
+					trigger = true;
+				}
+			}
+			bri.close();
+			while ((line = bre.readLine()) != null) {
+				retVal.append(line);
+			}
+			bre.close();
+			process.waitFor();
+		}
+		catch(Exception e) {
+		}
+		
+		return retVal.toString();
+	}
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAuthenticator.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAuthenticator.java?rev=1542505&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAuthenticator.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/DuccAuthenticator.java Sat Nov 16 13:07:49 2013
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.ws.authentication;
+
+import org.apache.uima.ducc.common.authentication.IAuthenticationManager;
+import org.apache.uima.ducc.common.authentication.IAuthenticationResult;
+import org.apache.uima.ducc.common.utils.DuccLogger;
+import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
+import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
+import org.apache.uima.ducc.common.utils.id.DuccId;
+
+public class DuccAuthenticator implements IAuthenticationManager {
+	
+	private static DuccLogger duccLogger = DuccLoggerComponents.getWsLogger(DuccAuthenticator.class.getName());
+	private static DuccId jobid = null;
+	
+	private static DuccAuthenticator instance = new DuccAuthenticator();
+	
+	private DuccPropertiesResolver duccPropertiesResolver = null;
+
+	private IAuthenticationManager iAuthenticationManager = null;
+	
+	public static DuccAuthenticator getInstance() {
+		return instance;
+	}
+	
+	public DuccAuthenticator() {
+		duccPropertiesResolver = DuccPropertiesResolver.getInstance();
+		initializeAuthenticator();
+	}
+	
+	private void initializeAuthenticator() {
+		String methodName = "initializeAuthenticator";
+		try {
+			String key = DuccPropertiesResolver.ducc_authentication_implementer;
+			String value = duccPropertiesResolver.getProperty(key);
+			duccLogger.info(methodName, jobid, value);
+			String cp = System.getProperty("java.class.path");
+			String[] cplist = cp.split(":");
+			if(cplist != null) {
+				for(String item : cplist) {
+					duccLogger.debug(methodName, null, item);
+				}
+			}
+			Class<?> authenticationImplementer = Class.forName(value);
+			iAuthenticationManager = (IAuthenticationManager)authenticationImplementer.newInstance();
+			duccLogger.info(methodName, jobid, iAuthenticationManager.getVersion());
+		}
+		catch(Throwable t) {
+			duccLogger.error(methodName, jobid, t);
+		}
+	}
+
+	@Override
+	public String getVersion() {
+		String methodName = "getVersion";
+		String retVal = null;
+		try {
+			retVal = iAuthenticationManager.getVersion();
+			duccLogger.debug(methodName, jobid, retVal);
+		}
+		catch(Throwable t) {
+			duccLogger.error(methodName, jobid, t);
+		}
+		return retVal;
+	}
+
+	@Override
+	public boolean isPasswordChecked() {
+		String methodName = "isPasswordChecked";
+		boolean retVal = false;
+		try {
+			retVal = iAuthenticationManager.isPasswordChecked();
+			duccLogger.debug(methodName, jobid, retVal);
+		}
+		catch(Throwable t) {
+			duccLogger.error(methodName, jobid, t);
+		}
+		return retVal;
+	}
+
+	@Override
+	public IAuthenticationResult isAuthenticate(String userid, String domain, String password) {
+		String methodName = "isAuthenticate";
+		IAuthenticationResult retVal = null;
+		try {
+			retVal = iAuthenticationManager.isAuthenticate(userid, domain, password);
+			duccLogger.debug(methodName, jobid, retVal);
+		}
+		catch(Throwable t) {
+			duccLogger.error(methodName, jobid, t);
+		}
+		return retVal;
+	}
+
+	@Override
+	public IAuthenticationResult isGroupMember(String userid, String domain, Role role) {
+		String methodName = "isGroupMember";
+		IAuthenticationResult retVal = null;
+		try {
+			retVal = iAuthenticationManager.isGroupMember(userid, domain, role);
+			duccLogger.debug(methodName, jobid, retVal);
+		}
+		catch(Throwable t) {
+			duccLogger.error(methodName, jobid, t);
+		}
+		return retVal;
+	}
+	
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/LinuxAuthenticationManager.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/LinuxAuthenticationManager.java?rev=1542505&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/LinuxAuthenticationManager.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/LinuxAuthenticationManager.java Sat Nov 16 13:07:49 2013
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.ws.authentication;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.uima.ducc.common.authentication.AuthenticationResult;
+import org.apache.uima.ducc.common.authentication.IAuthenticationManager;
+import org.apache.uima.ducc.common.authentication.IAuthenticationResult;
+import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
+
+public class LinuxAuthenticationManager implements IAuthenticationManager {
+	
+	private static IAuthenticationManager instance = new LinuxAuthenticationManager();
+	
+	private String version = "ducc linux 1.0";
+	
+	private DuccPropertiesResolver duccPropertiesResolver = DuccPropertiesResolver.getInstance();
+	
+	private ConcurrentHashMap<String,String[]> userGroupsCache = new ConcurrentHashMap<String,String[]>();
+	
+	public static IAuthenticationManager getInstance() {
+		return instance;
+	}
+	
+	@Override
+	public String getVersion() {
+		return version;
+	}
+
+	@Override
+	public boolean isPasswordChecked() {
+		return true;
+	}
+
+	private String getFileProperty(String key) {
+		String retVal = duccPropertiesResolver.getFileProperty(key);
+		return retVal;
+	}
+
+	private String getProperty(String key) {
+		return getFileProperty(key);
+	}
+	
+	private String removeDelimiters(String string) {
+		String retVal = string;
+		if(retVal == null) {
+			retVal = "";
+		}
+		else {
+			retVal = retVal.replace(',', ' ');
+			retVal = retVal.replace(';', ' ');
+			retVal = retVal.replace(':', ' ');
+		}
+		return retVal.trim();
+	}
+	
+	private String transform(String string) {
+		String retVal = removeDelimiters(string);
+		return(retVal);
+	}
+	
+	private boolean finder(String rawNeedle, String rawHaystack) {
+		boolean retVal = false;
+		if(rawNeedle != null) {
+			if(rawHaystack != null) {
+				String needle = " "+rawNeedle+" ";
+				String haystack = " "+rawHaystack+" ";
+				if(haystack.contains(needle)) {
+					retVal = true;
+				}
+			}
+		}
+		return retVal;
+	}
+	
+	private IAuthenticationResult checkUserExcluded(String userid) {
+		IAuthenticationResult retVal = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+		if(userid == null) {
+			retVal.setFailure();
+			retVal.setReason("userid missing");
+		}
+		else {
+			String uid = transform(userid);
+			String excludeString = transform(getProperty(DuccPropertiesResolver.ducc_authentication_users_exclude));
+			if(excludeString.trim().length() > 0) {
+				if(finder(uid,excludeString)) {
+					retVal.setFailure();
+					retVal.setReason("userid excluded");
+				}
+			}
+		}
+		return retVal;
+	}
+	
+	private IAuthenticationResult checkUserNotIncluded(String userid) {
+		IAuthenticationResult retVal = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+		if(userid == null) {
+			retVal.setFailure();
+			retVal.setReason("userid missing");
+		}
+		else {
+			String uid = transform(userid);
+			String includeString = transform(getProperty(DuccPropertiesResolver.ducc_authentication_users_include));
+			if(includeString.trim().length() > 0) {
+				if(!finder(uid,includeString)) {
+					retVal.setFailure();
+					retVal.setReason("userid not included");
+				}
+			}
+		}
+		return retVal;
+	}
+	
+	@Override
+	public IAuthenticationResult isAuthenticate(String userid, String domain, String password) {
+		IAuthenticationResult ar = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+		try {
+			ar = checkUserExcluded(userid);
+			if(ar.isSuccess()) {
+				ar = checkUserNotIncluded(userid);
+				if(ar.isSuccess()) {
+					String[] args = { userid, password };
+					UserAuthenticate instance = new UserAuthenticate();
+					String result = instance.launch(args);
+					// success groups = [group1, group2]
+					if(result.startsWith("success")) {
+						result = result.trim();
+						result = result.replace("success groups =", "");
+						result = result.replace("[", "");
+						result = result.replace("]", "");
+						result = result.replace(" ", "");
+						String[] groups = result.split(",");
+						if(groups != null) {
+							userGroupsCache.put(userid, groups);
+						}
+						else {
+							userGroupsCache.remove(userid);
+						}
+					}
+					// failure pam_authenticate failed: Authentication failure
+					else {
+						ar.setFailure();
+						result = result.replace("failure pam", "pam");
+						ar.setReason(result);
+					}
+				}
+			}
+		}
+		catch(Exception e) {
+			ar.setFailure();
+			ar.setException(e);
+		}
+		return ar;
+	}
+	
+	private IAuthenticationResult checkUserGroupExcluded(String userid) {
+		IAuthenticationResult retVal = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+		if(userid == null) {
+			retVal.setFailure();
+			retVal.setReason("userid missing");
+		}
+		else {
+			String excludeString = transform(getProperty(DuccPropertiesResolver.ducc_authentication_groups_exclude));
+			if(excludeString.trim().length() > 0) {
+				String[] userGroups = userGroupsCache.get(userid);
+				if(userGroups == null) {
+					retVal.setFailure();
+					retVal.setReason("userid has no groups?");
+				}
+				else {
+					for(String userGroup : userGroups) {
+						if(finder(userGroup,excludeString)) {
+							retVal.setFailure();
+							retVal.setReason("userid group "+userGroup+" excluded");
+							break;
+						}
+					}
+				}
+			}
+		}
+		return retVal;
+	}
+	
+	private IAuthenticationResult checkUserGroupNotIncluded(String userid) {
+		IAuthenticationResult retVal = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+		if(userid == null) {
+			retVal.setFailure();
+			retVal.setReason("userid missing");
+		}
+		else {
+			String includeString = transform(getProperty(DuccPropertiesResolver.ducc_authentication_groups_include));
+			if(includeString.trim().length() > 0) {
+				String[] userGroups = userGroupsCache.get(userid);
+				if(userGroups == null) {
+					retVal.setFailure();
+					retVal.setReason("userid has no groups?");
+				}
+				else {
+					retVal.setFailure();
+					retVal.setReason("userid has no group included");
+					for(String userGroup : userGroups) {
+						if(finder(userGroup,includeString)) {
+							retVal = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+							break;
+						}
+					}
+				}
+			}
+		}
+		return retVal;
+	}
+	
+	@Override
+	public IAuthenticationResult isGroupMember(String userid, String domain, Role role) {
+		IAuthenticationResult ar = new AuthenticationResult(IAuthenticationResult.SUCCESS);
+		try {
+			ar = checkUserGroupExcluded(userid);
+			if(ar.isSuccess()) {
+				ar = checkUserGroupNotIncluded(userid);
+			}
+		}
+		catch(Exception e) {
+			ar.setFailure();
+			ar.setException(e);
+		}
+		return ar;
+	}
+	
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java?rev=1542505&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamAuthenticate.java Sat Nov 16 13:07:49 2013
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.ws.authentication;
+
+import org.jvnet.libpam.PAM;
+import org.jvnet.libpam.UnixUser;
+
+public class PamAuthenticate {
+
+	private enum Result { success, failure };
+	
+	private void info(Result result, String text) {
+		System.out.println(result.name()+" "+text);
+	}
+	
+	protected void launch(String[] args, boolean verbose) {
+		try {
+			if(args == null) {
+				info(Result.failure, "args==null");
+			}
+			else if(args.length != 2) {
+				info(Result.failure, "args.length!=2");
+			}
+			else if(args[0] == null) {
+				info(Result.failure, "args[0]==null");
+			}
+			else if(args[1] == null) {
+				info(Result.failure, "args[1]==null");
+			}
+			else {
+				String userid = args[0];
+				String password = args[1];
+				UnixUser u = new PAM("sshd").authenticate(userid, password);
+				info(Result.success, "groups = "+u.getGroups().toString());
+			}
+			
+		}
+		catch(Throwable t) {
+			info(Result.failure,t.getMessage());
+			if(verbose) {
+				t.printStackTrace();
+			}
+		}
+	}
+	
+	public static void main(String[] args) {
+		PamAuthenticate instance = new PamAuthenticate();
+		instance.launch(args, false);
+	}
+
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamTest.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamTest.java?rev=1542505&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamTest.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/PamTest.java Sat Nov 16 13:07:49 2013
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.ws.authentication;
+
+public class PamTest {
+	
+	public static void main(String[] args) {
+		PamAuthenticate instance = new PamAuthenticate();
+		instance.launch(args, true);
+	}
+
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java?rev=1542505&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/authentication/UserAuthenticate.java Sat Nov 16 13:07:49 2013
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.ws.authentication;
+
+import org.apache.uima.ducc.common.utils.DuccLogger;
+import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
+import org.apache.uima.ducc.common.utils.DuccPropertiesResolver;
+
+public class UserAuthenticate {
+	
+	private static DuccLogger duccLogger = DuccLoggerComponents.getWsLogger(UserAuthenticate.class.getName());
+	
+	private String failure = "failure";
+	
+	public String launch(String[] args) {
+		String methodName = "launch";
+		String result = null;
+		try {
+			if(args == null) {
+				result = failure + " args==null";
+			}
+			else if(args.length != 2) {
+				result = failure + " args.length!=2";
+			}
+			else if(args[0] == null) {
+				result = failure + " args[0]==null";
+			}
+			else if(args[1] == null) {
+				result = failure + " args[1]==null";
+			}
+			else {
+				String userId = args[0];
+				String cp = System.getProperty("java.class.path");
+				String jclass = "org.apache.uima.ducc.ws.authentication.PamAuthenticate";
+				String jhome = System.getProperty("java.home");
+				String java = "/bin/java";
+				StringBuffer mask = new StringBuffer();
+				for(int i=0; i<args[1].length(); i++) {
+					mask.append("x");
+				}
+				String[] arglist = { "-u", userId, "-q", "--", jhome+java, "-cp", cp, jclass, args[0], args[1] };
+				String[] masklist = { "-u", userId, "-q", "--", jhome+java, "-cp", cp, jclass, args[0], mask.toString() };
+				duccLogger.debug(methodName, null, masklist[0]);
+				duccLogger.debug(methodName, null, masklist[1]);
+				duccLogger.debug(methodName, null, masklist[2]);
+				duccLogger.debug(methodName, null, masklist[3]);
+				duccLogger.debug(methodName, null, masklist[4]);
+				duccLogger.debug(methodName, null, masklist[5]);
+				//duccLogger.debug(methodName, null, masklist[6]);
+				String[] cplist = cp.split(":");
+				if(cplist != null) {
+					for(String item : cplist) {
+						duccLogger.debug(methodName, null, item);
+					}
+				}
+				duccLogger.debug(methodName, null, masklist[7]);
+				duccLogger.debug(methodName, null, masklist[8]);
+				duccLogger.debug(methodName, null, masklist[9]);
+				result = DuccAsUser.ducklingQuiet(userId, arglist, masklist);
+			}
+		}
+		catch(Throwable t) {
+			result = failure+" "+t.getMessage();
+		}
+		return result;
+	}
+	
+	public static void main(String[] args) {
+		String key = "DUCC_HOME";
+		String value = System.getenv(key);
+		if(value != null) {
+			System.setProperty(key, value);
+		}
+		DuccPropertiesResolver dpr = DuccPropertiesResolver.getInstance();
+		key = "ducc.agent.launcher.ducc_spawn_path";
+		value = dpr.getFileProperty("ducc.agent.launcher.ducc_spawn_path");
+		if(value != null) {
+			System.setProperty(key, value);
+		}
+		UserAuthenticate instance = new UserAuthenticate();
+		String result = instance.launch(args);
+		System.out.println(result);
+	}
+
+}

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java?rev=1542505&r1=1542504&r2=1542505&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java Sat Nov 16 13:07:49 2013
@@ -91,6 +91,8 @@ import org.apache.uima.ducc.ws.DuccMachi
 import org.apache.uima.ducc.ws.JobProcessInfo;
 import org.apache.uima.ducc.ws.MachineInfo;
 import org.apache.uima.ducc.ws.MachineSummaryInfo;
+import org.apache.uima.ducc.ws.authentication.DuccAsUser;
+import org.apache.uima.ducc.ws.authentication.DuccAuthenticator;
 import org.apache.uima.ducc.ws.registry.IServicesRegistry;
 import org.apache.uima.ducc.ws.registry.ServicesRegistry;
 import org.apache.uima.ducc.ws.registry.ServicesRegistryMapPayload;

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java?rev=1542505&r1=1542504&r2=1542505&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java Sat Nov 16 13:07:49 2013
@@ -30,6 +30,7 @@ import org.apache.uima.ducc.common.inter
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.common.utils.DuccLoggerComponents;
 import org.apache.uima.ducc.common.utils.id.DuccId;
+import org.apache.uima.ducc.ws.authentication.DuccAuthenticator;
 import org.eclipse.jetty.server.Request;
 
 public class DuccHandlerUserAuthentication extends DuccAbstractHandler {

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorJob.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorJob.java?rev=1542505&r1=1542504&r2=1542505&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorJob.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorJob.java Sat Nov 16 13:07:49 2013
@@ -38,6 +38,7 @@ import org.apache.uima.ducc.transport.ev
 import org.apache.uima.ducc.transport.event.common.IDuccState.JobState;
 import org.apache.uima.ducc.transport.event.common.IDuccWork;
 import org.apache.uima.ducc.transport.event.common.IRationale;
+import org.apache.uima.ducc.ws.authentication.DuccAsUser;
 
 public class DuccWebMonitorJob {
 	

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorManagedReservation.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorManagedReservation.java?rev=1542505&r1=1542504&r2=1542505&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorManagedReservation.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebMonitorManagedReservation.java Sat Nov 16 13:07:49 2013
@@ -37,6 +37,7 @@ import org.apache.uima.ducc.transport.ev
 import org.apache.uima.ducc.transport.event.common.IDuccProcess;
 import org.apache.uima.ducc.transport.event.common.IDuccState.JobState;
 import org.apache.uima.ducc.transport.event.common.IDuccWork;
+import org.apache.uima.ducc.ws.authentication.DuccAsUser;
 
 public class DuccWebMonitorManagedReservation {