Hi guys,

You will find here a patch to add support for NIS servers as source service on 
the trunk. 

I have not joined my test because this would require to add a NIS server to 
LSC :) but if you have a public testing NIS server I will also  send my JUnit 
test class with a binding to it.

I also have a dependency issue because this support seems to require a 
download from the Oracle / Sun website to get support for NIS and it does not 
seems to be integrated on any maven repository : any comment on the following 
license and on the fact that it could be integrated inside our Maven repo ? 

https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-
Site/en_US/-/USD/ViewLicense-Start

Regards
-- 
Sebastien BAHLOUL
IAM Open Source Products Manager
LINAGORA : http://www.linagora.com/
Tel / Phone : +33 1 46 96 63 63
Mobile : +33 (0)6 45 63 27 39
74/80 rue Roque de Fillol
92800 Puteaux
-----------
http://linid.org/ - http://linpki.org/
IAM and security Open Source projects
Index: pom.xml
===================================================================
--- pom.xml	(révision 841)
+++ pom.xml	(copie de travail)
@@ -489,7 +489,12 @@
 			<artifactId>jcifs</artifactId>
 			<version>1.2.19</version>
 		</dependency>
-		
+		<dependency>
+			<!--  Require specific download on Sun/Oracle JNDI provider website : http://java.sun.com/products/jndi/downloads/index.html -->
+		    <groupId>com.sun.jndi</groupId>
+		    <artifactId>nis</artifactId>
+		    <version>1.2.1</version>
+		</dependency>		
 	</dependencies>
 
 	<reporting>
