001: /*
002: * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.security.auth.module;
027:
028: import java.util.*;
029: import java.io.IOException;
030: import javax.security.auth.*;
031: import javax.security.auth.callback.*;
032: import javax.security.auth.login.*;
033: import javax.security.auth.spi.*;
034: import com.sun.security.auth.SolarisPrincipal;
035: import com.sun.security.auth.SolarisNumericUserPrincipal;
036: import com.sun.security.auth.SolarisNumericGroupPrincipal;
037:
038: /**
039: * <p> This <code>LoginModule</code> imports a user's Solaris
040: * <code>Principal</code> information (<code>SolarisPrincipal</code>,
041: * <code>SolarisNumericUserPrincipal</code>,
042: * and <code>SolarisNumericGroupPrincipal</code>)
043: * and associates them with the current <code>Subject</code>.
044: *
045: * <p> This LoginModule recognizes the debug option.
046: * If set to true in the login Configuration,
047: * debug messages will be output to the output stream, System.out.
048: * @deprecated As of JDK1.4, replaced by
049: * <code>com.sun.security.auth.module.UnixLoginModule</code>.
050: * This LoginModule is entirely deprecated and
051: * is here to allow for a smooth transition to the new
052: * UnixLoginModule.
053: *
054: * @version 1.19, 01/11/00
055: */
056: @Deprecated
057: public class SolarisLoginModule implements LoginModule {
058:
059: // initial state
060: private Subject subject;
061: private CallbackHandler callbackHandler;
062: private Map<String, ?> sharedState;
063: private Map<String, ?> options;
064:
065: // configurable option
066: private boolean debug = true;
067:
068: // SolarisSystem to retrieve underlying system info
069: private SolarisSystem ss;
070:
071: // the authentication status
072: private boolean succeeded = false;
073: private boolean commitSucceeded = false;
074:
075: // Underlying system info
076: private SolarisPrincipal userPrincipal;
077: private SolarisNumericUserPrincipal UIDPrincipal;
078: private SolarisNumericGroupPrincipal GIDPrincipal;
079: private LinkedList<SolarisNumericGroupPrincipal> supplementaryGroups = new LinkedList<SolarisNumericGroupPrincipal>();
080:
081: /**
082: * Initialize this <code>LoginModule</code>.
083: *
084: * <p>
085: *
086: * @param subject the <code>Subject</code> to be authenticated. <p>
087: *
088: * @param callbackHandler a <code>CallbackHandler</code> for communicating
089: * with the end user (prompting for usernames and
090: * passwords, for example). <p>
091: *
092: * @param sharedState shared <code>LoginModule</code> state. <p>
093: *
094: * @param options options specified in the login
095: * <code>Configuration</code> for this particular
096: * <code>LoginModule</code>.
097: */
098: public void initialize(Subject subject,
099: CallbackHandler callbackHandler,
100: Map<String, ?> sharedState, Map<String, ?> options) {
101:
102: this .subject = subject;
103: this .callbackHandler = callbackHandler;
104: this .sharedState = sharedState;
105: this .options = options;
106:
107: // initialize any configured options
108: debug = "true".equalsIgnoreCase((String) options.get("debug"));
109: }
110:
111: /**
112: * Authenticate the user (first phase).
113: *
114: * <p> The implementation of this method attempts to retrieve the user's
115: * Solaris <code>Subject</code> information by making a native Solaris
116: * system call.
117: *
118: * <p>
119: *
120: * @exception FailedLoginException if attempts to retrieve the underlying
121: * system information fail.
122: *
123: * @return true in all cases (this <code>LoginModule</code>
124: * should not be ignored).
125: */
126: public boolean login() throws LoginException {
127:
128: long[] solarisGroups = null;
129:
130: ss = new SolarisSystem();
131:
132: if (ss == null) {
133: succeeded = false;
134: throw new FailedLoginException(
135: "Failed in attempt to import "
136: + "the underlying system identity information");
137: } else {
138: userPrincipal = new SolarisPrincipal(ss.getUsername());
139: UIDPrincipal = new SolarisNumericUserPrincipal(ss.getUid());
140: GIDPrincipal = new SolarisNumericGroupPrincipal(
141: ss.getGid(), true);
142: if (ss.getGroups() != null && ss.getGroups().length > 0)
143: solarisGroups = ss.getGroups();
144: for (int i = 0; i < solarisGroups.length; i++) {
145: SolarisNumericGroupPrincipal ngp = new SolarisNumericGroupPrincipal(
146: solarisGroups[i], false);
147: if (!ngp.getName().equals(GIDPrincipal.getName()))
148: supplementaryGroups.add(ngp);
149: }
150: if (debug) {
151: System.out.println("\t\t[SolarisLoginModule]: "
152: + "succeeded importing info: ");
153: System.out.println("\t\t\tuid = " + ss.getUid());
154: System.out.println("\t\t\tgid = " + ss.getGid());
155: solarisGroups = ss.getGroups();
156: for (int i = 0; i < solarisGroups.length; i++) {
157: System.out.println("\t\t\tsupp gid = "
158: + solarisGroups[i]);
159: }
160: }
161: succeeded = true;
162: return true;
163: }
164: }
165:
166: /**
167: * Commit the authentication (second phase).
168: *
169: * <p> This method is called if the LoginContext's
170: * overall authentication succeeded
171: * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
172: * succeeded).
173: *
174: * <p> If this LoginModule's own authentication attempt
175: * succeeded (the importing of the Solaris authentication information
176: * succeeded), then this method associates the Solaris Principals
177: * with the <code>Subject</code> currently tied to the
178: * <code>LoginModule</code>. If this LoginModule's
179: * authentication attempted failed, then this method removes
180: * any state that was originally saved.
181: *
182: * <p>
183: *
184: * @exception LoginException if the commit fails
185: *
186: * @return true if this LoginModule's own login and commit attempts
187: * succeeded, or false otherwise.
188: */
189: public boolean commit() throws LoginException {
190: if (succeeded == false) {
191: if (debug) {
192: System.out.println("\t\t[SolarisLoginModule]: "
193: + "did not add any Principals to Subject "
194: + "because own authentication failed.");
195: }
196: return false;
197: }
198: if (subject.isReadOnly()) {
199: throw new LoginException("Subject is Readonly");
200: }
201: if (!subject.getPrincipals().contains(userPrincipal))
202: subject.getPrincipals().add(userPrincipal);
203: if (!subject.getPrincipals().contains(UIDPrincipal))
204: subject.getPrincipals().add(UIDPrincipal);
205: if (!subject.getPrincipals().contains(GIDPrincipal))
206: subject.getPrincipals().add(GIDPrincipal);
207: for (int i = 0; i < supplementaryGroups.size(); i++) {
208: if (!subject.getPrincipals().contains(
209: supplementaryGroups.get(i)))
210: subject.getPrincipals().add(supplementaryGroups.get(i));
211: }
212:
213: if (debug) {
214: System.out.println("\t\t[SolarisLoginModule]: "
215: + "added SolarisPrincipal,");
216: System.out.println("\t\t\t\tSolarisNumericUserPrincipal,");
217: System.out
218: .println("\t\t\t\tSolarisNumericGroupPrincipal(s),");
219: System.out.println("\t\t\t to Subject");
220: }
221:
222: commitSucceeded = true;
223: return true;
224: }
225:
226: /**
227: * Abort the authentication (second phase).
228: *
229: * <p> This method is called if the LoginContext's
230: * overall authentication failed.
231: * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
232: * did not succeed).
233: *
234: * <p> This method cleans up any state that was originally saved
235: * as part of the authentication attempt from the <code>login</code>
236: * and <code>commit</code> methods.
237: *
238: * <p>
239: *
240: * @exception LoginException if the abort fails
241: *
242: * @return false if this LoginModule's own login and/or commit attempts
243: * failed, and true otherwise.
244: */
245: public boolean abort() throws LoginException {
246: if (debug) {
247: System.out.println("\t\t[SolarisLoginModule]: "
248: + "aborted authentication attempt");
249: }
250:
251: if (succeeded == false) {
252: return false;
253: } else if (succeeded == true && commitSucceeded == false) {
254:
255: // Clean out state
256: succeeded = false;
257: ss = null;
258: userPrincipal = null;
259: UIDPrincipal = null;
260: GIDPrincipal = null;
261: supplementaryGroups = new LinkedList<SolarisNumericGroupPrincipal>();
262: } else {
263: // overall authentication succeeded and commit succeeded,
264: // but someone else's commit failed
265: logout();
266: }
267: return true;
268: }
269:
270: /**
271: * Logout the user
272: *
273: * <p> This method removes the Principals associated
274: * with the <code>Subject</code>.
275: *
276: * <p>
277: *
278: * @exception LoginException if the logout fails
279: *
280: * @return true in all cases (this <code>LoginModule</code>
281: * should not be ignored).
282: */
283: public boolean logout() throws LoginException {
284: if (debug) {
285: System.out.println("\t\t[SolarisLoginModule]: "
286: + "Entering logout");
287: }
288: if (subject.isReadOnly()) {
289: throw new LoginException("Subject is Readonly");
290: }
291: // remove the added Principals from the Subject
292: subject.getPrincipals().remove(userPrincipal);
293: subject.getPrincipals().remove(UIDPrincipal);
294: subject.getPrincipals().remove(GIDPrincipal);
295: for (int i = 0; i < supplementaryGroups.size(); i++) {
296: subject.getPrincipals().remove(supplementaryGroups.get(i));
297: }
298:
299: // clean out state
300: ss = null;
301: succeeded = false;
302: commitSucceeded = false;
303: userPrincipal = null;
304: UIDPrincipal = null;
305: GIDPrincipal = null;
306: supplementaryGroups = new LinkedList<SolarisNumericGroupPrincipal>();
307:
308: if (debug) {
309: System.out.println("\t\t[SolarisLoginModule]: "
310: + "logged out Subject");
311: }
312: return true;
313: }
314: }
|