Package com.sun.grid.security.login

Source Code of com.sun.grid.security.login.UnixLoginModule

/*___INFO__MARK_BEGIN__*/
/*************************************************************************
*
*  The Contents of this file are made available subject to the terms of
*  the Sun Industry Standards Source License Version 1.2
*
*  Sun Microsystems Inc., March, 2001
*
*
*  Sun Industry Standards Source License Version 1.2
*  =================================================
*  The contents of this file are subject to the Sun Industry Standards
*  Source License Version 1.2 (the "License"); You may not use this file
*  except in compliance with the License. You may obtain a copy of the
*  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
*
*  Software provided under this License is provided on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
*  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
*  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
*  See the License for the specific provisions governing your rights and
*  obligations concerning the Software.
*
*   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
*   Copyright: 2001 by Sun Microsystems, Inc.
*
*   All Rights Reserved.
*
************************************************************************/
/*___INFO__MARK_END__*/
package com.sun.grid.security.login;

import com.sun.grid.util.SGEUtil;
import java.io.File;
import java.io.IOException;
import java.security.Principal;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

/**
* This <code>LoginModule</code> authenticates a unix user with username
* and password against the PAM or system authentication system.
*
* The username is queried with a <code>NameCallback</code>, the password with
* a <code>PasswordCallback</code>
*
* <p>After a successfull login this <code>LoginModule</code> adds
*
* <ul>
*    <li> a {@link com.sun.security.auth.UnixPrincipal} of the authenticated user</li>
*    <li> a {@link com.sun.security.auth.UnixNumericUserPrincipal} with the user id
*         of the authenticated user</li>
*    <li> a {@link  com.sun.security.auth.UnixNumericGroupPrincipal} for each group the authenticated
*         user belongs too</li>
* </ul>
*
* to the current subject.</p>
*
* <p>This class uses a {@link java.util.logging.Logger} for log messages. The name of the <code>Logger</code>
*    is equal to the fullqualified classname of this class.</p>
*
* <H3>Options for UnixLoginModule</H3>
*
* <table>
*   <tr><th>Option</th><th>description</th></tr>
*   <tr>
*      <td>sge_root</td>
*      <td>path to the gridengine distribution</td>
*   </tr>
*   <tr>
*      <td>auth_method</td>
*      <td>Autehtication method. Valid values are "pam" and "system"</td>
*   </tr>
*   <tr>
*      <td>pam_service</td>
*      <td>Name of the pam service (see man pam(5). Required for
*          PAM authentifcation</td>
*   </tr>
* </table>
*
* <H3>Simple jaas config file for PAM authentication</H3>
*
* <pre>
*  sample {
*   com.sun.grid.security.login.UnixLoginModule requisite
*         sge_root="/opt/sge",
*         auth_method="pam";
*         pam_service="su";
*  };
* </pre>
*
* <H3>Simple jaas config file for system authentication</H3>
*
* <pre>
*  sample {
*   com.sun.grid.security.login.UnixLoginModule requisite
*         command="/opt/sge",
*         auth_method="system";
*  };
* </pre>
*
*/
public class UnixLoginModule implements LoginModule {

    private static final String AUTHZ_IDENTITY = "authzIdentity";   
   
    private final static Logger log = Logger.getLogger(UnixLoginModule.class.getName(), RB.BUNDLE);
    private String confError;
    private String authMethod;
    private String pamService;
    private String command;
    private Subject subject;
    private boolean loginSucceded;
    private boolean commitSucceded;
    private CallbackHandler callbackHandler;
    private Set principals = new HashSet();
    private String authzIdentity;
   

    /**
     * Initialize the <code>UnixLoginModule</code>
     * @param subject   the current subject
     * @param callbackHandler the callbackhandler (must at least handle a
     *                        <code>NameCallback</code> and a
     *                        </code>PasswordCallback</code>).
     * @param sharedState not used
     * @param options contains the options for the <code>UnixLoginModule</code>.
     */
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {

        log.entering("UnixLoginModule", "initialize");

        String sgeRoot = (String) options.get("sge_root");
        if (sgeRoot != null) {
            log.log(Level.FINE, "sge_root={0}", sgeRoot);
            try {
                String arch = SGEUtil.getArch(new File(sgeRoot));
                command = sgeRoot + File.separatorChar + "utilbin" + File.separatorChar + arch + File.separatorChar + "authuser";
                if (arch.equals("win32-x86")) {
                    command += ".exe";
                }
                log.log(Level.FINE, "command={0}", command);
            } catch (Exception ex) {
                log.log(Level.WARNING, "unixlogin.error.arch", ex);
                confError = RB.getString("unixlogin.error.arch", ex.getLocalizedMessage());
                return;
            }
        } else {
            log.log(Level.WARNING, "unixlogin.error.arch", "sge_root");
            confError = RB.getString("unixlogin.error.missing", "sge_root");
            return;
        }
        authMethod = (String) options.get("auth_method");
        if (authMethod == null) {
            log.log(Level.WARNING, "unixlogin.error.missing", "auth_method");
            confError = RB.getString("unixlogin.error.missing", "auth_method");
            return;
        }
        log.log(Level.FINE, "auth_method={0}", authMethod);
        if ("pam".equals(authMethod)) {
            pamService = (String) options.get("pam_service");
            if (pamService == null) {
                log.log(Level.WARNING, "unixlogin.error.missing", "pam_service");
                confError = RB.getString("unixlogin.error.missing", "pam_service");
                return;
            } else {
                log.log(Level.FINE, "pam_service={0}", pamService);
            }
        }
        authzIdentity = (String) options.get(AUTHZ_IDENTITY);
        if(authzIdentity != null && authzIdentity.length() == 0) {
            authzIdentity = null;
        }
       
        this.subject = subject;
        this.callbackHandler = callbackHandler;

        log.entering("UnixLoginModule", "exiting");

    }

