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.BasicHandler;
011: import org.esupportail.cas.server.util.MisconfiguredHandlerException;
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) handler
017: * class. It is used by GenericHandler.
018: *
019: * @author Florent Jouille <florent.jouille at loria dot fr>
020: *
021: * I rewrite the nis handler provided by esup generic package.
022: * This new handler use only one NIS server, and the delegation is
023: * stopped on failure.
024: */
025: public final class NisHandler extends BasicHandler {
026:
027: /**
028: * The NIS domain to bind to.
029: */
030: private String domain;
031: /**
032: * The NIS server to connect to.
033: */
034: private String host;
035: /**
036: * The map to search into.
037: */
038: private String map;
039: /**
040: * The encryption used to store the passwords.
041: */
042: private String encryption;
043:
044: /**
045: * Constructor.
046: *
047: * @param handlerElement the XML element that declares the handler
048: * in the configuration file
049: * @param configDebug debugging mode of the global configuration
050: * @throws Exception Exception
051: */
052: public NisHandler(final Element handlerElement,
053: final Boolean configDebug) throws Exception {
054: super (handlerElement, configDebug);
055: traceBegin();
056:
057: checkConfigElement(true);
058:
059: domain = getConfigSubElementContent("domain", true/*needed*/);
060: trace("domain = " + domain);
061:
062: host = getConfigSubElementContent("server", true/*needed*/);
063: trace("host = " + host);
064:
065: map = getConfigSubElementContent("map", false/*not needed*/);
066: if (map.equals("")) {
067: map = "passwd.byname";
068: }
069: trace("map = " + map);
070:
071: encryption = getConfigSubElementContent("encryption", false/*not needed*/);
072: if (encryption.equals("")) {
073: encryption = "pammd5";
074: }
075: if (!Crypt.isEncryptionSupported(encryption)) {
076: traceThrow(new MisconfiguredHandlerException(
077: "Encryption \"" + encryption
078: + "\" is not supported."));
079: }
080: trace("encryption = " + encryption);
081: if (encryption.equals("plain")) {
082: traceThrow(new MisconfiguredHandlerException(
083: "Can not use plain passwords with NIS."));
084: }
085:
086: // check that the JNDI class exists
087: checkClass("com.sun.jndi.nis.NISCtxFactory");
088:
089: traceEnd();
090: }
091:
092: /**
093: * Retrieve the map name.
094: *
095: * @return a String Object.
096: */
097: String getMap() {
098: return map;
099: }
100:
101: /**
102: * Retrieve the NIS domain name.
103: *
104: * @return a String Object.
105: */
106: String getDomain() {
107: return domain;
108: }
109:
110: /**
111: * Retrieve the encryption used to store passwords.
112: *
113: * @return a String Object.
114: */
115: String getEncryption() {
116: return encryption;
117: }
118:
119: public int authenticate(String username, String password) {
120: traceBegin();
121:
122: String url = "nis://" + host + "/" + getDomain();
123: String map = getMap();
124:
125: try {
126: trace("Connecting to the NIS domain...");
127: Hashtable hashtable = new Hashtable(5, 0.75f);
128: hashtable.put(Context.INITIAL_CONTEXT_FACTORY,
129: "com.sun.jndi.nis.NISCtxFactory");
130: hashtable.put(Context.PROVIDER_URL, url);
131: hashtable.put(Context.SECURITY_AUTHENTICATION, "simple");
132: InitialContext context = new InitialDirContext(hashtable);
133:
134: trace("Retrieving the information corresponding to the user...");
135: String nisEntry = context.lookup(
136: "system/" + map + "/" + username).toString();
137:
138: // we've got all needed information, close the context
139: context.close();
140:
141: trace("Username found, checking password ("
142: + getEncryption() + ")...");
143: // extracting the encrypted password
144: String[] nisFields = nisEntry.split(":");
145: String nisEncryptedPassword = nisFields[1];
146:
147: // compare the passwords
148: boolean match = Crypt.match(getEncryption(), password,
149: nisEncryptedPassword);
150:
151: if (Crypt.match(getEncryption(), password,
152: nisEncryptedPassword)) {
153: trace("Password matches.");
154: traceEnd("SUCCESS");
155: return SUCCEEDED;
156: } else {
157: // change here : stop on failure (users unicity with following handlers)
158: trace("Password does not match.");
159: traceEnd("AUTHENTICATE_NOAUTH");
160: return FAILED_STOP;
161: }
162: } catch (javax.naming.NoInitialContextException e) {
163: Log.warn(e.toString());
164: Log
165: .warn("JNDI nis provider (nis.jar) is probably not installed");
166: traceEnd("FAILED_CONTINUE");
167: return FAILED_CONTINUE;
168: } catch (javax.naming.ConfigurationException e) {
169: Log.warn("Bad NIS configuration: " + e.getMessage());
170: traceEnd("FAILED_CONTINUE");
171: return FAILED_CONTINUE;
172: } catch (javax.naming.CommunicationException e) {
173: Log.warn("NIS server not responding.");
174: traceEnd("FAILED_CONTINUE");
175: return FAILED_CONTINUE;
176: } catch (javax.naming.CannotProceedException e) {
177: Log.warn("Can not proceed: " + e.getMessage());
178: traceEnd("FAILED_CONTINUE");
179: return FAILED_CONTINUE;
180: } catch (javax.naming.NameNotFoundException e) {
181: trace("Username not found: " + e.getMessage());
182: traceEnd("FAILED_CONTINUE");
183: return FAILED_CONTINUE;
184: } catch (Exception e) {
185: Log.warn("Failure: " + e.toString());
186: traceEnd("FAILED_CONTINUE");
187: return FAILED_CONTINUE;
188: }
189: }
190:
191: }
|