Index: src/main/java/org/lsc/jndi/NisSrcService.java
===================================================================
--- src/main/java/org/lsc/jndi/NisSrcService.java	(révision 0)
+++ src/main/java/org/lsc/jndi/NisSrcService.java	(révision 0)
@@ -0,0 +1,236 @@
+/*
+ ****************************************************************************
+ * Ldap Synchronization Connector provides tools to synchronize
+ * electronic identities from a list of data sources including
+ * any database with a JDBC connector, another LDAP directory,
+ * flat files...
+ *
+ *                  ==LICENSE NOTICE==
+ * 
+ * Copyright (c) 2008, LSC Project 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ *    * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the LSC Project nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *                  ==LICENSE NOTICE==
+ *
+ *               (c) 2008 - 2009 LSC Project
+ *         Sebastien Bahloul <[email protected]>
+ *         Thomas Chemineau <[email protected]>
+ *         Jonathan Clarke <[email protected]>
+ *         Remy-Christophe Schermesser <[email protected]>
+ ****************************************************************************
+ */
+package org.lsc.jndi;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.lsc.Configuration;
+import org.lsc.LscAttributes;
+import org.lsc.beans.IBean;
+import org.lsc.exception.LscConfigurationException;
+import org.lsc.exception.LscServiceConfigurationException;
+import org.lsc.exception.LscServiceException;
+import org.lsc.service.IService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class is a NIS source service implementation
+ * 
+ * You only have to specify the following parameters :
+ * &lt;ul&gt;
+ *  &lt;li&gt;the server name (servername)
+ *  &lt;li&gt;the domain name (domain)
+ *  &lt;li&gt;the map name (map)
+ * &lt;ul&gt;
+ * 
+ * NIS requests are exclusively done on .byname ordering method
+ * 
+ * With the passwd map, the following attributes are exposed :
+ * &lt;pre&gt; 
+ * uid - test
+ * => gidnumber - 1000
+ * => nismapentry - test:x:1000:1000:Test account,,,:/home/test:/bin/bash
+ * => userpassword - A BYTE ARRAY ENCODED STRING
+ * => cn - test
+ * => nismapname - passwd.byname
+ * => loginshell - /bin/bash
+ * => gecos - Test account,,,
+ * => homedirectory - /home/test
+ * => objectclass - nisObject
+ *  - posixAccount
+ *  - top
+ * => uidnumber - 1000
+ * &lt;/pre&gt;
+ * 
+ * @author Sebastien Bahloul &lt;[email protected]&gt;
+ */
+public class NisSrcService implements IService {
+	
+	protected static final Logger LOGGER = LoggerFactory.getLogger(NisSrcService.class);
+	/**
+	 * Preceding the object feeding, it will be instantiated from this class.
+	 */
+	private Class<IBean> beanClass;
+
+	private String servername;
+	
+	private String domain;
+	
+	private String map;
+	
+	private InitialContext context;
+	
+	private Hashtable<String, String> conftable;
+	
+	private Map<String, Attributes> _cache;
+ 
+	public NisSrcService(final Properties serviceProps, final String beanClassName) throws LscServiceConfigurationException {
+
+		try {
+			this.beanClass = (Class<IBean>) Class.forName(beanClassName);
+		} catch (ClassNotFoundException e) {
+			throw new LscServiceConfigurationException(e);
+		}
+		_cache = new HashMap<String, Attributes>();
+		
+		map = serviceProps.getProperty("map");
+
+		domain = serviceProps.getProperty("domain");
+		servername = serviceProps.getProperty("servername");
+		
+		// check that we have all parameters, or abort
+		try {
+			Configuration.assertPropertyNotEmpty("map", map, this.getClass().getName());
+			Configuration.assertPropertyNotEmpty("domain", domain, this.getClass().getName());
+		} catch (LscConfigurationException e) {
+			throw new LscServiceConfigurationException(e);
+		}
+
+		String url = null;
+		if(servername != null) {
+			url = "nis://" + servername + "/" + domain;
+		} else {
+			url = "nis:///" + domain;
+		}
+
+		
+		conftable = new Hashtable<String, String>();
+		conftable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.nis.NISCtxFactory");
+		conftable.put(Context.PROVIDER_URL, url);
+		conftable.put(Context.SECURITY_AUTHENTICATION, "simple");
+	}
+
+
+	@Override
+	public IBean getBean(String pivotName, LscAttributes pivotAttributes)
+			throws LscServiceException {
+		IBean srcBean;
+		try {
+			srcBean = this.beanClass.newInstance();
+			updateCache();
+			NamingEnumeration<String> idsEnum = _cache.get(pivotName).getIDs();
+			while(idsEnum.hasMore()) {
+				srcBean.setAttribute(_cache.get(pivotName).get(idsEnum.next()));
+			}
+			return srcBean;
+		} catch (InstantiationException e) {
+			LOGGER.error("Bad class name: " + beanClass.getName() + "(" + e + ")");
+			LOGGER.debug(e.toString(), e);
+		} catch (IllegalAccessException e) {
+			LOGGER.error("Bad class name: " + beanClass.getName() + "(" + e + ")");
+			LOGGER.debug(e.toString(), e);
+		} catch (NamingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	@Override
+	public Map<String, LscAttributes> getListPivots()
+			throws LscServiceException {
+		Map<String, LscAttributes> ret = new HashMap<String, LscAttributes>();
+		try {
+			for( String name: _cache.keySet() ) {
+				Map<String, Object> attrsMap = new HashMap<String, Object>();
+				NamingEnumeration<? extends Attribute> attrs = _cache.get(name).getAll();
+				while(attrs.hasMore()) {
+					Attribute attr = attrs.next();
+					attrsMap.put(attr.getID(), attr.get());
+				}
+				ret.put(name, new LscAttributes());
+			}
+		} catch (NamingException ne) {
+			throw new LscServiceException(ne.getMessage(), ne);
+		}
+		return ret;
+	}
+
+	private synchronized void updateCache() {
+		try {
+			if(LOGGER.isDebugEnabled()) LOGGER.debug("Connecting to the NIS domain ...");
+			context = new InitialDirContext(conftable);
+			
+			if(LOGGER.isDebugEnabled()) LOGGER.debug("Retrieving the information ...");
+			DirContext maps = (DirContext) context.lookup("system/" + map + ".byname");
+			NamingEnumeration<SearchResult> results = maps.search("", "objectClass=*", new SearchControls());
+			while(results.hasMore()) {
+				SearchResult result = results.next();
+				_cache.put(result.getName(), result.getAttributes());
+			}
+			// we've got all needed information, close the context
+			if(LOGGER.isDebugEnabled()) LOGGER.debug("Closing context ...");
+			context.close();
+		} catch (javax.naming.NoInitialContextException e) {
+			LOGGER.error(e.toString());
+		} catch (javax.naming.ConfigurationException e) {
+			LOGGER.error("Bad NIS configuration: " + e.getMessage());
+		} catch (javax.naming.CommunicationException e) {
+			LOGGER.error("NIS server not responding. (" + e.getMessage() + ")");
+		} catch (javax.naming.CannotProceedException e) {
+			LOGGER.error("Can not proceed: " + e.getMessage());
+		} catch (javax.naming.NameNotFoundException e) {
+			LOGGER.error("Username not found: " + e.getMessage());
+		} catch (Exception e) {
+			LOGGER.error("Failure: " + e.toString());
+		}
+	}
+}
_______________________________________________________________
Ldap Synchronization Connector (LSC) - http://lsc-project.org

lsc-dev mailing list
[email protected]
http://lists.lsc-project.org/listinfo/lsc-dev

Reply via email to