    /**
     * Perform the login.
     *
     * @throws javax.security.auth.login.LoginException <ul>
     *      <li>if the callbackhandler reports an error</li>
     *      <li>if some options are missing (please check the jass.config file)</li>
     *      <li>if the underlying authentication system report an error</li>
     *    </ul>
     * @return <code>true</code> on successfull authentication. <code>false</code>
     *         if username of password is invalid.
     */
    public boolean login() throws LoginException {

        log.entering("UnixLoginModule", "login");

        if (confError != null) {
            throw RB.newLoginException("unixlogin.error.conf", new Object[]{confError});
        }
        PasswordCallback pwCallback = new PasswordCallback(RB.getString("unixlogin.userprompt"), false);
        NameCallback nameCallback = new NameCallback(RB.getString("unixlogin.pwprompt"));

        try {
            callbackHandler.handle(new Callback[]{nameCallback, pwCallback});
        } catch (IOException ex) {
            throw RB.newLoginException("unixlogin.error.iocb", ex,
                    new Object[]{ex.getLocalizedMessage()});
        } catch (UnsupportedCallbackException ex) {
            throw RB.newLoginException("unixlogin.error.invalidcb", ex,
                    new Object[]{ex.getLocalizedMessage()});
        }

        String username = nameCallback.getName();
        if (username == null || username.length() == 0) {
            loginSucceded = false;
            log.exiting("UnixLoginModule", "login", Boolean.FALSE);
            return loginSucceded;
        }

        char[] pw = pwCallback.getPassword();
        if (pw == null) {
            loginSucceded = false;
            log.exiting("UnixLoginModule", "login", Boolean.FALSE);
            return loginSucceded;
        }

        AuthUserWrapper authuser = null;
        if (authMethod == null) {
            throw RB.newLoginException("unixlogin.error.missing",
                    new Object[]{"auth_method"});
        } else if ("pam".equals(authMethod)) {
            authuser = AuthUserWrapper.newInstanceForPam(command, pamService);
        } else if ("shadow".equals(authMethod)) {
            log.log(Level.WARNING, "unixlogin.deprecatedAuthMethod",
                    new Object[]{authMethod, "system"});
            authuser = AuthUserWrapper.newInstance(command);
        } else if ("system".equals(authMethod)) {
            authuser = AuthUserWrapper.newInstance(command);
        } else {
            throw RB.newLoginException("unixlogin.error.unknownAuthMethod",
                    new Object[]{authMethod});
        }

        try {
            Set p = authuser.authenticate(username, pw);
            if (p != null) {
                log.log(Level.FINE, "unixlogin.authuser.principal.count", new Integer(p.size()));
                if(log.isLoggable(Level.FINER)) {
                    Iterator iter = p.iterator();
                    while(iter.hasNext()) {
                        Principal pr = (Principal)iter.next();
                        log.log(Level.FINER,"unixlogin.authuser.principal", new Object [] { pr.getClass().getName(), pr.getName() });
                    }
                }
                principals.addAll(p);
                if (authzIdentity != null) {
                    principals.add(new UserPrincipal(authzIdentity));
                }
               
                loginSucceded = true;
            } else {
                log.log(Level.FINE, "unixlogin.authuser.principal.no");
                loginSucceded = false;
            }
        } catch (LoginException ex) {
            log.throwing("UnixLoginModule", "login", ex);
            throw ex;
        }
        log.exiting("UnixLoginModule", "login", Boolean.valueOf(loginSucceded));
        return loginSucceded;
    }

    /**
     * Commit the login (adds the principals to the subject)
     *
     * @return <code>true</code> of the principals has been added to the subject.
     */
    public boolean commit() {
        log.entering("UnixLoginModule", "commit");
        if (loginSucceded) {
            subject.getPrincipals().addAll(principals);
            if (log.isLoggable(Level.FINER)) {
                log.log(Level.FINE, "unixlogin.subject.principal",
                        new Integer(subject.getPrincipals().size()));
            }
            commitSucceded = true;
        }
        log.exiting("UnixLoginModule", "commit", Boolean.valueOf(commitSucceded));
        return commitSucceded;
    }

    /**
     * Abort the login.
     * @return Always <code>true</code>
     */
    public boolean abort() {
        logout();
        return true;
    }

    /**
     * Removes all previously added prinicipals from the subject.
     *
     * @return Always <code>true</code>
     */
    public boolean logout() {
        if (commitSucceded) {
            subject.getPrincipals().removeAll(principals);
        }
        subject = null;
        principals.clear();
        callbackHandler = null;
        loginSucceded = false;
        commitSucceded = false;
        return true;
    }
}
TOP

Related Classes of com.sun.grid.security.login.UnixLoginModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.