We haven't yet done as good a
job of documentation as we'd like (no slight intended for our excellent
doc writer - we just haven't had time to work with him to the extent
necessary), and as a result I don't think it's as
easy to pick up and customize as it should be yet. In this document
I'll describe what it is and how to customize it, as an initial way of
getting some facts down that can later be turned into a more formal
form of documentation we can distribute with our product. In the
meantime hopefully you'll find these notes useful.
behaviors (Sun Ray "redirection", which causes it to connect to a
different server, and the pre-loading of a username into the login
dialog) have to be driven by data somewhere that says what to do in
different circumstances. For example, there might be data
somewhere that lists smartcard identifiers and the usernames with which
they should be associated. Or there might be data that lists
usernames and the servers the Sun Ray should be redirected to for those
users, so that they can find their sessions or create new ones if none
exist. This data may already exist for many customers
(most commonly the smartcard-to-username data), and might be in a flat
file, or in a Directory Service, or in a NIS map. Where that
data resides, and how to use it, will vary from customer to
customer. As a consequence, there's no way to create a GUI to
configure these policies because there are no constraints on location,
format, or logic defining how to use
the data - you can do anything you like with it.
An example - Sun's internal
use of AMGH
Let's consider how Sun uses
AMGH internally. Sun's IT department has created a "model"
which associates smartcards,
users, the buildings users work in, and Sun Ray Server
Groups. All of the data related to their model resides in an
Enterprise Directory Service (based on LDAP) which is available
global Wide Area Network (SWAN). The data is used by a wide
variety of internal tools. The Sun IT AMGH model relies on
following objects and attributes associated with objects:
The idea is that every employee, upon inserting their smartcard, should
have their Sun Ray directed to the Server Group associated with the
building they normally work in. They can override this
placement if they like by administering their "Preferred Server Group"
and setting it to someplace specific (normally it is not set).
When an employee inserts their smartcard, Sun's AMGH policy module
looks up the Person object associated with the smartcard
CUID. If they have a "Preferred" Server Group, its Sun Ray
Server Group object is referenced and the list of servers for that
object is returned. Otherwise their Building Object is
referenced to determine its Server Group, and then its Sun Ray Server
Group object is referenced and the list of servers for that object is
returned. The username for the Person object is also
returned, so the employee immediately sees a welcome screen to
All of the above lookups and references are made by the means of an
ldapsearch command. Since there are no standard Schemas for
most of these objects and attributes, Sun uses a custom Schema for this
As you can see from this example, AMGH mapping policy logic has no
constraints, and so does not lend itself to specification by a fixed
administrative GUI. Another site might like to direct Sun
Rays on a specific subnet to do something different from the rest, or a
specific Sun Ray to have a unique behavior. Some sites might
like all Sun Rays to reconnect to the original server they connected to
after bootup when a smartcard is removed (this can be accomplished
through another API return parameter:
All of these policies can be specified and implemented using the AMGH
We'll continue to think about ways to make a simple policy-builder GUI
that some customers can use but for now releasing the API gives
complete power to customers to control their environment as they see
I've gotten permission from our (very supportive) VP Bill Vass to post
the source to the AMGH script used by Sun IT internally.
I've posted that script to my blog
. Hopefully with the above model/object description it should be comprehensible. Thanks, Bill!
the API, you generally will find
more useful than
since the former represents the actual smartcard CUID whereas the
latter is a form translated by Sun Ray software in ways that may be
hard to predict. If you run "
" in a Sun
Ray session, you will see the value of
If you run "
you will see the value of
Depending on your Sun Ray policy specified by utpolicy or through the
administration browser interface these may be the same or
different. You should always use
if you have configured a registered card policy,
because with this policy
is not consistent across different Sun Ray Server Groups, so cannot be
used consistently for AMGH redirection.
There's probably not a use for
since that value is randomly assigned when a session is created.
If you use the 'executable' API, you can use a shell script as we do in
all the reference code, but you can also use something like perl or an
executable produced from C code. We used Bourne Shell code in
our examples simply because it is widely understood.
Less commonly used features of the AMGH API
There are two other pieces of information that can be returned, which are not as commonly used:
. Both have boolean values of
is returned, any
values are ignored, and the Sun Ray will be directed to the first Sun Ray server it contacted after last boot (note
this has an Availability issue - if that server is now unavailable, the
Sun Ray cannot be directed to other members of its FOG and instead the
Sun Ray will remain connected to the current server
). This can
be used for example to create a "return to home on smartcard removal"
model by matching all "pseudo.*" insert_tokens and returning
is really for expert-use only. It can be used in situations where
there are groups of servers with "partial knowledge" of the policy for
returned, AMGH will perform in the standard way, but after redirecting
the Sun Ray the remote server it connects to will apply AMGH policy again
based on its AMGH configuration. In this way a Sun Ray can be directed
to another group of servers with AMGH knowledge which might cause
further AMGH redirections to the final desired destination. Obviously
this can result in loops if improperly configured.
A Sun Ray with no card inserted will have an
of the form
" where the part after the '.' is the MAC address
of the Sun Ray.
Smartcards will have an
of the form
", where the part before the '.' is the
type of smartcard and the part after it is the unique badge CUID.
report tokens in
form, which is the same as
form if the tokens are not "registered" (see
reports tokens in
For security purposes, you need to lock down permissions on AMGH
mapping executables or libraries. Neither the executables,
libraries, nor the directories they reside in should be writable by
anybody other than root. In other words, they should all be
owned by root, and writable only by owner. libraries and
executables must be readable by owner (root), and executables must be
executable by owner.
Why not write an AMGH script utilizing information in the SRDS token registration database?
Initially this may seem attractive
but keep in mind that AMGH is intended to work across FOGs, so you
really ought to use a single, consistent database which can be shared
across FOGs and is not subject to FOG-local typos or errors. Such
errors can create inconsistent and hard to diagnose behavior.
If you do go this route, do not be tempted to use the "-c" option to
utuser. Although it will restrict the output only to relevant
tokens it will have an undesirable performance impact since it involves
the Authentication Manager (utauthd) at what can be a critical time
(e.g. as a server is first coming up many Sun Rays may be connecting to
utauthd simultaneously and creating sessions, all going into the
greeter at once so invoking AMGH). "utuser -l" generates more
output but does not involve utauthd so will actually scale better in
A tour of the Reference Source
Upon installing Sun Ray Server Software 3.1, a collection of reference
C code and shell scripts will be installed in
. The operative word here is reference
This code is not secure or robust - that's not its purpose.
It's goal is to give a clear example of how to use the API, so
the code is written to be as simple as possible to make it easy to
understand and write your own code. Making the code more
"production-ready" would have complicated the code and made the
utilization of the actual AMGH API less clear as a result. I've
already explained why we can't write "one size fits all" code that you
can just pick up and use. It's not nearly as flexible as it could
be. For instance it doesn't do any wildcard matching or the like.
A C header file defining the API is installed called
This can help in understanding the C code, and should be used by any C
code you write yourself. I've mentioned the man pages for the C
and executable (e.g. shell
script) APIs previously. Here is a brief description of each
of the reference sources currently delivered with the product:
||Simple C module to map a
token to a username and/or hosts
||Relocatable C library
built from utamghref_token.c
||Simple C module to map a
username to hosts
|Relocatable C library
built from utamghref_username.c
||Simple sh script
illustrating how to map a token to a username/hosts, or if no mapping
is available (in which case AMGH will prompt the user for their
username) map a username to hosts
|Flexible sh script which
will map any of the AMGH inputs to any of the available AMGH return
All of the above code uses a flat ASCII file in key=value format, with
a single line for every potential mapping. If a site chooses
to use this code they may wish to replicate the file either through an
NFS share or a mechanism like 'rdist'.
A reference Makefile is included to illustrate how to build a shared
library from this C source.
In future, we may include an example utilizing LDAP, since that is a
common customer requirement. However, the issue here is that,
since there are no standard schemas, it is not really possible to write
example code that people can understand, without understanding a
proprietary schema. This makes it hard to write clear
examples which utilize LDAP. However, once you understand the
API and how you could implement it using a flat file for your data
source, changing to using LDAP should be simple, and any complexity
there is related to how you store and represent the data that you wish
to utilize. You can just use the 'ldapsearch' command in a
shell script, for instance.
Technical details for the interminably curious
Some people have been curious as to where/how AMGH is being activated.
AMGH is invoked from the PAM stack of the Display Manager (either
dtlogin or gdm for Linux users). You'll need to at least read the
man page for "pam.conf" to understand the rest of the workings.
- When you insert your smartcard, the Display Manager (DM) is told
to create a session for you. Before you even see the greeter, it
- The PAM library will then invoke
pam_sunray_amgh.so::pam_sm_authenticate(), which does a callback to the
Authentication Manager to get all the specifics such as insert_token,
IP address, and the rest, and then calls the configured script you
configure for AMGH. At this time there is typically no username
- If your AMGH script doesn't return any hosts, the user will be prompted to enter their name (via sunray_get_user.so), and then
- pam_sunray_amgh.so::pam_sm_authenticate() is invoked again. with
all the specifics, this time including the username, so your script has
a chance to make a decision based on the username
If any hosts are returned during either
call to your script, pam_sunray_amgh will request the Authentication
Manager to redirect the Sun Ray to the first responsive host that you
return, and then it will request the DM to tear down the session which
was used to invoke AMGH.
An unsupported way to make the "username" non-overridable
the API can be overridden by the Display Manager (e.g. dtlogin's "Start
Over" button). Some customers would like this setting to be a
sort of "security" feature that cannot be overridden by the user,
rather than a "convenience" feature as it exists today. In
future, we may add such a feature to the product. There is an
unsupported way to deal with this today, however, for non-NSCM logins.
You can edit /etc/pam.conf and remove the clearuser
option from the pam_sunray_amgh.so
module. This is not officially supported because it has not been tested
by our Quality Assurance team but it has been known to work for some
customers. There is no similar recourse for NSCM logins today -
the "Start Over" button will clear the preset login name returned by
This should be enough information for you to get started using
AMGH. If you give me useful feedback I'll roll it into this
document. Eventually I want to see this information
distributed officially as part of the Sun Ray product but this document
serves as a way to get the information out to users quickly and to
start to form what will become the product document.
AMGH was finally led to product by Sangeeta Varma, with the invaluable assistance
of Vijay Rajkrishnan who was
graciously loaned to our team by Sun IT (an org which has been
enormously supportive of Sun Ray from the very beginning).
What a great team - thanks, guys, it was a pleasure! Also
proof that people can collaborate effectively over large distances (CA,
TX, and FL).