Overview of Authorization Toolkit for Java

Last revised: 10Aug2003 GLG

Table of Contents

Introduction

This document is an overview of the classes in the Authorization Toolkit for Java. For a complete discussion of the classes and API, see the API-docs or the Java source.

The Authorization Toolkit for Java is a simple class library intended to give Java programs access to arbitrary system-provided authorization and authentication services. On Unix-like OSes, this provides a controlled and authenticated pathway to running programs with an effective user-ID of root.

A concrete implementation is provided for Mac OS X, based on the native Authorization Services API.

Compatibility

Backward Compatibility

This full release is backward compatible with the prior prerelease. There were no significant changes made to the public API.

Java Compatibility

This toolkit requires a Java implementation compliant with JDK 1.1 or later. All the platform-neutral Java source will compile on any compiler compliant with JDK 1.1 or higher. This toolkit uses no methods or classes deprecated as of JDK 1.1.

Platform Compatibility

The implementation-specific requirements are outlined for each implementation provided.

A JNI-based implementation is provided for Mac OS X, using the Authorization Services API. This implementation uses a PowerPC Mach-O native library, supplied in pre-compiled form for immediate use. It has been tested under J2SE 1.3.1 and 1.4.1 on Mac OS 10.1 through 10.2.3. Use on Mac OS 10.0 is not advised.

Design Overview and Origins

The design of the Authorization Toolkit for Java (AuthKit) is almost painfully simple: Other Authorization methods provide features like securely sharing a session with another process, discovering current privilege status, discarding a session, etc. All the details, however, such as principals, subjects, roles, identities, credentials, policies, authenticators, interlocks, expiries, access-controls, etc. are hidden in a specific concrete implementation of Authorization.

The basic Authorization Toolkit (AuthKit) design reflects the capabilities of Mac OS X's Authorization Services API. However, the AuthKit's Java API is quite different from the Authorization Services C-level API. The Java API is more object-oriented, and is abstracted and simplified to improve its flexibility and allow for different implementations. The Java API is not a direct translation of the Authorization Services API, though it does have certain similarities.

Running with Elevated Privileges

One of the reasons I created the Authorization Toolkit for Java was to be able to run arbitrary programs on Mac OS X with elevated privileges. Specifically, I wanted to run Java programs as root. The native Authorization Services API provided this capability, and guarded it with a system-enforced authentication dialog. This makes it far safer than any hack I could create with setuid-root executables or the 'sudo' command, or any externally provided Java-level authentication.

I wanted to run Java programs as root because there are many useful administrative tasks one can easily express in Java programs, but Java itself has no awareness or representation for most system-provided privileges or identities. Furthermore, Java programs are typically stored in jar-files, and those can't be given setuid-root file-permissions with any effect. So in order to write the kind of administrative or system-maintenance tasks I wanted to write in Java, I had to have a Java API that would make the transition to root in the safest way possible.

The Authorization.execPrivileged() method will always authenticate the user unless authorization to execute as root is already available. Since the authentication dialog is presented and managed by the system itself, the Java API is as strong (or as weak) as the system's own API.

The Mac OS X Authorization Services authentication dialog requires an admin-user name and password. If you're logged in as a non-admin user, you must enter both the name and password. If you're logged in as an admin user, you only supply the password. Once authorized, the privilege to run other programs as root lasts for 5 minutes by default, or until the authenticating program terminates, or until the authenticating program discards the authorizing session.

Other Documentation

To fully understand how AuthKit works on Mac OS X, you should first understand Authorization Services on Mac OS X. For example, the only way to change any of the Authorization Services policies is to know what format the policy-file is in, where it lives, and how to change it safely. Coincidently, changing the Authorization Services policies was one of the things I wanted to be able to do in Java.


Following are the essential descriptions and references for Authorization Services on Mac OS X: The terminology of Authorization Services differs from that of AuthKit. The correspondence is roughly:


Some Apple Q&A's relate to Authorization Services. Searching the ADC web site is the best way to find these. Here's a Q&A that explains why an authentication dialog may not be required:


Some pivotal information on Authorization Services is difficult to find. For example, the location and format of the policies and rules database is not easily found. On Mac OS 10.1 through at least 10.2.*, the Authorization Services policy file for the machine is: The "/etc" name is actually a symlink to the directory "/private/etc". The "/etc/authorization" file itself is an XML file in property-list format. However, it contains crucial comments describing the format of the policy rules, so you should normally read or edit it in plain-text form, thereby preserving all the comments. Do not edit it using the Property List Editor developer tool.

The ownership and permissions on the /etc/authorization file make it readable only by root or a member of the admin group (i.e. an admin user), and writable only by root. The permissons of its actual parent directory (/private/etc) make it writable only by root, but accessible to anyone.

I strongly recommend that if you edit /etc/authorization, you work on a local unrestricted copy, and that you maintain the previously working original file each time you change it. For example, you can rename the original to have a ".bak" suffix, and then rename the new file into place. That way, if you mangle a policy rule, you only have to rename a couple of files (as root) in order to restore the original policy rules.

Even these safeguards will not prevent you from defining a foolish policy rule that leaves your machine wide open to compromise. So before you change anything in /etc/authorization, be absolutely certain you know exactly what you're doing.


To Greg's Home Page
To Greg's Software Page