1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2001 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
32
package com.sun.grid.security.login;
34
import com.sun.grid.util.expect.Expect;
35
import com.sun.grid.util.expect.ExpectBuffer;
36
import com.sun.grid.util.expect.ExpectHandler;
37
import com.sun.grid.util.expect.ExpectPasswordHandler;
38
import com.sun.grid.util.expect.ExpectStringHandler;
39
import java.io.IOException;
40
import java.util.HashSet;
42
import java.util.StringTokenizer;
43
import java.util.logging.Level;
44
import java.util.logging.Logger;
45
import javax.security.auth.login.LoginException;
48
* This class used by the <code>UnixLoginModule</code> to execute the authuser binary
51
class AuthUserWrapper {
53
private static final Logger LOGGER = Logger.getLogger(AuthUserWrapper.class.getName(), RB.BUNDLE);
55
private String [] command;
57
private AuthUserWrapper(String [] command) {
58
this.command = command;
62
* Create a new instance of <code>AuthUserWrapper</code> which uses
63
* the PAM authentication system.
65
* @param authuser path the the authuser binary
66
* @param pamServiceName name of the user pam service
67
* @return the <code>AuthUserWrapper</code>.
69
public static AuthUserWrapper newInstanceForPam(String authuser, String pamServiceName) {
70
return new AuthUserWrapper( new String [] {
71
authuser, "pam", "-s", pamServiceName
76
* Create a new instance of <code>AuthUserWrapper</code> which uses
77
* the authentication system of the operation system
79
* @param authuser path the the authuser binary
80
* @return the <code>AuthUserWrapper</code>.
82
public static AuthUserWrapper newInstance(String authuser) {
83
return new AuthUserWrapper( new String [] {
91
* @param username username
92
* @param password the password
93
* @throws javax.security.auth.login.LoginException <ul>
94
* <li>if the authuser binary reports and error (authuser exited with status 2)</li>
95
* <li>if the authuser can not be started</li>
96
* <li>if the authuser has been interrupted</li>
99
* <li><code>null</code> if <code>username</code> of <code>password</code> is invalid.
100
* (authuser exited with status 1)
102
* <li> else a <code>Set</code> containing <ul>
103
* <li> a {@link com.sun.grid.security.login.UserPrincipal} of the authenticated user</li>
104
* <li> a {@link com.sun.grid.security.login.NumericUserPrincipal} with the user id
105
* of the authenticated user</li>
106
* <li> a {@link com.sun.grid.security.login.NumericGroupPrincipal} for each group the authenticated
107
* user belongs too</li>
111
public Set authenticate(final String username, final char[] password) throws LoginException {
115
Expect expect = new Expect(command);
117
expect.add(new ExpectStringHandler("username: ", username.toCharArray()));
118
expect.add(new ExpectPasswordHandler("password: ", password));
120
PrincipalHandler principalHandler = new PrincipalHandler(username);
121
expect.add(principalHandler);
123
ErrorHandler errorHandler = new ErrorHandler();
124
expect.add(errorHandler);
127
int exitCode = expect.exec(60*1000);
129
// exit codes are defined in juti.h (see auth_result_t)
130
// 0 means success, 1 means invalid username of password,
134
LOGGER.log(Level.FINE, "authuser.success", username);
135
return principalHandler.getPrinicipals();
136
case 1: // authentication failed
137
LOGGER.log(Level.FINE, "authuser.failed", username);
140
if(errorHandler.getError() == null) {
141
throw RB.newLoginException("authuser.error.unknown",
142
new Object [] { new Integer(exitCode) });
144
throw RB.newLoginException("authuser.error",
145
new Object [] { errorHandler.getError() });
148
} catch (InterruptedException ex) {
149
throw RB.newLoginException("authuser.error.interrupted");
150
} catch (IOException ex) {
151
throw RB.newLoginException("authuser.error.io", ex,
152
new Object [] { ex.getLocalizedMessage() });
158
* Handles error message of the authuser
160
class ErrorHandler implements ExpectHandler {
163
public void handle(Expect expect, ExpectBuffer buffer) throws IOException {
164
String msg = buffer.consumeLine("Error: ");
170
public String getError() {
176
* Handles the uid and gid output of the authuser
178
class PrincipalHandler implements ExpectHandler {
180
private Set principals = new HashSet();
181
private String username;
183
public PrincipalHandler(String username) {
184
this.username = username;
187
public void handle(Expect expect, ExpectBuffer buffer) throws IOException {
189
String line = buffer.consumeLine("uid ");
192
UserPrincipal up = new UserPrincipal(username);
195
NumericUserPrincipal p = new NumericUserPrincipal(line);
199
line = buffer.consumeLine("gid ");
201
StringTokenizer st = new StringTokenizer(line.trim(), ",");
202
boolean primaryGroup = true;
203
while(st.hasMoreTokens()) {
204
String groupName = st.nextToken();
205
int index = groupName.indexOf('(');
207
int endIndex = groupName.indexOf(')', index);
208
if(endIndex > index) {
209
String gid = groupName.substring(index+1, endIndex);
210
groupName = groupName.substring(0,index);
211
NumericGroupPrincipal p = new NumericGroupPrincipal(gid, primaryGroup);
215
GroupPrincipal p = new GroupPrincipal(groupName, primaryGroup);
217
primaryGroup = false;
222
public Set getPrinicipals() {