2 * @(#)Token.java 1.2 05/06/2002
4 * Copyright (c) 2001 International Business Machines Corp.
7 * This software has been released under the terms of the IBM Public
8 * License. For details, see the LICENSE file in the top-level source
9 * directory or online at http://www.openafs.org/dl/license10.html
11 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
14 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
15 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 package org.openafs.jafs;
26 import java.io.Serializable;
29 * An abstract representation of an AFS authentication token. It conveniently
30 * maintains the handle associated with token and the cell to which the token
34 * Constructing a <code>Token</code> object results in an immediate attempt to
35 * authenticate the user within the specified cell. If this attempt fails, an
36 * <code>{@link AFSException}</code> will be thrown. Therefore, if the
37 * construction of the object succeeds without an exception, then the
38 * <code>Token</code> is considered authenticated.
40 * The construction of a <code>Token</code> object acts as an entry point
41 * for authentication into the AFS system. Thus, when you construct a
42 * <code>{@link Cell}</code> object, you must pass in an instance of a
43 * <code>Token</code> that has been authenticated within the AFS cell that
44 * <code><I>Cell</I></code> is intended to represent. You will only be
45 * allowed to perform actions that the user, used to authenticate
46 * <code>Token</code>, is authorized to perform. You must construct a
47 * <code>Token</code> object before constructing a <code>Cell</code> object,
48 * which is required by all other objects within this package either directly
49 * or indirectly.<BR><BR>
51 * If an error occurs during a method call, an
52 * <code>AFSException</code> will be thrown. This class is the Java
53 * equivalent of errors thrown by AFS; see {@link AFSException}
54 * for a complete description.<BR><BR>
56 * <!--Example of how to use class-->
57 * The following is a simple example of how to construct and use a
58 * <code>Token</code> object. It shows how to construct a <code>Cell</code>
59 * using a <code>Token</code>. See {@link Cell} for a more detailed example
60 * of constructing and using a <code>Cell</code> object.<BR><BR>
63 * import org.openafs.jafs.AFSException;
64 * import org.openafs.jafs.Cell;
65 * import org.openafs.jafs.Token;
71 * private Token token;
73 * public static void main(String[] args) throws Exception
75 * String username = arg[0];
76 * String password = arg[1];
77 * String cellName = arg[2];
78 * String serverName = arg[3];
80 * token = new Token(username, password, cellName);
81 * cell = new Cell(token);
90 public class Token implements Serializable, Comparable
92 public static int ANYUSER_PAG_ID;
94 protected int tokenHandle;
95 protected int pagID = -1;
98 protected String cellName;
99 protected String username;
100 private String password;
102 private boolean hasInitialized = false;
105 * Load the native libraries <code>libjafs</code> and
106 * <code>libjafs</code>.
111 Class.forName("org.openafs.jafs.AFSLibraryLoader");
113 initializeAdminClient();
114 } catch (Exception e) {
115 System.err.println(e);
117 } catch (ClassNotFoundException e) {
118 /* Most likely running on a client, do nothing */
123 * Constructs a new <CODE>Token</CODE> object instance given
124 * the name of the AFS cell it represents and the username and password
125 * of the user to be Tokend for
126 * administrative access.
128 * @param username the name of the user to Token with
129 * @param password the password of that user
130 * @param cellName the name of the cell to Token into
131 * @param login if true, automatically login upon construction
132 * @exception AFSException If an error occurs in the native code
134 protected Token( String username, String password, String cellName,
135 boolean automaticallyLogin )
138 this.username = username;
139 this.password = password;
140 this.cellName = cellName;
142 /* By default lets authenticate the user using libafsauthent.a */
143 if (automaticallyLogin) login();
147 * Constructs a new <CODE>Token</CODE> object instance given
148 * the name of the AFS cell it represents and the username and password
149 * of the user to be Tokend for
150 * administrative access.
152 * @param username the name of the user to Token with
153 * @param password the password of that user
154 * @param cellName the name of the cell to Token into
155 * @exception AFSException If an error occurs in the native code
157 public Token( String username, String password, String cellName )
160 this.username = username;
161 this.password = password;
162 this.cellName = cellName;
164 System.out.println(username + ", " + cellName);
165 /* By default lets authenticate the user using libafsauthent.a */
170 * Returns the name of the AFS cell that this <code>Token</code> was
171 * authenticated against.
173 * @exception AFSException If an error occurs in the native code
174 * @return the name of the AFS cell associated with this <code>Token</code>.
176 public String getCellName()
182 * Returns the username of user to whom this token belongs.
184 * @exception AFSException If an error occurs in the native code
185 * @return the username of the user represented by this Token
187 public String getUsername()
193 * Returns a token handle that can be used to prove this authentication
196 * @exception AFSException If an error occurs in the native code
197 * @return a token representing the authentication
199 protected int getHandle()
205 * Closes the given currently open token.
207 * @exception AFSException If an error occurs in the native code
209 public void close() throws AFSException
215 * Gets the expiration time for a given token.
217 * @return a long representing the UTC time for the token expiration
218 * @exception AFSException If an error occurs in the native code
220 public long getExpiration() throws AFSException
222 return getExpiration(tokenHandle);
226 * Authenticates a user in kas, and binds that authentication
227 * to the current process.
229 * @exception AFSException If an error occurs in the native code
231 public void klog() throws AFSException
233 if (!hasInitialized) {
234 initializeUserSpace();
235 hasInitialized = true;
240 pagID = klog(username, password, cellName, pagID);
245 * Authenticates a user in KAS, and binds that authentication
246 * to the current process.
248 * @exception AFSException If an error occurs in the native code
250 public void login() throws AFSException
252 this.tokenHandle = this.getToken(cellName, username, password);
253 System.out.println("Token handle -> " + tokenHandle);
257 * Initialize the user space AFS client (libjafs).
259 * <P> The user space client must be initialized prior to any
260 * user space related methods, including: klog, unlog, relog,
263 * @exception AFSException If an error occurs in the native code
265 protected static void initializeUserSpace() throws AFSException
268 Token.initUserSpace();
269 } catch (AFSException e) {
270 System.err.println(e.getMessage());
273 Runtime.getRuntime().addShutdownHook(new AFSShutdownHandler());
274 } catch (Exception e) {
275 System.err.println("Could not register shutdown hook: " + e.toString());
279 /////////////// custom override methods ////////////////////
282 * Compares two ACL objects respective to their paths and does not
283 * factor any other attribute. Alphabetic case is significant in
286 * @param acl The ACL object to be compared to this ACL
289 * @return Zero if the argument is equal to this ACL's path, a
290 * value less than zero if this ACL's path is
291 * lexicographically less than the argument, or a value greater
292 * than zero if this ACL's path is lexicographically
293 * greater than the argument
295 public int compareTo(Token token)
297 return this.toString().compareTo(token.toString());
301 * Comparable interface method.
303 * @see #compareTo(Token)
305 public int compareTo(Object obj)
307 return compareTo((Token)obj);
311 * Tests whether two <code>Cell</code> objects are equal, based on their
312 * names. Does not test whether the objects are actually the same
313 * representational instance of the AFS cell.
315 * @param otherCell the <code>Cell</code> to test
316 * @return whether the specifed user is the same as this user
318 public boolean equals( Token token )
320 return this.toString().equals( token.toString() );
324 * Returns the name of this <CODE>Cell</CODE>
326 * @return the name of this <CODE>Cell</CODE>
328 public String toString()
330 return username + "@" + cellName + ":" + tokenHandle;
333 /////////////// native methods found in *Token.c ////////////////////
336 * Initialize the user space library.
338 * @exception AFSException If an error occurs in the native code
340 private static native void initUserSpace() throws AFSException;
343 * Initialize the administrative library.
345 * @exception AFSException If an error occurs in the native code
347 protected static native void initializeAdminClient() throws AFSException;
350 * Returns a token handle that can be used to prove this authentication
353 * @param cellName the name of the cell in which to Token this user
354 * @param userName the name of the user to Token
355 * @param password the password of the user
356 * @exception AFSException If an error occurs in the native code
357 * @return a token representing the authentication
359 protected native int getToken( String cellName, String username,
364 * Closes the given currently open token.
366 * @param tokenHandle the token to close
367 * @exception AFSException If an error occurs in the native code
369 protected native void close( int tokenHandle ) throws AFSException;
372 * Gets the expiration time for a given token.
374 * @param tokenHandle a token handle previously returned by a call
375 * to {@link #getToken}
377 * @return a long representing the UTC time for the token expiration
378 * @exception AFSException If an error occurs in the native code
380 protected native long getExpiration( int tokenHandle )
384 * Authenticates a user in KAS, and binds that authentication
385 * to the current thread or native process.
387 * @param username the login to authenticate
388 * (expected as username@cellname)
389 * @param password the password of the login
390 * @param cellName the name of the cell to authenticate into
391 * @param id the existing pag (or 0)
393 * @return the assigned pag
394 * @exception AFSException If an error occurs in the native code
396 protected native int klog(String username, String password,
397 String cellName, int id)
401 * Authenticates a user in KAS by a previously acquired PAG ID, and binds
402 * that authentication to the current thread or native process.
404 * <P> This method does not require the user's username and password to
405 * fully authenticate their request. Rather it utilizes the user's PAG ID
406 * to recapture the user's existing credentials.
408 * <P> This method is called by the public <code>klog</code> method, which
409 * internally manages the PAG ID. Additionally, an application needs only
410 * call <code>klog</code>, this reduces the amount of complexity and ensures
411 * that <code>relog</code> is never called before a <code>klog</code>.
413 * @param int User's current PAG (process authentication group) ID
414 * @exception AFSException If an error occurs in the native code
416 protected native void relog(int id) throws AFSException;
419 * Manually discards all AFS credentials associated with the bound user.
421 * @exception AFSException If an error occurs in the native code
423 public native void unlog() throws AFSException;
426 * Inform the native library that the application is
427 * shutting down and will be unloading.
429 * <p> The library will make a call informing the file server that it will
430 * no longer be available for callbacks.
432 protected static native void shutdown();
435 * Reclaims all memory being saved by the authentication portion of
436 * the native library.
437 * This method should be called when no more authentications are expected.
439 protected static native void reclaimAuthMemory();
442 /*=======================================================================*/
444 * Class that loads the native libraries required for direct communication with
445 * AFS. Since the Token class is serializable the function of loading the
446 * native libraries must be performed in a non-serialized class, one that will
447 * not be included in any client side application packages.
449 * @version 1.0, 06/13/2001
451 class AFSLibraryLoader
455 System.loadLibrary("jafs");
456 System.loadLibrary("jafsadm");
459 /*=======================================================================*/
461 * Class that handles graceful AFS application shutdown procedures by
462 * instructing the native library to inform the file system server that
463 * it is shutting down.
465 * @version 1.0, 06/13/2001
467 class AFSShutdownHandler extends Thread
469 public AFSShutdownHandler() {}
472 * This is the execution method satisfying the interface requirement as a
473 * stand alone runnable thread.
475 * <p> This method will automatically be invoked by the Thread instantiator.
477 * @see Token#shutdown()
481 System.out.println("Shutting down Java AFS library...");
482 org.openafs.jafs.Token.shutdown();
485 /*=======================================================================*/