001    package org.esupportail.cas.server.handlers.nis;
002    
003    import java.util.Hashtable;
004    
005    import javax.naming.Context;
006    import javax.naming.InitialContext;
007    import javax.naming.directory.InitialDirContext;
008    
009    import org.dom4j.Element;
010    import org.esupportail.cas.server.util.RedundantHandler;
011    import org.esupportail.cas.server.util.Server;
012    import org.esupportail.cas.server.util.crypt.Crypt;
013    import org.esupportail.cas.server.util.log.Log;
014    
015    /**
016     * This class implements a NIS (Network Information Service) server.
017     *
018     * @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
019     */
020    public final class NisServer extends Server {
021            
022            /**
023             * The server hostname or IP address.
024             */
025            private String host;
026    
027            /**
028             * Constructor.
029             *
030             * @param handlerDebug debugging mode of the handler
031             * @param handler      the handler the server will be used by
032             * @param serverElement the XML element that declares the server 
033             * @throws Exception Exception
034             */
035            public NisServer(
036                            final Boolean handlerDebug,
037                            final RedundantHandler handler,
038                            final Element serverElement) throws Exception {
039                    super(handlerDebug, handler, serverElement);
040                    traceBegin();
041    
042                    host = getServerSubElementContent(serverElement, "host", true/*needed*/);
043                    trace("host = " + host);
044    
045                    traceEnd();
046            }
047            
048            
049            /**
050             * Try to authenticate a user (by searching into a NIS domain).
051             *
052             * @param username the user's name
053             * @param password the user's password
054             *
055             * @return Server.AUTHENTICATE_SUCCESS, Server.AUTHENTICATE_NOAUTH
056             * or Server.AUTHENTICATE_FAILURE.
057             */     
058            public int authenticate(final String username,
059                            final String password) {
060                    traceBegin();
061                    
062                    NisHandler handler = (NisHandler) getHandler();
063                    String url = "nis://" + host + "/" + handler.getDomain();
064                    String map = handler.getMap();
065                    
066                    try {
067                            trace("Connecting to the NIS domain...");
068                            Hashtable hashtable = new Hashtable(5, 0.75f);
069                            hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.nis.NISCtxFactory");
070                            hashtable.put(Context.PROVIDER_URL, url);
071                            hashtable.put(Context.SECURITY_AUTHENTICATION, "simple");
072                            InitialContext context = new InitialDirContext(hashtable);
073                            
074                            trace("Retrieving the information corresponding to the user...");
075                            String nisEntry = context.lookup("system/" + map + "/" + username).toString();
076                            
077                            // we've got all needed information, close the context
078                            context.close();
079                            
080                            trace("Username found, checking password (" + handler.getEncryption() + ")...");
081                            // extracting the encrypted password
082                            String[] nisFields = nisEntry.split(":");
083                            String nisEncryptedPassword = nisFields[1];
084                            
085                            // compare the passwords
086                            boolean match = Crypt.match(handler.getEncryption(), password, nisEncryptedPassword);
087                            
088                            if (Crypt.match(handler.getEncryption(), password, nisEncryptedPassword)) {
089                                    trace("Password matches.");
090                                    traceEnd("AUTHENTICATE_SUCCESS");
091                                    return AUTHENTICATE_SUCCESS;
092                            } else {
093                                    trace("Password does not match.");
094                                    traceEnd("AUTHENTICATE_NOAUTH");
095                                    return AUTHENTICATE_NOAUTH;
096                            }
097                    } catch (javax.naming.NoInitialContextException e) {
098                            Log.warn(e.toString());
099                            Log.warn("JNDI nis provider (nis.jar) is probably not installed");
100                            traceEnd("AUTHENTICATE_FAILURE");
101                            return AUTHENTICATE_FAILURE;
102                    } catch (javax.naming.ConfigurationException e) {
103                            Log.warn("Bad NIS configuration: " + e.getMessage());
104                            traceEnd("AUTHENTICATE_FAILURE");
105                            return AUTHENTICATE_FAILURE;
106                    } catch (javax.naming.CommunicationException e) {
107                            Log.warn("NIS server not responding.");
108                            traceEnd("AUTHENTICATE_FAILURE");
109                            return AUTHENTICATE_FAILURE;
110                    } catch (javax.naming.CannotProceedException e) {
111                            Log.warn("Can not proceed: " + e.getMessage());
112                            traceEnd("AUTHENTICATE_NOAUTH");
113                            return AUTHENTICATE_NOAUTH;
114                    } catch (javax.naming.NameNotFoundException e) {
115                            trace("Username not found: " + e.getMessage());
116                            traceEnd("AUTHENTICATE_NOAUTH");
117                            return AUTHENTICATE_NOAUTH;
118                    } catch (Exception e) {
119                            Log.warn("Failure: " + e.toString());
120                            traceEnd("AUTHENTICATE_FAILURE");
121                            return AUTHENTICATE_FAILURE;
122                    }
123            }
124            
125    }
126